source: waflib/Tools/qt5.py @ 904702d

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 904702d was 904702d, checked in by Paul Brossier <piem@piem.org>, 9 years ago

waf, waflib: update to 1.8.7

  • Property mode set to 100644
File size: 14.3 KB
Line 
1#! /usr/bin/env python
2# encoding: utf-8
3# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
4
5try:
6        from xml.sax import make_parser
7        from xml.sax.handler import ContentHandler
8except ImportError:
9        has_xml=False
10        ContentHandler=object
11else:
12        has_xml=True
13import os,sys
14from waflib.Tools import cxx
15from waflib import Task,Utils,Options,Errors,Context
16from waflib.TaskGen import feature,after_method,extension
17from waflib.Configure import conf
18from waflib import Logs
19MOC_H=['.h','.hpp','.hxx','.hh']
20EXT_RCC=['.qrc']
21EXT_UI=['.ui']
22EXT_QT5=['.cpp','.cc','.cxx','.C']
23QT5_LIBS='''
24qtmain
25Qt5Bluetooth
26Qt5CLucene
27Qt5Concurrent
28Qt5Core
29Qt5DBus
30Qt5Declarative
31Qt5DesignerComponents
32Qt5Designer
33Qt5Gui
34Qt5Help
35Qt5MultimediaQuick_p
36Qt5Multimedia
37Qt5MultimediaWidgets
38Qt5Network
39Qt5Nfc
40Qt5OpenGL
41Qt5Positioning
42Qt5PrintSupport
43Qt5Qml
44Qt5QuickParticles
45Qt5Quick
46Qt5QuickTest
47Qt5Script
48Qt5ScriptTools
49Qt5Sensors
50Qt5SerialPort
51Qt5Sql
52Qt5Svg
53Qt5Test
54Qt5WebKit
55Qt5WebKitWidgets
56Qt5Widgets
57Qt5WinExtras
58Qt5X11Extras
59Qt5XmlPatterns
60Qt5Xml'''
61class qxx(Task.classes['cxx']):
62        def __init__(self,*k,**kw):
63                Task.Task.__init__(self,*k,**kw)
64                self.moc_done=0
65        def runnable_status(self):
66                if self.moc_done:
67                        return Task.Task.runnable_status(self)
68                else:
69                        for t in self.run_after:
70                                if not t.hasrun:
71                                        return Task.ASK_LATER
72                        self.add_moc_tasks()
73                        return Task.Task.runnable_status(self)
74        def create_moc_task(self,h_node,m_node):
75                try:
76                        moc_cache=self.generator.bld.moc_cache
77                except AttributeError:
78                        moc_cache=self.generator.bld.moc_cache={}
79                try:
80                        return moc_cache[h_node]
81                except KeyError:
82                        tsk=moc_cache[h_node]=Task.classes['moc'](env=self.env,generator=self.generator)
83                        tsk.set_inputs(h_node)
84                        tsk.set_outputs(m_node)
85                        if self.generator:
86                                self.generator.tasks.append(tsk)
87                        gen=self.generator.bld.producer
88                        gen.outstanding.insert(0,tsk)
89                        gen.total+=1
90                        return tsk
91                else:
92                        delattr(self,'cache_sig')
93        def moc_h_ext(self):
94                try:
95                        ext=Options.options.qt_header_ext.split()
96                except AttributeError:
97                        pass
98                if not ext:
99                        ext=MOC_H
100                return ext
101        def add_moc_tasks(self):
102                node=self.inputs[0]
103                bld=self.generator.bld
104                try:
105                        self.signature()
106                except KeyError:
107                        pass
108                else:
109                        delattr(self,'cache_sig')
110                include_nodes=[node.parent]+self.generator.includes_nodes
111                moctasks=[]
112                mocfiles=set([])
113                for d in bld.raw_deps.get(self.uid(),[]):
114                        if not d.endswith('.moc'):
115                                continue
116                        if d in mocfiles:
117                                continue
118                        mocfiles.add(d)
119                        h_node=None
120                        base2=d[:-4]
121                        for x in include_nodes:
122                                for e in self.moc_h_ext():
123                                        h_node=x.find_node(base2+e)
124                                        if h_node:
125                                                break
126                                if h_node:
127                                        m_node=h_node.change_ext('.moc')
128                                        break
129                        else:
130                                for k in EXT_QT5:
131                                        if base2.endswith(k):
132                                                for x in include_nodes:
133                                                        h_node=x.find_node(base2)
134                                                        if h_node:
135                                                                break
136                                                if h_node:
137                                                        m_node=h_node.change_ext(k+'.moc')
138                                                        break
139                        if not h_node:
140                                raise Errors.WafError('No source found for %r which is a moc file'%d)
141                        task=self.create_moc_task(h_node,m_node)
142                        moctasks.append(task)
143                self.run_after.update(set(moctasks))
144                self.moc_done=1
145class trans_update(Task.Task):
146        run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
147        color='BLUE'
148Task.update_outputs(trans_update)
149class XMLHandler(ContentHandler):
150        def __init__(self):
151                self.buf=[]
152                self.files=[]
153        def startElement(self,name,attrs):
154                if name=='file':
155                        self.buf=[]
156        def endElement(self,name):
157                if name=='file':
158                        self.files.append(str(''.join(self.buf)))
159        def characters(self,cars):
160                self.buf.append(cars)
161@extension(*EXT_RCC)
162def create_rcc_task(self,node):
163        rcnode=node.change_ext('_rc.cpp')
164        self.create_task('rcc',node,rcnode)
165        cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o'))
166        try:
167                self.compiled_tasks.append(cpptask)
168        except AttributeError:
169                self.compiled_tasks=[cpptask]
170        return cpptask
171@extension(*EXT_UI)
172def create_uic_task(self,node):
173        uictask=self.create_task('ui5',node)
174        uictask.outputs=[self.path.find_or_declare(self.env['ui_PATTERN']%node.name[:-3])]
175@extension('.ts')
176def add_lang(self,node):
177        self.lang=self.to_list(getattr(self,'lang',[]))+[node]
178@feature('qt5')
179@after_method('apply_link')
180def apply_qt5(self):
181        if getattr(self,'lang',None):
182                qmtasks=[]
183                for x in self.to_list(self.lang):
184                        if isinstance(x,str):
185                                x=self.path.find_resource(x+'.ts')
186                        qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.qm')))
187                if getattr(self,'update',None)and Options.options.trans_qt5:
188                        cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if getattr(a,'inputs',None)and a.inputs[0].name.endswith('.ui')]
189                        for x in qmtasks:
190                                self.create_task('trans_update',cxxnodes,x.inputs)
191                if getattr(self,'langname',None):
192                        qmnodes=[x.outputs[0]for x in qmtasks]
193                        rcnode=self.langname
194                        if isinstance(rcnode,str):
195                                rcnode=self.path.find_or_declare(rcnode+'.qrc')
196                        t=self.create_task('qm2rcc',qmnodes,rcnode)
197                        k=create_rcc_task(self,t.outputs[0])
198                        self.link_task.inputs.append(k.outputs[0])
199        lst=[]
200        for flag in self.to_list(self.env['CXXFLAGS']):
201                if len(flag)<2:continue
202                f=flag[0:2]
203                if f in('-D','-I','/D','/I'):
204                        if(f[0]=='/'):
205                                lst.append('-'+flag[1:])
206                        else:
207                                lst.append(flag)
208        self.env.append_value('MOC_FLAGS',lst)
209@extension(*EXT_QT5)
210def cxx_hook(self,node):
211        return self.create_compiled_task('qxx',node)
212class rcc(Task.Task):
213        color='BLUE'
214        run_str='${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
215        ext_out=['.h']
216        def rcname(self):
217                return os.path.splitext(self.inputs[0].name)[0]
218        def scan(self):
219                if not has_xml:
220                        Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
221                        return([],[])
222                parser=make_parser()
223                curHandler=XMLHandler()
224                parser.setContentHandler(curHandler)
225                fi=open(self.inputs[0].abspath(),'r')
226                try:
227                        parser.parse(fi)
228                finally:
229                        fi.close()
230                nodes=[]
231                names=[]
232                root=self.inputs[0].parent
233                for x in curHandler.files:
234                        nd=root.find_resource(x)
235                        if nd:nodes.append(nd)
236                        else:names.append(x)
237                return(nodes,names)
238class moc(Task.Task):
239        color='BLUE'
240        run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
241class ui5(Task.Task):
242        color='BLUE'
243        run_str='${QT_UIC} ${SRC} -o ${TGT}'
244        ext_out=['.h']
245class ts2qm(Task.Task):
246        color='BLUE'
247        run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
248class qm2rcc(Task.Task):
249        color='BLUE'
250        after='ts2qm'
251        def run(self):
252                txt='\n'.join(['<file>%s</file>'%k.path_from(self.outputs[0].parent)for k in self.inputs])
253                code='<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>'%txt
254                self.outputs[0].write(code)
255def configure(self):
256        self.find_qt5_binaries()
257        self.set_qt5_libs_to_check()
258        self.set_qt5_defines()
259        self.find_qt5_libraries()
260        self.add_qt5_rpath()
261        self.simplify_qt5_libs()
262@conf
263def find_qt5_binaries(self):
264        env=self.env
265        opt=Options.options
266        qtdir=getattr(opt,'qtdir','')
267        qtbin=getattr(opt,'qtbin','')
268        paths=[]
269        if qtdir:
270                qtbin=os.path.join(qtdir,'bin')
271        if not qtdir:
272                qtdir=os.environ.get('QT5_ROOT','')
273                qtbin=os.environ.get('QT5_BIN',None)or os.path.join(qtdir,'bin')
274        if qtbin:
275                paths=[qtbin]
276        if not qtdir:
277                paths=os.environ.get('PATH','').split(os.pathsep)
278                paths.append('/usr/share/qt5/bin/')
279                try:
280                        lst=Utils.listdir('/usr/local/Trolltech/')
281                except OSError:
282                        pass
283                else:
284                        if lst:
285                                lst.sort()
286                                lst.reverse()
287                                qtdir='/usr/local/Trolltech/%s/'%lst[0]
288                                qtbin=os.path.join(qtdir,'bin')
289                                paths.append(qtbin)
290        cand=None
291        prev_ver=['5','0','0']
292        for qmk in('qmake-qt5','qmake5','qmake'):
293                try:
294                        qmake=self.find_program(qmk,path_list=paths)
295                except self.errors.ConfigurationError:
296                        pass
297                else:
298                        try:
299                                version=self.cmd_and_log(qmake+['-query','QT_VERSION']).strip()
300                        except self.errors.WafError:
301                                pass
302                        else:
303                                if version:
304                                        new_ver=version.split('.')
305                                        if new_ver>prev_ver:
306                                                cand=qmake
307                                                prev_ver=new_ver
308        if not cand:
309                try:
310                        self.find_program('qtchooser')
311                except self.errors.ConfigurationError:
312                        pass
313                else:
314                        cmd=self.env.QTCHOOSER+['-qt=5','-run-tool=qmake']
315                        try:
316                                version=self.cmd_and_log(cmd+['-query','QT_VERSION'])
317                        except self.errors.WafError:
318                                pass
319                        else:
320                                cand=cmd
321        if cand:
322                self.env.QMAKE=cand
323        else:
324                self.fatal('Could not find qmake for qt5')
325        self.env.QT_INSTALL_BINS=qtbin=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_BINS']).strip()+os.sep
326        paths.insert(0,qtbin)
327        def find_bin(lst,var):
328                if var in env:
329                        return
330                for f in lst:
331                        try:
332                                ret=self.find_program(f,path_list=paths)
333                        except self.errors.ConfigurationError:
334                                pass
335                        else:
336                                env[var]=ret
337                                break
338        find_bin(['uic-qt5','uic'],'QT_UIC')
339        if not env.QT_UIC:
340                self.fatal('cannot find the uic compiler for qt5')
341        self.start_msg('Checking for uic version')
342        uicver=self.cmd_and_log(env.QT_UIC+['-version'],output=Context.BOTH)
343        uicver=''.join(uicver).strip()
344        uicver=uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt','')
345        self.end_msg(uicver)
346        if uicver.find(' 3.')!=-1 or uicver.find(' 4.')!=-1:
347                self.fatal('this uic compiler is for qt3 or qt5, add uic for qt5 to your path')
348        find_bin(['moc-qt5','moc'],'QT_MOC')
349        find_bin(['rcc-qt5','rcc'],'QT_RCC')
350        find_bin(['lrelease-qt5','lrelease'],'QT_LRELEASE')
351        find_bin(['lupdate-qt5','lupdate'],'QT_LUPDATE')
352        env['UIC_ST']='%s -o %s'
353        env['MOC_ST']='-o'
354        env['ui_PATTERN']='ui_%s.h'
355        env['QT_LRELEASE_FLAGS']=['-silent']
356        env.MOCCPPPATH_ST='-I%s'
357        env.MOCDEFINES_ST='-D%s'
358@conf
359def find_qt5_libraries(self):
360        qtlibs=getattr(Options.options,'qtlibs',None)or os.environ.get("QT5_LIBDIR",None)
361        if not qtlibs:
362                try:
363                        qtlibs=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_LIBS']).strip()
364                except Errors.WafError:
365                        qtdir=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_PREFIX']).strip()+os.sep
366                        qtlibs=os.path.join(qtdir,'lib')
367        self.msg('Found the Qt5 libraries in',qtlibs)
368        qtincludes=os.environ.get("QT5_INCLUDES",None)or self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_HEADERS']).strip()
369        env=self.env
370        if not'PKG_CONFIG_PATH'in os.environ:
371                os.environ['PKG_CONFIG_PATH']='%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib'%(qtlibs,qtlibs)
372        try:
373                if os.environ.get("QT5_XCOMPILE",None):
374                        raise self.errors.ConfigurationError()
375                self.check_cfg(atleast_pkgconfig_version='0.1')
376        except self.errors.ConfigurationError:
377                for i in self.qt5_vars:
378                        uselib=i.upper()
379                        if Utils.unversioned_sys_platform()=="darwin":
380                                frameworkName=i+".framework"
381                                qtDynamicLib=os.path.join(qtlibs,frameworkName,i)
382                                if os.path.exists(qtDynamicLib):
383                                        env.append_unique('FRAMEWORK_'+uselib,i)
384                                        self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
385                                else:
386                                        self.msg('Checking for %s'%i,False,'YELLOW')
387                                env.append_unique('INCLUDES_'+uselib,os.path.join(qtlibs,frameworkName,'Headers'))
388                        elif env.DEST_OS!="win32":
389                                qtDynamicLib=os.path.join(qtlibs,"lib"+i+".so")
390                                qtStaticLib=os.path.join(qtlibs,"lib"+i+".a")
391                                if os.path.exists(qtDynamicLib):
392                                        env.append_unique('LIB_'+uselib,i)
393                                        self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
394                                elif os.path.exists(qtStaticLib):
395                                        env.append_unique('LIB_'+uselib,i)
396                                        self.msg('Checking for %s'%i,qtStaticLib,'GREEN')
397                                else:
398                                        self.msg('Checking for %s'%i,False,'YELLOW')
399                                env.append_unique('LIBPATH_'+uselib,qtlibs)
400                                env.append_unique('INCLUDES_'+uselib,qtincludes)
401                                env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
402                        else:
403                                for k in("lib%s.a","lib%s5.a","%s.lib","%s5.lib"):
404                                        lib=os.path.join(qtlibs,k%i)
405                                        if os.path.exists(lib):
406                                                env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
407                                                self.msg('Checking for %s'%i,lib,'GREEN')
408                                                break
409                                else:
410                                        self.msg('Checking for %s'%i,False,'YELLOW')
411                                env.append_unique('LIBPATH_'+uselib,qtlibs)
412                                env.append_unique('INCLUDES_'+uselib,qtincludes)
413                                env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
414                                uselib=i.upper()+"_debug"
415                                for k in("lib%sd.a","lib%sd5.a","%sd.lib","%sd5.lib"):
416                                        lib=os.path.join(qtlibs,k%i)
417                                        if os.path.exists(lib):
418                                                env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
419                                                self.msg('Checking for %s'%i,lib,'GREEN')
420                                                break
421                                else:
422                                        self.msg('Checking for %s'%i,False,'YELLOW')
423                                env.append_unique('LIBPATH_'+uselib,qtlibs)
424                                env.append_unique('INCLUDES_'+uselib,qtincludes)
425                                env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
426        else:
427                for i in self.qt5_vars_debug+self.qt5_vars:
428                        self.check_cfg(package=i,args='--cflags --libs',mandatory=False)
429@conf
430def simplify_qt5_libs(self):
431        env=self.env
432        def process_lib(vars_,coreval):
433                for d in vars_:
434                        var=d.upper()
435                        if var=='QTCORE':
436                                continue
437                        value=env['LIBPATH_'+var]
438                        if value:
439                                core=env[coreval]
440                                accu=[]
441                                for lib in value:
442                                        if lib in core:
443                                                continue
444                                        accu.append(lib)
445                                env['LIBPATH_'+var]=accu
446        process_lib(self.qt5_vars,'LIBPATH_QTCORE')
447        process_lib(self.qt5_vars_debug,'LIBPATH_QTCORE_DEBUG')
448@conf
449def add_qt5_rpath(self):
450        env=self.env
451        if getattr(Options.options,'want_rpath',False):
452                def process_rpath(vars_,coreval):
453                        for d in vars_:
454                                var=d.upper()
455                                value=env['LIBPATH_'+var]
456                                if value:
457                                        core=env[coreval]
458                                        accu=[]
459                                        for lib in value:
460                                                if var!='QTCORE':
461                                                        if lib in core:
462                                                                continue
463                                                accu.append('-Wl,--rpath='+lib)
464                                        env['RPATH_'+var]=accu
465                process_rpath(self.qt5_vars,'LIBPATH_QTCORE')
466                process_rpath(self.qt5_vars_debug,'LIBPATH_QTCORE_DEBUG')
467@conf
468def set_qt5_libs_to_check(self):
469        if not hasattr(self,'qt5_vars'):
470                self.qt5_vars=QT5_LIBS
471        self.qt5_vars=Utils.to_list(self.qt5_vars)
472        if not hasattr(self,'qt5_vars_debug'):
473                self.qt5_vars_debug=[a+'_debug'for a in self.qt5_vars]
474        self.qt5_vars_debug=Utils.to_list(self.qt5_vars_debug)
475@conf
476def set_qt5_defines(self):
477        if sys.platform!='win32':
478                return
479        for x in self.qt5_vars:
480                y=x[2:].upper()
481                self.env.append_unique('DEFINES_%s'%x.upper(),'QT_%s_LIB'%y)
482                self.env.append_unique('DEFINES_%s_DEBUG'%x.upper(),'QT_%s_LIB'%y)
483def options(opt):
484        opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries')
485        opt.add_option('--header-ext',type='string',default='',help='header extension for moc files',dest='qt_header_ext')
486        for i in'qtdir qtbin qtlibs'.split():
487                opt.add_option('--'+i,type='string',default='',dest=i)
488        opt.add_option('--translate',action="store_true",help="collect translation strings",dest="trans_qt5",default=False)
Note: See TracBrowser for help on using the repository browser.