~elementary-apps/noise/trunk

« back to all changes in this revision

Viewing changes to .waf-1.6.2-ad4cc42bd7d347f7e283789e711b993f/waflib/Tools/qt4.py

  • Committer: Scott Ringwelski
  • Date: 2011-02-10 21:30:53 UTC
  • Revision ID: sgringwe@mtu.edu-20110210213053-d3c7mnexeref3cwj
sexy icons, sexy waf

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
2
# encoding: utf-8
 
3
# WARNING! All changes made to this file will be lost!
 
4
 
 
5
import sys
 
6
if sys.hexversion < 0x020400f0: from sets import Set as set
 
7
try:
 
8
        from xml.sax import make_parser
 
9
        from xml.sax.handler import ContentHandler
 
10
except ImportError:
 
11
        has_xml=False
 
12
        ContentHandler=object
 
13
else:
 
14
        has_xml=True
 
15
import os,sys
 
16
from waflib.Tools import c_preproc,cxx
 
17
from waflib import TaskGen,Task,Utils,Runner,Options,Node,Errors
 
18
from waflib.TaskGen import feature,after,extension
 
19
from waflib.Logs import error
 
20
MOC_H=['.h','.hpp','.hxx','.hh']
 
21
EXT_RCC=['.qrc']
 
22
EXT_UI=['.ui']
 
23
EXT_QT4=['.cpp','.cc','.cxx','.C']
 
24
class qxx(cxx.cxx):
 
25
        def __init__(self,*k,**kw):
 
26
                Task.Task.__init__(self,*k,**kw)
 
27
                self.moc_done=0
 
28
        def scan(self):
 
29
                (nodes,names)=c_preproc.scan(self)
 
30
                for x in nodes:
 
31
                        if x.name.endswith('.moc'):
 
32
                                nodes.remove(x)
 
33
                                names.append(x.path_from(self.inputs[0].parent.get_bld()))
 
34
                return(nodes,names)
 
35
        def runnable_status(self):
 
36
                if self.moc_done:
 
37
                        return Task.Task.runnable_status(self)
 
38
                else:
 
39
                        for t in self.run_after:
 
40
                                if not t.hasrun:
 
41
                                        return Task.ASK_LATER
 
42
                        self.add_moc_tasks()
 
43
                        return Task.Task.runnable_status(self)
 
44
        def add_moc_tasks(self):
 
45
                node=self.inputs[0]
 
46
                bld=self.generator.bld
 
47
                try:
 
48
                        self.signature()
 
49
                except KeyError:
 
50
                        pass
 
51
                else:
 
52
                        delattr(self,'cache_sig')
 
53
                moctasks=[]
 
54
                mocfiles=[]
 
55
                try:
 
56
                        tmp_lst=bld.raw_deps[self.uid()]
 
57
                        bld.raw_deps[self.uid()]=[]
 
58
                except KeyError:
 
59
                        tmp_lst=[]
 
60
                for d in tmp_lst:
 
61
                        if not d.endswith('.moc'):
 
62
                                continue
 
63
                        if d in mocfiles:
 
64
                                error("paranoia owns")
 
65
                                continue
 
66
                        mocfiles.append(d)
 
67
                        h_node=None
 
68
                        try:ext=Options.options.qt_header_ext.split()
 
69
                        except AttributeError:pass
 
70
                        if not ext:ext=MOC_H
 
71
                        base2=d[:-4]
 
72
                        for x in[node.parent]+self.generator.includes_nodes:
 
73
                                for e in ext:
 
74
                                        h_node=x.find_node(base2+e)
 
75
                                        if h_node:
 
76
                                                break
 
77
                                else:
 
78
                                        continue
 
79
                                break
 
80
                        else:
 
81
                                raise Errors.WafError('no header found for %r which is a moc file'%d)
 
82
                        m_node=h_node.change_ext('.moc')
 
83
                        bld.node_deps[(self.inputs[0].parent.abspath(),m_node.name)]=h_node
 
84
                        task=Task.classes['moc'](env=self.env,generator=self.generator)
 
85
                        task.set_inputs(h_node)
 
86
                        task.set_outputs(m_node)
 
87
                        gen=bld.producer
 
88
                        gen.outstanding.insert(0,task)
 
89
                        gen.total+=1
 
90
                        moctasks.append(task)
 
91
                tmp_lst=bld.raw_deps[self.uid()]=mocfiles
 
92
                lst=bld.node_deps.get(self.uid(),())
 
93
                for d in lst:
 
94
                        name=d.name
 
95
                        if name.endswith('.moc'):
 
96
                                task=Task.classes['moc'](env=self.env,generator=self.generator)
 
97
                                task.set_inputs(bld.node_deps[(self.inputs[0].parent.abspath(),name)])
 
98
                                task.set_outputs(d)
 
99
                                gen=bld.producer
 
100
                                gen.outstanding.insert(0,task)
 
101
                                gen.total+=1
 
102
                                moctasks.append(task)
 
103
                self.run_after.update(set(moctasks))
 
104
                self.moc_done=1
 
105
        run=Task.classes['cxx'].__dict__['run']
 
106
class trans_update(Task.Task):
 
107
        run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
 
108
        color='BLUE'
 
109
Task.update_outputs(trans_update)
 
110
class XMLHandler(ContentHandler):
 
111
        def __init__(self):
 
112
                self.buf=[]
 
113
                self.files=[]
 
114
        def startElement(self,name,attrs):
 
115
                if name=='file':
 
116
                        self.buf=[]
 
117
        def endElement(self,name):
 
118
                if name=='file':
 
119
                        self.files.append(str(''.join(self.buf)))
 
120
        def characters(self,cars):
 
121
                self.buf.append(cars)
 
122
def create_rcc_task(self,node):
 
123
        rcnode=node.change_ext('_rc.cpp')
 
124
        rcctask=self.create_task('rcc',node,rcnode)
 
125
        cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o'))
 
126
        self.compiled_tasks.append(cpptask)
 
127
        return cpptask
 
128
def create_uic_task(self,node):
 
129
        uictask=self.create_task('ui4',node)
 
130
        uictask.outputs=[self.path.find_or_declare(self.env['ui_PATTERN']%node.name[:-3])]
 
131
def add_lang(self,node):
 
132
        self.lang=self.to_list(getattr(self,'lang',[]))+[node]
 
133
def apply_qt4(self):
 
134
        if getattr(self,'lang',None):
 
135
                qmtasks=[]
 
136
                for x in self.to_list(self.lang):
 
137
                        if isinstance(x,str):
 
138
                                x=self.path.find_resource(x+'.ts')
 
139
                        qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.qm')))
 
140
                if getattr(self,'update',None)and Options.options.trans_qt4:
 
141
                        cxxnodes=[a.inputs[0]for a in self.compiled_tasks]
 
142
                        for x in qmtasks:
 
143
                                self.create_task('trans_update',cxxnodes,x.inputs)
 
144
                if getattr(self,'langname',None):
 
145
                        qmnodes=[x.outputs[0]for x in qmtasks]
 
146
                        rcnode=self.langname
 
147
                        if isinstance(rcnode,str):
 
148
                                rcnode=self.path.find_or_declare(rcnode+'.qrc')
 
149
                        t=self.create_task('qm2rcc',qmnodes,rcnode)
 
150
                        k=create_rcc_task(self,t.outputs[0])
 
151
                        self.link_task.inputs.append(k.outputs[0])
 
152
        lst=[]
 
153
        for flag in self.to_list(self.env['CXXFLAGS']):
 
154
                if len(flag)<2:continue
 
155
                f=flag[0:2]
 
156
                if f in['-D','-I','/D','/I']:
 
157
                        lst.append(flag)
 
158
        self.env['MOC_FLAGS']=lst
 
159
def cxx_hook(self,node):
 
160
        return self.create_compiled_task('qxx',node)
 
161
class rcc(Task.Task):
 
162
        color='BLUE'
 
163
        run_str='${QT_RCC} -name ${SRC[0].name} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
 
164
        ext_out=['.h']
 
165
        def scan(self):
 
166
                node=self.inputs[0]
 
167
                parser=make_parser()
 
168
                curHandler=XMLHandler()
 
169
                parser.setContentHandler(curHandler)
 
170
                fi=open(self.inputs[0].abspath())
 
171
                parser.parse(fi)
 
172
                fi.close()
 
173
                nodes=[]
 
174
                names=[]
 
175
                root=self.inputs[0].parent
 
176
                for x in curHandler.files:
 
177
                        nd=root.find_resource(x)
 
178
                        if nd:nodes.append(nd)
 
179
                        else:names.append(x)
 
180
                return(nodes,names)
 
181
class moc(Task.Task):
 
182
        color='BLUE'
 
183
        run_str='${QT_MOC} ${MOC_FLAGS} ${SRC} ${MOC_ST} ${TGT}'
 
184
class ui4(Task.Task):
 
185
        color='BLUE'
 
186
        run_str='${QT_UIC} ${SRC} -o ${TGT}'
 
187
        ext_out=['.h']
 
188
class ts2qm(Task.Task):
 
189
        color='BLUE'
 
190
        run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
 
191
class qm2rcc(Task.Task):
 
192
        color='BLUE'
 
193
        after='ts2qm'
 
194
        def run(self):
 
195
                txt='\n'.join(['<file>%s</file>'%k.path_from(self.outputs[0].parent)for k in self.inputs])
 
196
                code='<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>'%txt
 
197
                self.outputs[0].write(code)
 
198
def configure(self):
 
199
        env=self.env
 
200
        opt=Options.options
 
201
        qtdir=getattr(opt,'qtdir','')
 
202
        qtbin=getattr(opt,'qtbin','')
 
203
        qtlibs=getattr(opt,'qtlibs','')
 
204
        useframework=getattr(opt,'use_qt4_osxframework',True)
 
205
        paths=[]
 
206
        if qtbin:
 
207
                paths=[qtbin]
 
208
        if not qtdir:
 
209
                qtdir=self.environ.get('QT4_ROOT','')
 
210
                qtbin=os.path.join(qtdir,'bin')
 
211
                paths=[qtbin]
 
212
        if not qtdir:
 
213
                paths=os.environ.get('PATH','').split(os.pathsep)
 
214
                paths.append('/usr/share/qt4/bin/')
 
215
                try:
 
216
                        lst=os.listdir('/usr/local/Trolltech/')
 
217
                except OSError:
 
218
                        pass
 
219
                else:
 
220
                        if lst:
 
221
                                lst.sort()
 
222
                                lst.reverse()
 
223
                                qtdir='/usr/local/Trolltech/%s/'%lst[0]
 
224
                                qtbin=os.path.join(qtdir,'bin')
 
225
                                paths.append(qtbin)
 
226
        cand=None
 
227
        prev_ver=['4','0','0']
 
228
        for qmk in['qmake-qt4','qmake4','qmake']:
 
229
                try:
 
230
                        qmake=self.find_program(qmk,path_list=paths)
 
231
                except self.errors.ConfigurationError:
 
232
                        pass
 
233
                else:
 
234
                        try:
 
235
                                version=self.cmd_and_log([qmake,'-query','QT_VERSION']).strip()
 
236
                        except self.errors.ConfigurationError:
 
237
                                pass
 
238
                        else:
 
239
                                if version:
 
240
                                        new_ver=version.split('.')
 
241
                                        if new_ver>prev_ver:
 
242
                                                cand=qmake
 
243
                                                prev_ver=new_ver
 
244
        if cand:
 
245
                qmake=cand
 
246
        else:
 
247
                self.fatal('could not find qmake for qt4')
 
248
        self.env.QMAKE=qmake
 
249
        qtincludes=self.cmd_and_log([qmake,'-query','QT_INSTALL_HEADERS']).strip()
 
250
        qtdir=self.cmd_and_log([qmake,'-query','QT_INSTALL_PREFIX']).strip()+os.sep
 
251
        qtbin=self.cmd_and_log([qmake,'-query','QT_INSTALL_BINS']).strip()+os.sep
 
252
        if not qtlibs:
 
253
                try:
 
254
                        qtlibs=self.cmd_and_log([qmake,'-query','QT_INSTALL_LIBS']).strip()
 
255
                except Errors.WafError:
 
256
                        qtlibs=os.path.join(qtdir,'lib')
 
257
        def find_bin(lst,var):
 
258
                for f in lst:
 
259
                        try:
 
260
                                ret=self.find_program(f,path_list=paths)
 
261
                        except self.errors.ConfigurationError:
 
262
                                pass
 
263
                        else:
 
264
                                env[var]=ret
 
265
                                break
 
266
        find_bin(['uic-qt3','uic3'],'QT_UIC3')
 
267
        find_bin(['uic-qt4','uic'],'QT_UIC')
 
268
        if not env['QT_UIC']:
 
269
                self.fatal('cannot find the uic compiler for qt4')
 
270
        try:
 
271
                version=self.cmd_and_log(env['QT_UIC']+" -version 2>&1").strip()
 
272
        except self.errors.ConfigurationError:
 
273
                self.fatal('your uic compiler is for qt3, add uic for qt4 to your path')
 
274
        version=version.replace('Qt User Interface Compiler ','')
 
275
        version=version.replace('User Interface Compiler for Qt','')
 
276
        if version.find(' 3.')!=-1:
 
277
                self.msg('Checking for uic version','(%s: too old)'%version,False)
 
278
                self.fatal('uic is too old')
 
279
        self.msg('Checking for uic version','(%s)'%version)
 
280
        find_bin(['moc-qt4','moc'],'QT_MOC')
 
281
        find_bin(['rcc'],'QT_RCC')
 
282
        find_bin(['lrelease-qt4','lrelease'],'QT_LRELEASE')
 
283
        find_bin(['lupdate-qt4','lupdate'],'QT_LUPDATE')
 
284
        env['UIC3_ST']='%s -o %s'
 
285
        env['UIC_ST']='%s -o %s'
 
286
        env['MOC_ST']='-o'
 
287
        env['ui_PATTERN']='ui_%s.h'
 
288
        env['QT_LRELEASE_FLAGS']=['-silent']
 
289
        vars="QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtWebKit Qt3Support".split()
 
290
        vars_debug=[a+'_debug'for a in vars]
 
291
        if not'PKG_CONFIG_PATH'in os.environ:
 
292
                os.environ['PKG_CONFIG_PATH']='%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib pkg-config --silence-errors'%(qtlibs,qtlibs)
 
293
        pkgconfig=env['pkg-config']or'pkg-config'
 
294
        for i in vars_debug+vars:
 
295
                try:
 
296
                        self.check_cfg(package=i,args='--cflags --libs',path=pkgconfig)
 
297
                except self.errors.ConfigurationError:
 
298
                        pass
 
299
        def process_lib(vars_,coreval):
 
300
                for d in vars_:
 
301
                        var=d.upper()
 
302
                        if var=='QTCORE':
 
303
                                continue
 
304
                        value=env['LIBPATH_'+var]
 
305
                        if value:
 
306
                                core=env[coreval]
 
307
                                accu=[]
 
308
                                for lib in value:
 
309
                                        if lib in core:
 
310
                                                continue
 
311
                                        accu.append(lib)
 
312
                                env['LIBPATH_'+var]=accu
 
313
        process_lib(vars,'LIBPATH_QTCORE')
 
314
        process_lib(vars_debug,'LIBPATH_QTCORE_DEBUG')
 
315
        if Options.options.want_rpath:
 
316
                def process_rpath(vars_,coreval):
 
317
                        for d in vars_:
 
318
                                var=d.upper()
 
319
                                value=env['LIBPATH_'+var]
 
320
                                if value:
 
321
                                        core=env[coreval]
 
322
                                        accu=[]
 
323
                                        for lib in value:
 
324
                                                if var!='QTCORE':
 
325
                                                        if lib in core:
 
326
                                                                continue
 
327
                                                accu.append('-Wl,--rpath='+lib)
 
328
                                        env['RPATH_'+var]=accu
 
329
                process_rpath(vars,'LIBPATH_QTCORE')
 
330
                process_rpath(vars_debug,'LIBPATH_QTCORE_DEBUG')
 
331
def options(opt):
 
332
        opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries')
 
333
        opt.add_option('--header-ext',type='string',default='',help='header extension for moc files',dest='qt_header_ext')
 
334
        for i in'qtdir qtbin qtlibs'.split():
 
335
                opt.add_option('--'+i,type='string',default='',dest=i)
 
336
        if sys.platform=="darwin":
 
337
                opt.add_option('--no-qt4-framework',action="store_false",help='do not use the framework version of Qt4 in OS X',dest='use_qt4_osxframework',default=True)
 
338
        opt.add_option('--translate',action="store_true",help="collect translation strings",dest="trans_qt4",default=False)
 
339
 
 
340
extension(*EXT_RCC)(create_rcc_task)
 
341
extension(*EXT_UI)(create_uic_task)
 
342
extension('.ts')(add_lang)
 
343
feature('qt4')(apply_qt4)
 
344
after('apply_link')(apply_qt4)
 
345
extension(*EXT_QT4)(cxx_hook)
 
 
b'\\ No newline at end of file'