build:wafsamba: Remove unnecessary parameters to cmd_and_log
[nivanova/samba-autobuild/.git] / third_party / waf / waflib / Tools / qt4.py
1 #! /usr/bin/env python
2 # encoding: utf-8
3 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
4
5 #!/usr/bin/env python
6 # encoding: utf-8
7 # Thomas Nagy, 2006-2010 (ita)
8
9 """
10
11 Tool Description
12 ================
13
14 This tool helps with finding Qt4 tools and libraries,
15 and also provides syntactic sugar for using Qt4 tools.
16
17 The following snippet illustrates the tool usage::
18
19         def options(opt):
20                 opt.load('compiler_cxx qt4')
21
22         def configure(conf):
23                 conf.load('compiler_cxx qt4')
24
25         def build(bld):
26                 bld(
27                         features = 'qt4 cxx cxxprogram',
28                         uselib   = 'QTCORE QTGUI QTOPENGL QTSVG',
29                         source   = 'main.cpp textures.qrc aboutDialog.ui',
30                         target   = 'window',
31                 )
32
33 Here, the UI description and resource files will be processed
34 to generate code.
35
36 Usage
37 =====
38
39 Load the "qt4" tool.
40
41 You also need to edit your sources accordingly:
42
43 - the normal way of doing things is to have your C++ files
44   include the .moc file.
45   This is regarded as the best practice (and provides much faster
46   compilations).
47   It also implies that the include paths have beenset properly.
48
49 - to have the include paths added automatically, use the following::
50
51      from waflib.TaskGen import feature, before_method, after_method
52      @feature('cxx')
53      @after_method('process_source')
54      @before_method('apply_incpaths')
55      def add_includes_paths(self):
56         incs = set(self.to_list(getattr(self, 'includes', '')))
57         for x in self.compiled_tasks:
58             incs.add(x.inputs[0].parent.path_from(self.path))
59         self.includes = list(incs)
60
61 Note: another tool provides Qt processing that does not require
62 .moc includes, see 'playground/slow_qt/'.
63
64 A few options (--qt{dir,bin,...}) and environment variables
65 (QT4_{ROOT,DIR,MOC,UIC,XCOMPILE}) allow finer tuning of the tool,
66 tool path selection, etc; please read the source for more info.
67
68 """
69
70 try:
71         from xml.sax import make_parser
72         from xml.sax.handler import ContentHandler
73 except ImportError:
74         has_xml = False
75         ContentHandler = object
76 else:
77         has_xml = True
78
79 import os, sys
80 from waflib.Tools import cxx
81 from waflib import Task, Utils, Options, Errors, Context
82 from waflib.TaskGen import feature, after_method, extension
83 from waflib.Configure import conf
84 from waflib import Logs
85
86 MOC_H = ['.h', '.hpp', '.hxx', '.hh']
87 """
88 File extensions associated to the .moc files
89 """
90
91 EXT_RCC = ['.qrc']
92 """
93 File extension for the resource (.qrc) files
94 """
95
96 EXT_UI  = ['.ui']
97 """
98 File extension for the user interface (.ui) files
99 """
100
101 EXT_QT4 = ['.cpp', '.cc', '.cxx', '.C']
102 """
103 File extensions of C++ files that may require a .moc processing
104 """
105
106 QT4_LIBS = "QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtXmlPatterns QtWebKit Qt3Support QtHelp QtScript QtDeclarative QtDesigner"
107
108 class qxx(Task.classes['cxx']):
109         """
110         Each C++ file can have zero or several .moc files to create.
111         They are known only when the files are scanned (preprocessor)
112         To avoid scanning the c++ files each time (parsing C/C++), the results
113         are retrieved from the task cache (bld.node_deps/bld.raw_deps).
114         The moc tasks are also created *dynamically* during the build.
115         """
116
117         def __init__(self, *k, **kw):
118                 Task.Task.__init__(self, *k, **kw)
119                 self.moc_done = 0
120
121         def runnable_status(self):
122                 """
123                 Compute the task signature to make sure the scanner was executed. Create the
124                 moc tasks by using :py:meth:`waflib.Tools.qt4.qxx.add_moc_tasks` (if necessary),
125                 then postpone the task execution (there is no need to recompute the task signature).
126                 """
127                 if self.moc_done:
128                         return Task.Task.runnable_status(self)
129                 else:
130                         for t in self.run_after:
131                                 if not t.hasrun:
132                                         return Task.ASK_LATER
133                         self.add_moc_tasks()
134                         return Task.Task.runnable_status(self)
135
136         def create_moc_task(self, h_node, m_node):
137                 """
138                 If several libraries use the same classes, it is possible that moc will run several times (Issue 1318)
139                 It is not possible to change the file names, but we can assume that the moc transformation will be identical,
140                 and the moc tasks can be shared in a global cache.
141
142                 The defines passed to moc will then depend on task generator order. If this is not acceptable, then
143                 use the tool slow_qt4 instead (and enjoy the slow builds... :-( )
144                 """
145                 try:
146                         moc_cache = self.generator.bld.moc_cache
147                 except AttributeError:
148                         moc_cache = self.generator.bld.moc_cache = {}
149
150                 try:
151                         return moc_cache[h_node]
152                 except KeyError:
153                         tsk = moc_cache[h_node] = Task.classes['moc'](env=self.env, generator=self.generator)
154                         tsk.set_inputs(h_node)
155                         tsk.set_outputs(m_node)
156
157                         if self.generator:
158                                 self.generator.tasks.append(tsk)
159
160                         # direct injection in the build phase (safe because called from the main thread)
161                         gen = self.generator.bld.producer
162                         gen.outstanding.insert(0, tsk)
163                         gen.total += 1
164
165                         return tsk
166
167         def moc_h_ext(self):
168                 ext = []
169                 try:
170                         ext = Options.options.qt_header_ext.split()
171                 except AttributeError:
172                         pass
173                 if not ext:
174                         ext = MOC_H
175                 return ext
176
177         def add_moc_tasks(self):
178                 """
179                 Create the moc tasks by looking in ``bld.raw_deps[self.uid()]``
180                 """
181                 node = self.inputs[0]
182                 bld = self.generator.bld
183
184                 try:
185                         # compute the signature once to know if there is a moc file to create
186                         self.signature()
187                 except KeyError:
188                         # the moc file may be referenced somewhere else
189                         pass
190                 else:
191                         # remove the signature, it must be recomputed with the moc task
192                         delattr(self, 'cache_sig')
193
194                 include_nodes = [node.parent] + self.generator.includes_nodes
195
196                 moctasks = []
197                 mocfiles = set([])
198                 for d in bld.raw_deps.get(self.uid(), []):
199                         if not d.endswith('.moc'):
200                                 continue
201
202                         # process that base.moc only once
203                         if d in mocfiles:
204                                 continue
205                         mocfiles.add(d)
206
207                         # find the source associated with the moc file
208                         h_node = None
209
210                         base2 = d[:-4]
211                         for x in include_nodes:
212                                 for e in self.moc_h_ext():
213                                         h_node = x.find_node(base2 + e)
214                                         if h_node:
215                                                 break
216                                 if h_node:
217                                         m_node = h_node.change_ext('.moc')
218                                         break
219                         else:
220                                 # foo.cpp -> foo.cpp.moc
221                                 for k in EXT_QT4:
222                                         if base2.endswith(k):
223                                                 for x in include_nodes:
224                                                         h_node = x.find_node(base2)
225                                                         if h_node:
226                                                                 break
227                                                 if h_node:
228                                                         m_node = h_node.change_ext(k + '.moc')
229                                                         break
230
231                         if not h_node:
232                                 raise Errors.WafError('No source found for %r which is a moc file' % d)
233
234                         # create the moc task
235                         task = self.create_moc_task(h_node, m_node)
236                         moctasks.append(task)
237
238                 # simple scheduler dependency: run the moc task before others
239                 self.run_after.update(set(moctasks))
240                 self.moc_done = 1
241
242 class trans_update(Task.Task):
243         """Update a .ts files from a list of C++ files"""
244         run_str = '${QT_LUPDATE} ${SRC} -ts ${TGT}'
245         color   = 'BLUE'
246 Task.update_outputs(trans_update)
247
248 class XMLHandler(ContentHandler):
249         """
250         Parser for *.qrc* files
251         """
252         def __init__(self):
253                 self.buf = []
254                 self.files = []
255         def startElement(self, name, attrs):
256                 if name == 'file':
257                         self.buf = []
258         def endElement(self, name):
259                 if name == 'file':
260                         self.files.append(str(''.join(self.buf)))
261         def characters(self, cars):
262                 self.buf.append(cars)
263
264 @extension(*EXT_RCC)
265 def create_rcc_task(self, node):
266         "Create rcc and cxx tasks for *.qrc* files"
267         rcnode = node.change_ext('_rc.cpp')
268         self.create_task('rcc', node, rcnode)
269         cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o'))
270         try:
271                 self.compiled_tasks.append(cpptask)
272         except AttributeError:
273                 self.compiled_tasks = [cpptask]
274         return cpptask
275
276 @extension(*EXT_UI)
277 def create_uic_task(self, node):
278         "hook for uic tasks"
279         uictask = self.create_task('ui4', node)
280         uictask.outputs = [self.path.find_or_declare(self.env['ui_PATTERN'] % node.name[:-3])]
281
282 @extension('.ts')
283 def add_lang(self, node):
284         """add all the .ts file into self.lang"""
285         self.lang = self.to_list(getattr(self, 'lang', [])) + [node]
286
287 @feature('qt4')
288 @after_method('apply_link')
289 def apply_qt4(self):
290         """
291         Add MOC_FLAGS which may be necessary for moc::
292
293                 def build(bld):
294                         bld.program(features='qt4', source='main.cpp', target='app', use='QTCORE')
295
296         The additional parameters are:
297
298         :param lang: list of translation files (\*.ts) to process
299         :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension
300         :param update: whether to process the C++ files to update the \*.ts files (use **waf --translate**)
301         :type update: bool
302         :param langname: if given, transform the \*.ts files into a .qrc files to include in the binary file
303         :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension
304         """
305         if getattr(self, 'lang', None):
306                 qmtasks = []
307                 for x in self.to_list(self.lang):
308                         if isinstance(x, str):
309                                 x = self.path.find_resource(x + '.ts')
310                         qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.qm')))
311
312                 if getattr(self, 'update', None) and Options.options.trans_qt4:
313                         cxxnodes = [a.inputs[0] for a in self.compiled_tasks] + [
314                                 a.inputs[0] for a in self.tasks if getattr(a, 'inputs', None) and a.inputs[0].name.endswith('.ui')]
315                         for x in qmtasks:
316                                 self.create_task('trans_update', cxxnodes, x.inputs)
317
318                 if getattr(self, 'langname', None):
319                         qmnodes = [x.outputs[0] for x in qmtasks]
320                         rcnode = self.langname
321                         if isinstance(rcnode, str):
322                                 rcnode = self.path.find_or_declare(rcnode + '.qrc')
323                         t = self.create_task('qm2rcc', qmnodes, rcnode)
324                         k = create_rcc_task(self, t.outputs[0])
325                         self.link_task.inputs.append(k.outputs[0])
326
327         lst = []
328         for flag in self.to_list(self.env['CXXFLAGS']):
329                 if len(flag) < 2: continue
330                 f = flag[0:2]
331                 if f in ('-D', '-I', '/D', '/I'):
332                         if (f[0] == '/'):
333                                 lst.append('-' + flag[1:])
334                         else:
335                                 lst.append(flag)
336         self.env.append_value('MOC_FLAGS', lst)
337
338 @extension(*EXT_QT4)
339 def cxx_hook(self, node):
340         """
341         Re-map C++ file extensions to the :py:class:`waflib.Tools.qt4.qxx` task.
342         """
343         return self.create_compiled_task('qxx', node)
344
345 class rcc(Task.Task):
346         """
347         Process *.qrc* files
348         """
349         color   = 'BLUE'
350         run_str = '${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
351         ext_out = ['.h']
352
353         def rcname(self):
354                 return os.path.splitext(self.inputs[0].name)[0]
355
356         def scan(self):
357                 """Parse the *.qrc* files"""
358                 if not has_xml:
359                         Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
360                         return ([], [])
361
362                 parser = make_parser()
363                 curHandler = XMLHandler()
364                 parser.setContentHandler(curHandler)
365                 fi = open(self.inputs[0].abspath(), 'r')
366                 try:
367                         parser.parse(fi)
368                 finally:
369                         fi.close()
370
371                 nodes = []
372                 names = []
373                 root = self.inputs[0].parent
374                 for x in curHandler.files:
375                         nd = root.find_resource(x)
376                         if nd: nodes.append(nd)
377                         else: names.append(x)
378                 return (nodes, names)
379
380 class moc(Task.Task):
381         """
382         Create *.moc* files
383         """
384         color   = 'BLUE'
385         run_str = '${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
386         def keyword(self):
387                 return "Creating"
388         def __str__(self):
389                 return self.outputs[0].path_from(self.generator.bld.launch_node())
390
391 class ui4(Task.Task):
392         """
393         Process *.ui* files
394         """
395         color   = 'BLUE'
396         run_str = '${QT_UIC} ${SRC} -o ${TGT}'
397         ext_out = ['.h']
398
399 class ts2qm(Task.Task):
400         """
401         Create *.qm* files from *.ts* files
402         """
403         color   = 'BLUE'
404         run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
405
406 class qm2rcc(Task.Task):
407         """
408         Transform *.qm* files into *.rc* files
409         """
410         color = 'BLUE'
411         after = 'ts2qm'
412
413         def run(self):
414                 """Create a qrc file including the inputs"""
415                 txt = '\n'.join(['<file>%s</file>' % k.path_from(self.outputs[0].parent) for k in self.inputs])
416                 code = '<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>' % txt
417                 self.outputs[0].write(code)
418
419 def configure(self):
420         """
421         Besides the configuration options, the environment variable QT4_ROOT may be used
422         to give the location of the qt4 libraries (absolute path).
423
424         The detection will use the program *pkg-config* through :py:func:`waflib.Tools.config_c.check_cfg`
425         """
426         self.find_qt4_binaries()
427         self.set_qt4_libs_to_check()
428         self.set_qt4_defines()
429         self.find_qt4_libraries()
430         self.add_qt4_rpath()
431         self.simplify_qt4_libs()
432
433 @conf
434 def find_qt4_binaries(self):
435         env = self.env
436         opt = Options.options
437
438         qtdir = getattr(opt, 'qtdir', '')
439         qtbin = getattr(opt, 'qtbin', '')
440
441         paths = []
442
443         if qtdir:
444                 qtbin = os.path.join(qtdir, 'bin')
445
446         # the qt directory has been given from QT4_ROOT - deduce the qt binary path
447         if not qtdir:
448                 qtdir = os.environ.get('QT4_ROOT', '')
449                 qtbin = os.environ.get('QT4_BIN', None) or os.path.join(qtdir, 'bin')
450
451         if qtbin:
452                 paths = [qtbin]
453
454         # no qtdir, look in the path and in /usr/local/Trolltech
455         if not qtdir:
456                 paths = os.environ.get('PATH', '').split(os.pathsep)
457                 paths.append('/usr/share/qt4/bin/')
458                 try:
459                         lst = Utils.listdir('/usr/local/Trolltech/')
460                 except OSError:
461                         pass
462                 else:
463                         if lst:
464                                 lst.sort()
465                                 lst.reverse()
466
467                                 # keep the highest version
468                                 qtdir = '/usr/local/Trolltech/%s/' % lst[0]
469                                 qtbin = os.path.join(qtdir, 'bin')
470                                 paths.append(qtbin)
471
472         # at the end, try to find qmake in the paths given
473         # keep the one with the highest version
474         cand = None
475         prev_ver = ['4', '0', '0']
476         for qmk in ('qmake-qt4', 'qmake4', 'qmake'):
477                 try:
478                         qmake = self.find_program(qmk, path_list=paths)
479                 except self.errors.ConfigurationError:
480                         pass
481                 else:
482                         try:
483                                 version = self.cmd_and_log(qmake + ['-query', 'QT_VERSION']).strip()
484                         except self.errors.WafError:
485                                 pass
486                         else:
487                                 if version:
488                                         new_ver = version.split('.')
489                                         if new_ver > prev_ver:
490                                                 cand = qmake
491                                                 prev_ver = new_ver
492         if cand:
493                 self.env.QMAKE = cand
494         else:
495                 self.fatal('Could not find qmake for qt4')
496
497         qtbin = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_BINS']).strip() + os.sep
498
499         def find_bin(lst, var):
500                 if var in env:
501                         return
502                 for f in lst:
503                         try:
504                                 ret = self.find_program(f, path_list=paths)
505                         except self.errors.ConfigurationError:
506                                 pass
507                         else:
508                                 env[var]=ret
509                                 break
510
511         find_bin(['uic-qt3', 'uic3'], 'QT_UIC3')
512         find_bin(['uic-qt4', 'uic'], 'QT_UIC')
513         if not env.QT_UIC:
514                 self.fatal('cannot find the uic compiler for qt4')
515
516         self.start_msg('Checking for uic version')
517         uicver = self.cmd_and_log(env.QT_UIC + ["-version"], output=Context.BOTH)
518         uicver = ''.join(uicver).strip()
519         uicver = uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt', '')
520         self.end_msg(uicver)
521         if uicver.find(' 3.') != -1:
522                 self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
523
524         find_bin(['moc-qt4', 'moc'], 'QT_MOC')
525         find_bin(['rcc-qt4', 'rcc'], 'QT_RCC')
526         find_bin(['lrelease-qt4', 'lrelease'], 'QT_LRELEASE')
527         find_bin(['lupdate-qt4', 'lupdate'], 'QT_LUPDATE')
528
529         env['UIC3_ST']= '%s -o %s'
530         env['UIC_ST'] = '%s -o %s'
531         env['MOC_ST'] = '-o'
532         env['ui_PATTERN'] = 'ui_%s.h'
533         env['QT_LRELEASE_FLAGS'] = ['-silent']
534         env.MOCCPPPATH_ST = '-I%s'
535         env.MOCDEFINES_ST = '-D%s'
536
537 @conf
538 def find_qt4_libraries(self):
539         qtlibs = getattr(Options.options, 'qtlibs', None) or os.environ.get("QT4_LIBDIR", None)
540         if not qtlibs:
541                 try:
542                         qtlibs = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_LIBS']).strip()
543                 except Errors.WafError:
544                         qtdir = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_PREFIX']).strip() + os.sep
545                         qtlibs = os.path.join(qtdir, 'lib')
546         self.msg('Found the Qt4 libraries in', qtlibs)
547
548         qtincludes =  os.environ.get("QT4_INCLUDES", None) or self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_HEADERS']).strip()
549         env = self.env
550         if not 'PKG_CONFIG_PATH' in os.environ:
551                 os.environ['PKG_CONFIG_PATH'] = '%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib' % (qtlibs, qtlibs)
552
553         try:
554                 if os.environ.get("QT4_XCOMPILE", None):
555                         raise self.errors.ConfigurationError()
556                 self.check_cfg(atleast_pkgconfig_version='0.1')
557         except self.errors.ConfigurationError:
558                 for i in self.qt4_vars:
559                         uselib = i.upper()
560                         if Utils.unversioned_sys_platform() == "darwin":
561                                 # Since at least qt 4.7.3 each library locates in separate directory
562                                 frameworkName = i + ".framework"
563                                 qtDynamicLib = os.path.join(qtlibs, frameworkName, i)
564                                 if os.path.exists(qtDynamicLib):
565                                         env.append_unique('FRAMEWORK_' + uselib, i)
566                                         self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN')
567                                 else:
568                                         self.msg('Checking for %s' % i, False, 'YELLOW')
569                                 env.append_unique('INCLUDES_' + uselib, os.path.join(qtlibs, frameworkName, 'Headers'))
570                         elif env.DEST_OS != "win32":
571                                 qtDynamicLib = os.path.join(qtlibs, "lib" + i + ".so")
572                                 qtStaticLib = os.path.join(qtlibs, "lib" + i + ".a")
573                                 if os.path.exists(qtDynamicLib):
574                                         env.append_unique('LIB_' + uselib, i)
575                                         self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN')
576                                 elif os.path.exists(qtStaticLib):
577                                         env.append_unique('LIB_' + uselib, i)
578                                         self.msg('Checking for %s' % i, qtStaticLib, 'GREEN')
579                                 else:
580                                         self.msg('Checking for %s' % i, False, 'YELLOW')
581
582                                 env.append_unique('LIBPATH_' + uselib, qtlibs)
583                                 env.append_unique('INCLUDES_' + uselib, qtincludes)
584                                 env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i))
585                         else:
586                                 # Release library names are like QtCore4
587                                 for k in ("lib%s.a", "lib%s4.a", "%s.lib", "%s4.lib"):
588                                         lib = os.path.join(qtlibs, k % i)
589                                         if os.path.exists(lib):
590                                                 env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')])
591                                                 self.msg('Checking for %s' % i, lib, 'GREEN')
592                                                 break
593                                 else:
594                                         self.msg('Checking for %s' % i, False, 'YELLOW')
595
596                                 env.append_unique('LIBPATH_' + uselib, qtlibs)
597                                 env.append_unique('INCLUDES_' + uselib, qtincludes)
598                                 env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i))
599
600                                 # Debug library names are like QtCore4d
601                                 uselib = i.upper() + "_debug"
602                                 for k in ("lib%sd.a", "lib%sd4.a", "%sd.lib", "%sd4.lib"):
603                                         lib = os.path.join(qtlibs, k % i)
604                                         if os.path.exists(lib):
605                                                 env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')])
606                                                 self.msg('Checking for %s' % i, lib, 'GREEN')
607                                                 break
608                                 else:
609                                         self.msg('Checking for %s' % i, False, 'YELLOW')
610
611                                 env.append_unique('LIBPATH_' + uselib, qtlibs)
612                                 env.append_unique('INCLUDES_' + uselib, qtincludes)
613                                 env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i))
614         else:
615                 for i in self.qt4_vars_debug + self.qt4_vars:
616                         self.check_cfg(package=i, args='--cflags --libs', mandatory=False)
617
618 @conf
619 def simplify_qt4_libs(self):
620         # the libpaths make really long command-lines
621         # remove the qtcore ones from qtgui, etc
622         env = self.env
623         def process_lib(vars_, coreval):
624                 for d in vars_:
625                         var = d.upper()
626                         if var == 'QTCORE':
627                                 continue
628
629                         value = env['LIBPATH_'+var]
630                         if value:
631                                 core = env[coreval]
632                                 accu = []
633                                 for lib in value:
634                                         if lib in core:
635                                                 continue
636                                         accu.append(lib)
637                                 env['LIBPATH_'+var] = accu
638
639         process_lib(self.qt4_vars,       'LIBPATH_QTCORE')
640         process_lib(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG')
641
642 @conf
643 def add_qt4_rpath(self):
644         # rpath if wanted
645         env = self.env
646         if getattr(Options.options, 'want_rpath', False):
647                 def process_rpath(vars_, coreval):
648                         for d in vars_:
649                                 var = d.upper()
650                                 value = env['LIBPATH_'+var]
651                                 if value:
652                                         core = env[coreval]
653                                         accu = []
654                                         for lib in value:
655                                                 if var != 'QTCORE':
656                                                         if lib in core:
657                                                                 continue
658                                                 accu.append('-Wl,--rpath='+lib)
659                                         env['RPATH_'+var] = accu
660                 process_rpath(self.qt4_vars,       'LIBPATH_QTCORE')
661                 process_rpath(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG')
662
663 @conf
664 def set_qt4_libs_to_check(self):
665         if not hasattr(self, 'qt4_vars'):
666                 self.qt4_vars = QT4_LIBS
667         self.qt4_vars = Utils.to_list(self.qt4_vars)
668         if not hasattr(self, 'qt4_vars_debug'):
669                 self.qt4_vars_debug = [a + '_debug' for a in self.qt4_vars]
670         self.qt4_vars_debug = Utils.to_list(self.qt4_vars_debug)
671
672 @conf
673 def set_qt4_defines(self):
674         if sys.platform != 'win32':
675                 return
676         for x in self.qt4_vars:
677                 y = x[2:].upper()
678                 self.env.append_unique('DEFINES_%s' % x.upper(), 'QT_%s_LIB' % y)
679                 self.env.append_unique('DEFINES_%s_DEBUG' % x.upper(), 'QT_%s_LIB' % y)
680
681 def options(opt):
682         """
683         Command-line options
684         """
685         opt.add_option('--want-rpath', action='store_true', default=False, dest='want_rpath', help='enable the rpath for qt libraries')
686
687         opt.add_option('--header-ext',
688                 type='string',
689                 default='',
690                 help='header extension for moc files',
691                 dest='qt_header_ext')
692
693         for i in 'qtdir qtbin qtlibs'.split():
694                 opt.add_option('--'+i, type='string', default='', dest=i)
695
696         opt.add_option('--translate', action="store_true", help="collect translation strings", dest="trans_qt4", default=False)