~ubuntu-branches/ubuntu/karmic/kleansweep/karmic

« back to all changes in this revision

Viewing changes to admin/kde.py

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Mercatante
  • Date: 2006-01-20 11:26:41 UTC
  • Revision ID: james.westby@ubuntu.com-20060120112641-xd1rmv568k0vvz3u
Tags: upstream-0.2.5
ImportĀ upstreamĀ versionĀ 0.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Thomas Nagy, 2005 <tnagy2^8@yahoo.fr>
 
2
""" Run scons -h to display the associated help, or look below """
 
3
 
 
4
import os, re, types
 
5
from SCons.Script.SConscript import SConsEnvironment
 
6
 
 
7
# Returns the name of the shared object (i.e. libkdeui.so.4)
 
8
# referenced by a libtool archive (like libkdeui.la)
 
9
def getSOfromLA(lafile):
 
10
        contents = open(lafile, 'r').read()
 
11
        match = re.search("^dlname='([^']*)'$", contents, re.M)
 
12
        if match: return match.group(1)
 
13
        return None
 
14
 
 
15
# A helper, needed .. everywhere
 
16
def KDEuse(lenv, flags):
 
17
        if lenv['HELP']: lenv.Exit(0)
 
18
 
 
19
        _flags=lenv.make_list(flags)
 
20
        if 'environ' in _flags:
 
21
                ## The scons developers advise against using this but it is mostly innocuous :)
 
22
                lenv.AppendUnique( ENV = os.environ )
 
23
        if not 'lang_qt' in _flags:
 
24
                ## Use this define if you are using the kde translation scheme (.po files)
 
25
                lenv.Append( CPPFLAGS = '-DQT_NO_TRANSLATION' )
 
26
        if 'rpath' in _flags:
 
27
                ## Use this to set rpath - this may cause trouble if folders are moved (chrpath)
 
28
                kdelibpaths=[]
 
29
                if lenv['KDELIBPATH'] == lenv['KDELIB']: kdelibpaths = [lenv['KDELIB']]
 
30
                else: kdelibpaths = [lenv['KDELIBPATH'],  lenv['KDELIB']]
 
31
                lenv.Append( RPATH = [lenv['QTLIBPATH'], lenv['KDEMODULE']]+kdelibpaths )
 
32
        if 'thread' in _flags:
 
33
                ## Uncomment the following if you need threading support
 
34
                lenv.KDEaddflags_cxx( ['-DQT_THREAD_SUPPORT', '-D_REENTRANT'] )
 
35
        if 'fastmoc' in _flags:
 
36
                lenv['BKSYS_FASTMOC']=1
 
37
        if not 'nohelp' in _flags:
 
38
                if lenv['_CONFIGURE'] or lenv['HELP']: lenv.Exit(0)
 
39
        if not 'nosmart' or not lenv.has_key('nosmart_includes'):
 
40
                lenv.AppendUnique(CPPPATH=['#/'])
 
41
                lst=[]
 
42
                if lenv.has_key('USE_THE_FORCE_LUKE'):
 
43
                        lst=lenv['USE_THE_FORCE_LUKE']
 
44
                        lenv.__delitem__('USE_THE_FORCE_LUKE')
 
45
                for v in lst: v.execute()
 
46
        else: lenv['nosmart_includes']=1
 
47
 
 
48
        ## To use kdDebug(intvalue)<<"some trace"<<endl; you need to define -DDEBUG
 
49
        ## it is done in admin/generic.py automatically when you do scons configure debug=1
 
50
 
 
51
def exists(env):
 
52
        return True
 
53
 
 
54
def detect_kde(env):
 
55
        """ Detect the qt and kde environment using kde-config mostly """
 
56
        def getpath(varname):
 
57
                if not env.has_key('ARGS'): return None
 
58
                v=env['ARGS'].get(varname, None)
 
59
                if v: v=os.path.abspath(v)
 
60
                return v
 
61
 
 
62
        def getstr(varname):
 
63
                if env.has_key('ARGS'): return env['ARGS'].get(varname, '')
 
64
                return ''
 
65
 
 
66
        prefix      = getpath('prefix')
 
67
        execprefix  = getpath('execprefix')
 
68
        datadir     = getpath('datadir')
 
69
        libdir      = getpath('libdir')
 
70
 
 
71
        kdedir      = getstr('kdedir')
 
72
        kdeincludes = getpath('kdeincludes')
 
73
        kdelibs     = getpath('kdelibs')
 
74
 
 
75
        qtdir       = getstr('qtdir')
 
76
        qtincludes  = getpath('qtincludes')
 
77
        qtlibs      = getpath('qtlibs')
 
78
        libsuffix   = getstr('libsuffix')
 
79
 
 
80
        p=env.pprint
 
81
 
 
82
        if libdir: libdir = libdir+libsuffix
 
83
 
 
84
        ## Detect the kde libraries
 
85
        print "Checking for kde-config           : ",
 
86
        str="which kde-config 2>/dev/null"
 
87
        if kdedir: str="which %s 2>/dev/null" % (kdedir+'/bin/kde-config')
 
88
        kde_config = os.popen(str).read().strip()
 
89
        if len(kde_config):
 
90
                p('GREEN', 'kde-config was found as '+kde_config)
 
91
        else:
 
92
                if kdedir: p('RED','kde-config was NOT found in the folder given '+kdedir)
 
93
                else: p('RED','kde-config was NOT found in your PATH')
 
94
                print "Make sure kde is installed properly"
 
95
                print "(missing package kdebase-devel?)"
 
96
                env.Exit(1)
 
97
        if kdedir: env['KDEDIR']=kdedir
 
98
        else: env['KDEDIR'] = os.popen(kde_config+' -prefix').read().strip()
 
99
 
 
100
        print "Checking for kde version          : ",
 
101
        kde_version = os.popen(kde_config+" --version|grep KDE").read().strip().split()[1]
 
102
        if int(kde_version[0]) != 3 or int(kde_version[2]) < 2:
 
103
                p('RED', kde_version)
 
104
                p('RED',"Your kde version can be too old")
 
105
                p('RED',"Please make sure kde is at least 3.2")
 
106
        else:
 
107
                p('GREEN',kde_version)
 
108
 
 
109
        ## Detect the qt library
 
110
        print "Checking for the qt library       : ",
 
111
        if not qtdir: qtdir = os.getenv("QTDIR")
 
112
        if qtdir:
 
113
                p('GREEN',"qt is in "+qtdir)
 
114
        else:
 
115
                try:
 
116
                        tmplibdir = os.popen(kde_config+' --expandvars --install lib').read().strip()
 
117
                        libkdeuiSO = env.join(tmplibdir, getSOfromLA(env.join(tmplibdir,'/libkdeui.la')) )
 
118
                        m = re.search('(.*)/lib/libqt.*', os.popen('ldd ' + libkdeuiSO + ' | grep libqt').read().strip().split()[2])
 
119
                except: m=None
 
120
                if m:
 
121
                        qtdir = m.group(1)
 
122
                        p('YELLOW',"qt was found as "+m.group(1))
 
123
                else:
 
124
                        p('RED','qt was not found')
 
125
                        p('RED','Please set QTDIR first (/usr/lib/qt3?) or try scons -h for more options')
 
126
                        env.Exit(1)
 
127
        env['QTDIR'] = qtdir.strip()
 
128
 
 
129
        ## Find the necessary programs uic and moc
 
130
        print "Checking for uic                  : ",
 
131
        uic = qtdir + "/bin/uic"
 
132
        if os.path.isfile(uic):
 
133
                p('GREEN',"uic was found as "+uic)
 
134
        else:
 
135
                uic = os.popen("which uic 2>/dev/null").read().strip()
 
136
                if len(uic):
 
137
                        p('YELLOW',"uic was found as "+uic)
 
138
                else:
 
139
                        uic = os.popen("which uic 2>/dev/null").read().strip()
 
140
                        if len(uic):
 
141
                                p('YELLOW',"uic was found as "+uic)
 
142
                        else:
 
143
                                p('RED',"uic was not found - set QTDIR put it in your PATH ?")
 
144
                                env.Exit(1)
 
145
        env['QT_UIC'] = uic
 
146
 
 
147
        print "Checking for moc                  : ",
 
148
        moc = qtdir + "/bin/moc"
 
149
        if os.path.isfile(moc):
 
150
                p('GREEN',"moc was found as "+moc)
 
151
        else:
 
152
                moc = os.popen("which moc 2>/dev/null").read().strip()
 
153
                if len(moc):
 
154
                        p('YELLOW',"moc was found as "+moc)
 
155
                elif os.path.isfile("/usr/share/qt3/bin/moc"):
 
156
                        moc = "/usr/share/qt3/bin/moc"
 
157
                        p('YELLOW',"moc was found as "+moc)
 
158
                else:
 
159
                        p('RED',"moc was not found - set QTDIR or put it in your PATH ?")
 
160
                        env.Exit(1)
 
161
        env['QT_MOC'] = moc
 
162
 
 
163
        ## check for the qt and kde includes
 
164
        print "Checking for the qt includes      : ",
 
165
        if qtincludes and os.path.isfile(qtincludes + "/qlayout.h"):
 
166
                # The user told where to look for and it looks valid
 
167
                p('GREEN',"ok "+qtincludes)
 
168
        else:
 
169
                if os.path.isfile(qtdir + "/include/qlayout.h"):
 
170
                        # Automatic detection
 
171
                        p('GREEN',"ok "+qtdir+"/include/")
 
172
                        qtincludes = qtdir + "/include/"
 
173
                elif os.path.isfile("/usr/include/qt3/qlayout.h"):
 
174
                        # Debian probably
 
175
                        p('YELLOW','the qt headers were found in /usr/include/qt3/')
 
176
                        qtincludes = "/usr/include/qt3"
 
177
                else:
 
178
                        p('RED',"the qt headers were not found")
 
179
                        env.Exit(1)
 
180
 
 
181
        print "Checking for the kde includes     : ",
 
182
        kdeprefix = os.popen(kde_config+" --prefix").read().strip()
 
183
        if not kdeincludes:
 
184
                kdeincludes = kdeprefix+"/include/"
 
185
        if os.path.isfile(kdeincludes + "/klineedit.h"):
 
186
                p('GREEN',"ok "+kdeincludes)
 
187
        else:
 
188
                if os.path.isfile(kdeprefix+"/include/kde/klineedit.h"):
 
189
                        # Debian, Fedora probably
 
190
                        p('YELLOW',"the kde headers were found in %s/include/kde/"%kdeprefix)
 
191
                        kdeincludes = kdeprefix + "/include/kde/"
 
192
                else:
 
193
                        p('RED',"The kde includes were NOT found")
 
194
                        env.Exit(1)
 
195
 
 
196
        # kde-config options
 
197
        kdec_opts = {'KDEBIN'    : 'exe',     'KDEAPPS'      : 'apps',
 
198
                     'KDEDATA'   : 'data',    'KDEICONS'     : 'icon',
 
199
                     'KDEMODULE' : 'module',  'KDELOCALE'    : 'locale',
 
200
                     'KDEKCFG'   : 'kcfg',    'KDEDOC'       : 'html',
 
201
                     'KDEMENU'   : 'apps',    'KDEXDG'       : 'xdgdata-apps',
 
202
                     'KDEMIME'   : 'mime',    'KDEXDGDIR'    : 'xdgdata-dirs',
 
203
                     'KDESERV'   : 'services','KDESERVTYPES' : 'servicetypes',
 
204
                     'KDEINCLUDE': 'include' }
 
205
 
 
206
        if prefix:
 
207
                ## use the user-specified prefix
 
208
                if not execprefix: execprefix=prefix
 
209
                if not datadir: datadir=env.join(prefix,'share')
 
210
                if not libdir: libdir=env.join(execprefix, "lib"+libsuffix)
 
211
 
 
212
                subst_vars = lambda x: x.replace('${exec_prefix}', execprefix)\
 
213
                                .replace('${datadir}', datadir)\
 
214
                                .replace('${libdir}', libdir)\
 
215
                                .replace('${prefix}', prefix)
 
216
                debian_fix = lambda x: x.replace('/usr/share', '${datadir}')
 
217
                env['PREFIX'] = prefix
 
218
                env['KDELIB'] = libdir
 
219
                for (var, option) in kdec_opts.items():
 
220
                        dir = os.popen(kde_config+' --install ' + option).read().strip()
 
221
                        if var == 'KDEDOC': dir = debian_fix(dir)
 
222
                        env[var] = subst_vars(dir)
 
223
 
 
224
        else:
 
225
                env['PREFIX'] = os.popen(kde_config+' --expandvars --prefix').read().strip()
 
226
                env['KDELIB'] = os.popen(kde_config+' --expandvars --install lib').read().strip()
 
227
                for (var, option) in kdec_opts.items():
 
228
                        dir = os.popen(kde_config+' --expandvars --install ' + option).read().strip()
 
229
                        env[var] = dir
 
230
 
 
231
        env['QTPLUGINS']=os.popen(kde_config+' --expandvars --install qtplugins').read().strip()
 
232
 
 
233
        ## kde libs and includes
 
234
        env['KDEINCLUDEPATH']=kdeincludes
 
235
        if not kdelibs:
 
236
                kdelibs=os.popen(kde_config+' --expandvars --install lib').read().strip()
 
237
        env['KDELIBPATH']=kdelibs
 
238
 
 
239
        ## qt libs and includes
 
240
        env['QTINCLUDEPATH']=qtincludes
 
241
        if not qtlibs:
 
242
                qtlibs=qtdir+"/lib"+libsuffix
 
243
        env['QTLIBPATH']=qtlibs
 
244
 
 
245
def generate(env):
 
246
        """"Set up the qt and kde environment and builders - the moc part is difficult to understand """
 
247
 
 
248
        # attach this function immediately
 
249
        SConsEnvironment.KDEuse=KDEuse
 
250
 
 
251
        if env['HELP']:
 
252
                p=env.pprint
 
253
                p('BOLD','*** KDE options ***')
 
254
                p('BOLD','--------------------')
 
255
                p('BOLD','* prefix     ','base install path,         ie: /usr/local')
 
256
                p('BOLD','* execprefix ','install path for binaries, ie: /usr/bin')
 
257
                p('BOLD','* datadir    ','install path for the data, ie: /usr/local/share')
 
258
                p('BOLD','* libdir     ','install path for the libs, ie: /usr/lib')
 
259
 
 
260
                p('BOLD','* qtdir      ','base of the kde libraries')
 
261
                p('BOLD','* kdedir     ','base of the qt libraries')
 
262
 
 
263
                p('BOLD','* libsuffix  ','suffix of libraries on amd64, ie: 64, 32')
 
264
                p('BOLD','* kdeincludes','kde includes path (/usr/include/kde on debian, ..)')
 
265
                p('BOLD','* qtincludes ','qt includes path (/usr/include/qt on debian, ..)')
 
266
                p('BOLD','* kdelibs    ','kde libraries path, for linking the programs')
 
267
                p('BOLD','* qtlibs     ','qt libraries path, for linking the program')
 
268
 
 
269
                p('BOLD','* scons configure libdir=/usr/local/lib qtincludes=/usr/include/qt\n')
 
270
                return
 
271
 
 
272
        import SCons.Defaults
 
273
        import SCons.Tool
 
274
        import SCons.Util
 
275
        import SCons.Node
 
276
 
 
277
        CLVar = SCons.Util.CLVar
 
278
        splitext = SCons.Util.splitext
 
279
        Builder = SCons.Builder.Builder
 
280
        
 
281
        # Detect the environment - replaces ./configure implicitely and store the options into a cache
 
282
        from SCons.Options import Options
 
283
        cachefile=env['CACHEDIR']+'kde.cache.py'
 
284
        opts = Options(cachefile)
 
285
        opts.AddOptions(
 
286
                ('PREFIX', 'root of the program installation'),
 
287
 
 
288
                ('QTDIR', ''),
 
289
                ('QTLIBPATH', 'path to the qt libraries'),
 
290
                ('QTINCLUDEPATH', 'path to the qt includes'),
 
291
                ('QT_UIC', 'uic command'),
 
292
                ('QT_MOC', 'moc command'),
 
293
                ('QTPLUGINS', 'uic executable command'),
 
294
 
 
295
                ('KDEDIR', ''),
 
296
                ('KDELIBPATH', 'path to the installed kde libs'),
 
297
                ('KDEINCLUDEPATH', 'path to the installed kde includes'),
 
298
 
 
299
                ('KDEBIN', 'inst path of the kde binaries'),
 
300
                ('KDEINCLUDE', 'inst path of the kde include files'),
 
301
                ('KDELIB', 'inst path of the kde libraries'),
 
302
                ('KDEMODULE', 'inst path of the parts and libs'),
 
303
                ('KDEDATA', 'inst path of the application data'),
 
304
                ('KDELOCALE', ''), ('KDEDOC', ''), ('KDEKCFG', ''),
 
305
                ('KDEXDG', ''), ('KDEXDGDIR', ''), ('KDEMENU', ''),
 
306
                ('KDEMIME', ''), ('KDEICONS', ''), ('KDESERV', ''),
 
307
                ('KDESERVTYPES', ''), ('KDEAPPS', ''),
 
308
        )
 
309
        opts.Update(env)
 
310
 
 
311
        def getInstDirForResType(lenv,restype):
 
312
                if len(restype) == 0 or not lenv.has_key(restype):
 
313
                        lenv.pprint('RED',"unknown resource type "+restype)
 
314
                        lenv.Exit(1)
 
315
                else: instdir = lenv[restype]
 
316
 
 
317
                if env['ARGS'] and env['ARGS'].has_key('prefix'):
 
318
                        instdir = instdir.replace(lenv['PREFIX'], env['ARGS']['prefix'])
 
319
                return instdir
 
320
 
 
321
        # reconfigure when things are missing
 
322
        if not env['HELP'] and (env['_CONFIGURE'] or not env.has_key('QTDIR') or not env.has_key('KDEDIR')):
 
323
                detect_kde(env)
 
324
                opts.Save(cachefile, env)
 
325
 
 
326
        ## set default variables, one can override them in sconscript files
 
327
        env.Append(CXXFLAGS = ['-I'+env['KDEINCLUDEPATH'], '-I'+env['QTINCLUDEPATH'] ],
 
328
                        LIBPATH = [env['KDELIBPATH'], env['QTLIBPATH'] ])
 
329
        
 
330
        env['QT_AUTOSCAN'] = 1
 
331
        env['QT_DEBUG']    = 0
 
332
 
 
333
        env['MEINPROC'] = 'meinproc'
 
334
        env['MSGFMT']   = 'msgfmt'
 
335
 
 
336
        ## ui file processing
 
337
        def uic_processing(target, source, env):
 
338
                inc_kde  ='#include <klocale.h>\n#include <kdialog.h>\n'
 
339
                inc_moc  ='#include "%s"\n' % target[2].name
 
340
                comp_h   ='$QT_UIC -L $QTPLUGINS -nounload -o %s %s' % (target[0].path, source[0].path)
 
341
                comp_c   ='$QT_UIC -L $QTPLUGINS -nounload -tr tr2i18n -impl %s %s' % (target[0].path, source[0].path)
 
342
                comp_moc ='$QT_MOC -o %s %s' % (target[2].path, target[0].path)
 
343
                if env.Execute(comp_h): return ret
 
344
                dest = open( target[1].path, "w" )
 
345
                dest.write(inc_kde)
 
346
                dest.close()
 
347
                if env.Execute( comp_c+" >> "+target[1].path ): return ret
 
348
                dest = open( target[1].path, "a" )
 
349
                dest.write(inc_moc)
 
350
                dest.close()
 
351
                ret = env.Execute( comp_moc )
 
352
                return ret
 
353
        def uicEmitter(target, source, env):
 
354
                adjustixes = SCons.Util.adjustixes
 
355
                bs = SCons.Util.splitext(str(source[0].name))[0]
 
356
                bs = env.join(str(target[0].get_dir()),bs)
 
357
                target.append(bs+'.cpp')
 
358
                target.append(bs+'.moc')
 
359
                return target, source
 
360
        env['BUILDERS']['Uic']=Builder(action=uic_processing,emitter=uicEmitter,suffix='.h',src_suffix='.ui')
 
361
 
 
362
        def kcfg_buildit(target, source, env):
 
363
                comp='kconfig_compiler -d%s %s %s' % (str(source[0].get_dir()), source[1].path, source[0].path)
 
364
                return env.Execute(comp)
 
365
        def kcfg_stringit(target, source, env):
 
366
                print "processing %s to get %s and %s" % (source[0].name, target[0].name, target[1].name)
 
367
        def kcfgEmitter(target, source, env):
 
368
                adjustixes = SCons.Util.adjustixes
 
369
                file=str(source[0].srcnode().name)
 
370
                bs = SCons.Util.splitext(str(source[0].name))[0]
 
371
                bs = env.join(str(target[0].get_dir()),bs)
 
372
                # .h file is already there
 
373
                target.append( bs+'.cpp' )
 
374
                
 
375
                content=source[0].srcnode().get_contents()
 
376
                #print content
 
377
 
 
378
                kcfgfilename=""
 
379
                kcfgFileDeclRx = re.compile("[fF]ile\s*=\s*(.+)\s*")
 
380
                match = kcfgFileDeclRx.search(content)
 
381
                if match: kcfgfilename = match.group(1)
 
382
 
 
383
                if not kcfgfilename:
 
384
                        env.pprint('RED','invalid kcfgc file '+source[0].srcnode().abspath)
 
385
                        env.Exit(1)
 
386
                source.append( env.join( str(source[0].get_dir()), kcfgfilename) )
 
387
                return target, source
 
388
 
 
389
        env['BUILDERS']['Kcfg']=Builder(action=env.Action(kcfg_buildit, kcfg_stringit),
 
390
                        emitter=kcfgEmitter, suffix='.h', src_suffix='.kcfgc')
 
391
        
 
392
        ## MOC processing
 
393
        env['BUILDERS']['Moc']=Builder(action='$QT_MOC -o $TARGET $SOURCE',suffix='.moc',src_suffix='.h')
 
394
        env['BUILDERS']['Moccpp']=Builder(action='$QT_MOC -o $TARGET $SOURCE',suffix='_moc.cpp',src_suffix='.h')
 
395
 
 
396
        ## KIDL file
 
397
        env['BUILDERS']['Kidl']=Builder(action= 'dcopidl $SOURCE > $TARGET || (rm -f $TARGET ; false)',
 
398
                        suffix='.kidl', src_suffix='.h')
 
399
        ## DCOP
 
400
        env['BUILDERS']['Dcop']=Builder(action='dcopidl2cpp --c++-suffix cpp --no-signals --no-stub $SOURCE',
 
401
                        suffix='_skel.cpp', src_suffix='.kidl')
 
402
        ## STUB
 
403
        env['BUILDERS']['Stub']=Builder(action= 'dcopidl2cpp --c++-suffix cpp --no-signals --no-skel $SOURCE',
 
404
                        suffix='_stub.cpp', src_suffix='.kidl')
 
405
        ## DOCUMENTATION
 
406
        env['BUILDERS']['Meinproc']=Builder(action='cd $TARGET.dir && $MEINPROC --check --cache $TARGET.name $SOURCE.name',suffix='.cache.bz2')
 
407
        ## TRANSLATIONS
 
408
        env['BUILDERS']['Transfiles']=Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
 
409
 
 
410
        ## Handy helpers for building kde programs
 
411
        ## You should not have to modify them ..
 
412
 
 
413
        ui_ext = [".ui"]
 
414
        kcfg_ext = ['.kcfgc']
 
415
        header_ext = [".h", ".hxx", ".hpp", ".hh"]
 
416
        cpp_ext = [".cpp", ".cxx", ".cc"]
 
417
        skel_ext = [".skel", ".SKEL"]
 
418
        stub_ext = [".stub", ".STUB"]
 
419
 
 
420
        def KDEfiles(lenv, target, source):
 
421
                """ Returns a list of files for scons (handles kde tricks like .skel) 
 
422
                It also makes custom checks against double includes like : ['file.ui', 'file.cpp']
 
423
                (file.cpp is already included because of file.ui) """
 
424
 
 
425
                q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]')
 
426
                def scan_moc(cppfile):
 
427
                        addfile=None
 
428
 
 
429
                        # try to find the header
 
430
                        orifile=cppfile.srcnode().name
 
431
                        bs=SCons.Util.splitext(orifile)[0]
 
432
 
 
433
                        h_file=''
 
434
                        dir=cppfile.dir
 
435
                        for n_h_ext in header_ext:
 
436
                                afile=dir.File(bs+n_h_ext)
 
437
                                if afile.rexists():
 
438
                                        #h_ext=n_h_ext
 
439
                                        h_file=afile
 
440
                                        break
 
441
                        # We have the header corresponding to the cpp file
 
442
                        if h_file:
 
443
                                h_contents = h_file.get_contents()
 
444
                                if q_object_search.search(h_contents):
 
445
                                        # we know now there is Q_OBJECT macro
 
446
                                        reg = '\n\s*#include\s*("|<)'+str(bs)+'.moc("|>)'
 
447
                                        meta_object_search = re.compile(reg)
 
448
                                        #cpp_contents = open(file_cpp, 'rb').read()
 
449
                                        cpp_contents=cppfile.get_contents()
 
450
                                        if meta_object_search.search(cpp_contents):
 
451
                                                lenv.Moc(h_file)
 
452
                                        else:
 
453
                                                lenv.Moccpp(h_file)
 
454
                                                addfile=bs+'_moc.cpp'
 
455
                                                print "WARNING: moc.cpp for "+h_file.name+" consider using #include <file.moc> instead"
 
456
                        return addfile
 
457
 
 
458
                src=[]
 
459
                ui_files=[]
 
460
                kcfg_files=[]
 
461
                other_files=[]
 
462
                kidl=[]
 
463
 
 
464
                source_=lenv.make_list(source)
 
465
 
 
466
                # For each file, check wether it is a dcop file or not, and create the complete list of sources
 
467
                for file in source_:
 
468
                        sfile=SCons.Node.FS.default_fs.File(str(file)) # why str(file) ? because ordinal not in range issues
 
469
                        bs  = SCons.Util.splitext(file)[0]
 
470
                        ext = SCons.Util.splitext(file)[1]
 
471
                        if ext in skel_ext:
 
472
                                if not bs in kidl:
 
473
                                        kidl.append(bs)
 
474
                                lenv.Dcop(bs+'.kidl')
 
475
                                src.append(bs+'_skel.cpp')
 
476
                        elif ext in stub_ext:
 
477
                                if not bs in kidl:
 
478
                                        kidl.append(bs)
 
479
                                lenv.Stub(bs+'.kidl')
 
480
                                src.append(bs+'_stub.cpp')
 
481
                        elif ext == ".moch":
 
482
                                lenv.Moccpp(bs+'.h')
 
483
                                src.append(bs+'_moc.cpp')
 
484
                        elif ext in cpp_ext:
 
485
                                src.append(file)
 
486
                                if not env.has_key('NOMOCFILE'):
 
487
                                        ret = scan_moc(sfile)
 
488
                                        if ret: src.append( ret )
 
489
                        elif ext in ui_ext:
 
490
                                lenv.Uic(file)
 
491
                                src.append(bs+'.cpp')
 
492
                        elif ext in kcfg_ext:
 
493
                                name=SCons.Util.splitext(sfile.name)[0]
 
494
                                hfile=lenv.Kcfg(file)
 
495
                                cppkcfgfile=sfile.dir.File(bs+'.cpp')
 
496
                                src.append(bs+'.cpp')
 
497
                        else:
 
498
                                src.append(file)
 
499
 
 
500
                for base in kidl: lenv.Kidl(base+'.h')
 
501
                
 
502
                # Now check against typical newbie errors
 
503
                for file in ui_files:
 
504
                        for ofile in other_files:
 
505
                                if ofile == file:
 
506
                                        env.pprint('RED',"WARNING: You have included %s.ui and another file of the same prefix"%file)
 
507
                                        print "Files generated by uic (file.h, file.cpp must not be included"
 
508
                for file in kcfg_files:
 
509
                        for ofile in other_files:
 
510
                                if ofile == file:
 
511
                                        env.pprint('RED',"WARNING: You have included %s.kcfg and another file of the same prefix"%file)
 
512
                                        print "Files generated by kconfig_compiler (settings.h, settings.cpp) must not be included"
 
513
                return src
 
514
 
 
515
 
 
516
        """ In the future, these functions will contain the code that will dump the
 
517
        configuration for re-use from an IDE """
 
518
        def KDEinstall(lenv, restype, subdir, files, perms=None):
 
519
                if env.has_key('DUMPCONFIG'):
 
520
                        print "<install type=\"%s\" subdir=\"%s\">" % (restype, subdir)
 
521
                        for i in lenv.make_list(files): print "    <file name=\"%s\"/>" % (lenv.join(lenv.getreldir(),i))
 
522
                        print "</install>"
 
523
                        return
 
524
 
 
525
                if not env['_INSTALL']: return None
 
526
                dir = getInstDirForResType(lenv, restype)
 
527
 
 
528
                p=None
 
529
                if not perms:
 
530
                        if restype=='KDEBIN': p=0755
 
531
                else: p=perms
 
532
                install_list = lenv.bksys_install(lenv.join(dir, subdir), files, perms=p)
 
533
                return install_list
 
534
 
 
535
        def KDEinstallas(lenv, restype, destfile, file):
 
536
                if not env['_INSTALL']: return
 
537
                dir = getInstDirForResType(lenv, restype)
 
538
                install_list = lenv.InstallAs(lenv.join(dir, destfile), file)
 
539
                env.Alias('install', install_list)
 
540
                return install_list
 
541
 
 
542
        def KDEprogram(lenv, target, source, 
 
543
                        includes='', localshlibs='', globallibs='', globalcxxflags=''):
 
544
                """ Makes a kde program 
 
545
                The program is installed except if one sets env['NOAUTOINSTALL'] """
 
546
                src = KDEfiles(lenv, target, source)
 
547
                program_list = lenv.Program(target, src)
 
548
 
 
549
                # we link the program against a shared library done locally, add the dependency
 
550
                if not lenv.has_key('nosmart_includes'):
 
551
                        lenv.AppendUnique(CPPPATH=['./'])
 
552
                if len(localshlibs)>0:
 
553
                        lst=lenv.make_list(localshlibs)
 
554
                        lenv.link_local_shlib(lst)
 
555
                        lenv.Depends( program_list, lst )
 
556
                        
 
557
                if len(includes)>0:       lenv.KDEaddpaths_includes(includes)
 
558
                if len(globallibs)>0:     lenv.KDEaddlibs(globallibs)
 
559
                if len(globalcxxflags)>0: lenv.KDEaddflags_cxx(globalcxxflags)
 
560
                
 
561
                if not lenv.has_key('NOAUTOINSTALL'):
 
562
                        KDEinstall(lenv, 'KDEBIN', '', target)
 
563
                return program_list
 
564
 
 
565
        def KDEshlib(lenv, target, source, kdelib=0, libprefix='lib', 
 
566
                        includes='', localshlibs='', globallibs='', globalcxxflags='', vnum=''):
 
567
                """ Makes a shared library for kde (.la file for klibloader)
 
568
                The library is installed except if one sets env['NOAUTOINSTALL'] """
 
569
                src = KDEfiles(lenv, target, source)
 
570
 
 
571
                if not lenv.has_key('nosmart_includes'):
 
572
                        lenv.AppendUnique(CPPPATH=['./'])
 
573
                # we link the program against a shared library done locally, add the dependency
 
574
                lst=[]
 
575
                if len(localshlibs)>0:
 
576
                        lst=lenv.make_list(localshlibs)
 
577
                        lenv.link_local_shlib(lst)
 
578
                if len(includes)>0:       lenv.KDEaddpaths_includes(includes)
 
579
                if len(globallibs)>0:     lenv.KDEaddlibs(globallibs)
 
580
                if len(globalcxxflags)>0: lenv.KDEaddflags_cxx(globalcxxflags)
 
581
 
 
582
                restype='KDEMODULE'
 
583
                if kdelib==1: restype='KDELIB'
 
584
 
 
585
                library_list = lenv.bksys_shlib(target, src, getInstDirForResType(lenv, restype), libprefix, vnum)
 
586
                if len(lst)>0: lenv.Depends( library_list, lst )
 
587
 
 
588
                return library_list
 
589
 
 
590
        def KDEstaticlib(lenv, target, source):
 
591
                """ Makes a static library for kde - in practice you should not use static libraries 
 
592
                1. they take more memory than shared ones
 
593
                2. makefile.am needed it because of limitations
 
594
                (cannot handle sources in separate folders - takes extra processing) """
 
595
                if not lenv.has_key('nosmart_includes'): lenv.AppendUnique(CPPPATH=['./'])
 
596
                src=KDEfiles(lenv, target, source)
 
597
                return lenv.StaticLibrary(target, src)
 
598
                # do not install static libraries by default
 
599
 
 
600
        def KDEaddflags_cxx(lenv, fl):
 
601
                """ Compilation flags for C++ programs """
 
602
                lenv.AppendUnique(CXXFLAGS = lenv.make_list(fl))
 
603
        
 
604
        def KDEaddflags_c(lenv, fl):
 
605
                """ Compilation flags for C programs """
 
606
                lenv.AppendUnique(CFLAGS = lenv.make_list(fl))
 
607
 
 
608
        def KDEaddflags_link(lenv, fl):
 
609
                """ Add link flags - Use this if KDEaddlibs below is not enough """
 
610
                lenv.PrependUnique(LINKFLAGS = lenv.make_list(fl))
 
611
 
 
612
        def KDEaddlibs(lenv, libs):
 
613
                """ Helper function """
 
614
                lenv.AppendUnique(LIBS = lenv.make_list(libs))
 
615
 
 
616
        def KDEaddpaths_includes(lenv, paths):
 
617
                """ Add new include paths """
 
618
                lenv.AppendUnique(CPPPATH = lenv.make_list(paths))
 
619
 
 
620
        def KDEaddpaths_libs(lenv, paths):
 
621
                """ Add paths to libraries """
 
622
                lenv.PrependUnique(LIBPATH = lenv.make_list(paths))
 
623
 
 
624
        def KDElang(lenv, folder, appname):
 
625
                """ Process translations (.po files) in a po/ dir """
 
626
                import glob
 
627
                dir=SCons.Node.FS.default_fs.Dir(folder).srcnode()
 
628
                fld=dir.srcnode()
 
629
                tmptransfiles = glob.glob(str(fld)+'/*.po')
 
630
 
 
631
                transfiles=[]
 
632
                if lenv.has_key('_BUILDDIR_'):
 
633
                        bdir=lenv['_BUILDDIR_']
 
634
                        for dir in lenv.make_list(tmptransfiles):
 
635
                                transfiles.append( lenv.join(bdir, dir) )
 
636
                else: tmptransfiles=transfiles
 
637
 
 
638
                languages=None
 
639
                if lenv['ARGS'] and lenv['ARGS'].has_key('languages'):
 
640
                        languages=lenv.make_list(lenv['ARGS']['languages'])
 
641
                mydir=SCons.Node.FS.default_fs.Dir('.')
 
642
                for f in transfiles:
 
643
                        fname=f.replace(mydir.abspath, '')
 
644
                        file=SCons.Node.FS.default_fs.File(fname)
 
645
                        country = SCons.Util.splitext(file.name)[0]
 
646
                        if not languages or country in languages:
 
647
                                result = lenv.Transfiles(file)
 
648
                                dir=lenv.join( getInstDirForResType(lenv, 'KDELOCALE'), country)
 
649
                                lenv.bksys_install(lenv.join(dir, 'LC_MESSAGES'), result, destfile=appname+'.mo')
 
650
 
 
651
        def KDEicon(lenv, icname='*', path='./', restype='KDEICONS', subdir=''):
 
652
                """Contributed by: "Andrey Golovizin" <grooz()gorodok()net>
 
653
                modified by "Martin Ellis" <m.a.ellis()ncl()ac()uk>
 
654
 
 
655
                Installs icons with filenames such as cr22-action-frame.png into 
 
656
                KDE icon hierachy with names like icons/crystalsvg/22x22/actions/frame.png.
 
657
                
 
658
                Global KDE icons can be installed simply using env.KDEicon('name').
 
659
                The second parameter, path, is optional, and specifies the icons
 
660
                location in the source, relative to the SConscript file.
 
661
 
 
662
                To install icons that need to go under an applications directory (to
 
663
                avoid name conflicts, for example), use e.g.
 
664
                env.KDEicon('name', './', 'KDEDATA', 'appname/icons')"""
 
665
 
 
666
                if env.has_key('DUMPCONFIG'):
 
667
                        print "<icondirent subdir=\"%s\" />" % (lenv.join(lenv.getreldir(),path,subdir))
 
668
                        return
 
669
 
 
670
                type_dic = { 'action':'actions', 'app':'apps', 'device':'devices',
 
671
                        'filesys':'filesystems', 'mime':'mimetypes' } 
 
672
                dir_dic = {
 
673
                'los'  :'locolor/16x16', 'lom'  :'locolor/32x32',
 
674
                'him'  :'hicolor/32x32', 'hil'  :'hicolor/48x48',
 
675
                'lo16' :'locolor/16x16', 'lo22' :'locolor/22x22', 'lo32' :'locolor/32x32',
 
676
                'hi16' :'hicolor/16x16', 'hi22' :'hicolor/22x22', 'hi32' :'hicolor/32x32',
 
677
                'hi48' :'hicolor/48x48', 'hi64' :'hicolor/64x64', 'hi128':'hicolor/128x128',
 
678
                'hisc' :'hicolor/scalable',
 
679
                'cr16' :'crystalsvg/16x16', 'cr22' :'crystalsvg/22x22', 'cr32' :'crystalsvg/32x32',
 
680
                'cr48' :'crystalsvg/48x48', 'cr64' :'crystalsvg/64x64', 'cr128':'crystalsvg/128x128',
 
681
                'crsc' :'crystalsvg/scalable'
 
682
                }
 
683
 
 
684
                iconfiles = []
 
685
                dir=SCons.Node.FS.default_fs.Dir(path).srcnode()
 
686
                mydir=SCons.Node.FS.default_fs.Dir('.')
 
687
                import glob
 
688
                for ext in ['png', 'xpm', 'mng', 'svg', 'svgz']:
 
689
                        files = glob.glob(str(dir)+'/'+'*-*-%s.%s' % (icname, ext))
 
690
                        for file in files:
 
691
                                iconfiles.append( file.replace(mydir.abspath, '') )
 
692
                for iconfile in iconfiles:
 
693
                        lst = iconfile.split('/')
 
694
                        filename = lst[ len(lst) - 1 ]
 
695
                        tmp = filename.split('-')
 
696
                        if len(tmp)!=3:
 
697
                                env.pprint('RED','WARNING: icon filename has unknown format: '+iconfile)
 
698
                                continue
 
699
                        [icon_dir, icon_type, icon_filename]=tmp
 
700
                        try:
 
701
                                basedir=getInstDirForResType(lenv, restype)
 
702
                                destdir = '%s/%s/%s/%s/' % (basedir, subdir, dir_dic[icon_dir], type_dic[icon_type])
 
703
                        except KeyError:
 
704
                                env.pprint('RED','WARNING: unknown icon type: '+iconfile)
 
705
                                continue
 
706
                        lenv.bksys_install(destdir, iconfile, icon_filename)
 
707
 
 
708
        ## This function uses env imported above - WARNING ugly code, i will have to rewrite (ITA)
 
709
        def docfolder(lenv, folder, lang, destination=""):
 
710
                # folder is the folder to process
 
711
                # lang is the language
 
712
                # destination is the subdirectory in KDEDOC
 
713
                import glob
 
714
                docfiles=[]
 
715
                dir=SCons.Node.FS.default_fs.Dir(folder).srcnode()
 
716
                mydir=SCons.Node.FS.default_fs.Dir('.')
 
717
                dirpath=mydir.srcnode().abspath
 
718
                docg = glob.glob(str(dir)+"/???*.*") # file files that are at least 4 chars wide :)
 
719
                for file in docg:
 
720
                        f = file.replace(dirpath, '')
 
721
                        docfiles.append(f)
 
722
                
 
723
                # warn about errors
 
724
                #if len(lang) != 2:
 
725
                #       print "error, lang must be a two-letter string, like 'en'"
 
726
 
 
727
                # when the destination is not given, use the folder
 
728
                if len(destination) == 0: destination=folder
 
729
                docbook_list = []
 
730
 
 
731
                bdir='.'
 
732
                if lenv.has_key('_BUILDDIR_'): bdir = lenv['_BUILDDIR_']
 
733
                for file in docfiles:
 
734
                        # do not process folders
 
735
                        #if not os.path.isfile( lenv.join('.', file) ): continue
 
736
 
 
737
                        # using nodefile forces to symlink in builddir
 
738
                        nodefile=SCons.Node.FS.default_fs.File( lenv.join(mydir.abspath, file) )
 
739
 
 
740
                        # do not process the cache file
 
741
                        if file == 'index.cache.bz2': continue
 
742
                        # ignore invalid files (TODO??)
 
743
                        if len( SCons.Util.splitext( file ) ) <= 1: continue
 
744
                        ext = SCons.Util.splitext( file )[1]
 
745
 
 
746
                        # install picture files
 
747
                        if ext in ['.jpeg', '.jpg', '.png']: lenv.KDEinstall('KDEDOC', lenv.join(lang,destination), nodefile.srcnode())
 
748
                        # docbook files are processed by meinproc
 
749
                        if ext != '.docbook': continue
 
750
                        
 
751
                        docbook_list.append( nodefile )
 
752
                        lenv.KDEinstall('KDEDOC', lenv.join(lang,destination), nodefile.srcnode())
 
753
 
 
754
                # Now process the index.docbook files ..
 
755
                if len(docbook_list) == 0: return
 
756
                # TODO
 
757
                #if not os.path.isfile( folder+'/index.docbook' ):
 
758
                #       print "Error, index.docbook was not found in "+folder+'/index.docbook'
 
759
                #       return
 
760
                ## Define this to 1 if you are writing documentation else to 0 :)
 
761
                #if lenv.has_key('i_am_a_documentation_writer'):
 
762
                for file in docbook_list:
 
763
                        lenv.Depends( folder+'index.cache.bz2', nodefile )
 
764
 
 
765
                if lenv.has_key('_BUILDDIR_'): folder=lenv.join(lenv['_BUILDDIR_'], folder)
 
766
 
 
767
                lenv.Meinproc( lenv.join(folder,'index.cache.bz2'), lenv.join(folder,'index.docbook') )
 
768
                lenv.KDEinstall( 'KDEDOC', lenv.join(lang,destination), lenv.join(folder,'index.cache.bz2') )
 
769
                
 
770
                if env['_INSTALL']:
 
771
                        dir=lenv.join(lenv.getInstDirForResType('KDEDOC'), lang, destination)
 
772
                        comp='mkdir -p %s && cd %s && rm -f common && ln -s ../common common' % (dir, dir)
 
773
                        lenv.Execute(comp)
 
774
 
 
775
        #valid_targets = "program shlib kioslave staticlib".split()
 
776
        import generic
 
777
        class kobject(generic.genobj):
 
778
                def __init__(self, val, senv=None):
 
779
                        if senv: generic.genobj.__init__(self, val, senv)
 
780
                        else: generic.genobj.__init__(self, val, env)
 
781
                        self.iskdelib=0
 
782
                def it_is_a_kdelib(self): self.iskdelib=1
 
783
                def execute(self):
 
784
                        if self.executed: return
 
785
                        self.lockchdir()
 
786
                        if self.orenv.has_key('DUMPCONFIG'):
 
787
                                print self.xml()
 
788
                                self.unlockchdir()
 
789
                                self.executed=1
 
790
                                return
 
791
                        if (self.type=='shlib' or self.type=='kioslave'):
 
792
                                install_dir = 'KDEMODULE'
 
793
                                if self.iskdelib==1: install_dir = 'KDELIB'
 
794
                                self.instdir=getInstDirForResType(self.orenv, install_dir)
 
795
                        elif self.type=='program':
 
796
                                self.instdir=getInstDirForResType(self.orenv, 'KDEBIN')
 
797
                                self.perms=0755
 
798
 
 
799
                        self.p_localsource=KDEfiles(env, self.joinpath(self.target), self.joinpath(self.source))
 
800
                        generic.genobj.execute(self)
 
801
                        self.unlockchdir()
 
802
 
 
803
                def xml(self):
 
804
                        chdirto=self.orenv.join(self.orenv.getreldir(),self.chdir)
 
805
                        ret= '<compile type="%s" chdir="%s" target="%s" cxxflags="%s" cflags="%s" includes="%s" linkflags="%s" libpaths="%s" libs="%s" vnum="%s" iskdelib="%s" libprefix="%s">\n' % (self.type, chdirto, self.target, self.cxxflags, self.cflags, self.includes, self.linkflags, self.libpaths, self.libs, self.vnum, self.iskdelib, self.libprefix)
 
806
                        if self.source:
 
807
                                for i in self.orenv.make_list(self.source): ret+='  <source file="%s"/>\n' % i
 
808
                        ret += "</compile>"
 
809
                        return ret
 
810
 
 
811
        # Attach the functions to the environment so that SConscripts can use them
 
812
        SConsEnvironment.KDEprogram = KDEprogram
 
813
        SConsEnvironment.KDEshlib = KDEshlib
 
814
        SConsEnvironment.KDEstaticlib = KDEstaticlib
 
815
        SConsEnvironment.KDEinstall = KDEinstall
 
816
        SConsEnvironment.KDEinstallas = KDEinstallas
 
817
        SConsEnvironment.KDElang = KDElang
 
818
        SConsEnvironment.KDEicon = KDEicon
 
819
 
 
820
        SConsEnvironment.KDEaddflags_cxx = KDEaddflags_cxx
 
821
        SConsEnvironment.KDEaddflags_c = KDEaddflags_c
 
822
        SConsEnvironment.KDEaddflags_link = KDEaddflags_link
 
823
        SConsEnvironment.KDEaddlibs = KDEaddlibs
 
824
        SConsEnvironment.KDEaddpaths_includes = KDEaddpaths_includes
 
825
        SConsEnvironment.KDEaddpaths_libs = KDEaddpaths_libs
 
826
 
 
827
        SConsEnvironment.docfolder = docfolder
 
828
        SConsEnvironment.getInstDirForResType = getInstDirForResType
 
829
        SConsEnvironment.kobject = kobject
 
830