build:wafsamba: Remove unnecessary parameters to cmd_and_log
[bbaumbach/samba-autobuild/.git] / third_party / waf / waflib / extras / 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 = sorted(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.append(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
247 class XMLHandler(ContentHandler):
248         """
249         Parser for *.qrc* files
250         """
251         def __init__(self):
252                 self.buf = []
253                 self.files = []
254         def startElement(self, name, attrs):
255                 if name == 'file':
256                         self.buf = []
257         def endElement(self, name):
258                 if name == 'file':
259                         self.files.append(str(''.join(self.buf)))
260         def characters(self, cars):
261                 self.buf.append(cars)
262
263 @extension(*EXT_RCC)
264 def create_rcc_task(self, node):
265         "Create rcc and cxx tasks for *.qrc* files"
266         rcnode = node.change_ext('_rc.cpp')
267         self.create_task('rcc', node, rcnode)
268         cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o'))
269         try:
270                 self.compiled_tasks.append(cpptask)
271         except AttributeError:
272                 self.compiled_tasks = [cpptask]
273         return cpptask
274
275 @extension(*EXT_UI)
276 def create_uic_task(self, node):
277         "hook for uic tasks"
278         uictask = self.create_task('ui4', node)
279         uictask.outputs = [self.path.find_or_declare(self.env['ui_PATTERN'] % node.name[:-3])]
280
281 @extension('.ts')
282 def add_lang(self, node):
283         """add all the .ts file into self.lang"""
284         self.lang = self.to_list(getattr(self, 'lang', [])) + [node]
285
286 @feature('qt4')
287 @after_method('apply_link')
288 def apply_qt4(self):
289         """
290         Add MOC_FLAGS which may be necessary for moc::
291
292                 def build(bld):
293                         bld.program(features='qt4', source='main.cpp', target='app', use='QTCORE')
294
295         The additional parameters are:
296
297         :param lang: list of translation files (\*.ts) to process
298         :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension
299         :param update: whether to process the C++ files to update the \*.ts files (use **waf --translate**)
300         :type update: bool
301         :param langname: if given, transform the \*.ts files into a .qrc files to include in the binary file
302         :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension
303         """
304         if getattr(self, 'lang', None):
305                 qmtasks = []
306                 for x in self.to_list(self.lang):
307                         if isinstance(x, str):
308                                 x = self.path.find_resource(x + '.ts')
309                         qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.qm')))
310
311                 if getattr(self, 'update', None) and Options.options.trans_qt4:
312                         cxxnodes = [a.inputs[0] for a in self.compiled_tasks] + [
313                                 a.inputs[0] for a in self.tasks if getattr(a, 'inputs', None) and a.inputs[0].name.endswith('.ui')]
314                         for x in qmtasks:
315                                 self.create_task('trans_update', cxxnodes, x.inputs)
316
317                 if getattr(self, 'langname', None):
318                         qmnodes = [x.outputs[0] for x in qmtasks]
319                         rcnode = self.langname
320                         if isinstance(rcnode, str):
321                                 rcnode = self.path.find_or_declare(rcnode + '.qrc')
322                         t = self.create_task('qm2rcc', qmnodes, rcnode)
323                         k = create_rcc_task(self, t.outputs[0])
324                         self.link_task.inputs.append(k.outputs[0])
325
326         lst = []
327         for flag in self.to_list(self.env['CXXFLAGS']):
328                 if len(flag) < 2:
329                         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:
377                                 nodes.append(nd)
378                         else:
379                                 names.append(x)
380                 return (nodes, names)
381
382 class moc(Task.Task):
383         """
384         Create *.moc* files
385         """
386         color   = 'BLUE'
387         run_str = '${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
388         def keyword(self):
389                 return "Creating"
390         def __str__(self):
391                 return self.outputs[0].path_from(self.generator.bld.launch_node())
392
393 class ui4(Task.Task):
394         """
395         Process *.ui* files
396         """
397         color   = 'BLUE'
398         run_str = '${QT_UIC} ${SRC} -o ${TGT}'
399         ext_out = ['.h']
400
401 class ts2qm(Task.Task):
402         """
403         Create *.qm* files from *.ts* files
404         """
405         color   = 'BLUE'
406         run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
407
408 class qm2rcc(Task.Task):
409         """
410         Transform *.qm* files into *.rc* files
411         """
412         color = 'BLUE'
413         after = 'ts2qm'
414
415         def run(self):
416                 """Create a qrc file including the inputs"""
417                 txt = '\n'.join(['<file>%s</file>' % k.path_from(self.outputs[0].parent) for k in self.inputs])
418                 code = '<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>' % txt
419                 self.outputs[0].write(code)
420
421 def configure(self):
422         """
423         Besides the configuration options, the environment variable QT4_ROOT may be used
424         to give the location of the qt4 libraries (absolute path).
425
426         The detection will use the program *pkg-config* through :py:func:`waflib.Tools.config_c.check_cfg`
427         """
428         self.find_qt4_binaries()
429         self.set_qt4_libs_to_check()
430         self.set_qt4_defines()
431         self.find_qt4_libraries()
432         self.add_qt4_rpath()
433         self.simplify_qt4_libs()
434
435 @conf
436 def find_qt4_binaries(self):
437         env = self.env
438         opt = Options.options
439
440         qtdir = getattr(opt, 'qtdir', '')
441         qtbin = getattr(opt, 'qtbin', '')
442
443         paths = []
444
445         if qtdir:
446                 qtbin = os.path.join(qtdir, 'bin')
447
448         # the qt directory has been given from QT4_ROOT - deduce the qt binary path
449         if not qtdir:
450                 qtdir = os.environ.get('QT4_ROOT', '')
451                 qtbin = os.environ.get('QT4_BIN') or os.path.join(qtdir, 'bin')
452
453         if qtbin:
454                 paths = [qtbin]
455
456         # no qtdir, look in the path and in /usr/local/Trolltech
457         if not qtdir:
458                 paths = os.environ.get('PATH', '').split(os.pathsep)
459                 paths.append('/usr/share/qt4/bin/')
460                 try:
461                         lst = Utils.listdir('/usr/local/Trolltech/')
462                 except OSError:
463                         pass
464                 else:
465                         if lst:
466                                 lst.sort()
467                                 lst.reverse()
468
469                                 # keep the highest version
470                                 qtdir = '/usr/local/Trolltech/%s/' % lst[0]
471                                 qtbin = os.path.join(qtdir, 'bin')
472                                 paths.append(qtbin)
473
474         # at the end, try to find qmake in the paths given
475         # keep the one with the highest version
476         cand = None
477         prev_ver = ['4', '0', '0']
478         for qmk in ('qmake-qt4', 'qmake4', 'qmake'):
479                 try:
480                         qmake = self.find_program(qmk, path_list=paths)
481                 except self.errors.ConfigurationError:
482                         pass
483                 else:
484                         try:
485                                 version = self.cmd_and_log(qmake + ['-query', 'QT_VERSION']).strip()
486                         except self.errors.WafError:
487                                 pass
488                         else:
489                                 if version:
490                                         new_ver = version.split('.')
491                                         if new_ver > prev_ver:
492                                                 cand = qmake
493                                                 prev_ver = new_ver
494         if cand:
495                 self.env.QMAKE = cand
496         else:
497                 self.fatal('Could not find qmake for qt4')
498
499         qtbin = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_BINS']).strip() + os.sep
500
501         def find_bin(lst, var):
502                 if var in env:
503                         return
504                 for f in lst:
505                         try:
506                                 ret = self.find_program(f, path_list=paths)
507                         except self.errors.ConfigurationError:
508                                 pass
509                         else:
510                                 env[var]=ret
511                                 break
512
513         find_bin(['uic-qt3', 'uic3'], 'QT_UIC3')
514         find_bin(['uic-qt4', 'uic'], 'QT_UIC')
515         if not env.QT_UIC:
516                 self.fatal('cannot find the uic compiler for qt4')
517
518         self.start_msg('Checking for uic version')
519         uicver = self.cmd_and_log(env.QT_UIC + ["-version"], output=Context.BOTH)
520         uicver = ''.join(uicver).strip()
521         uicver = uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt', '')
522         self.end_msg(uicver)
523         if uicver.find(' 3.') != -1:
524                 self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
525
526         find_bin(['moc-qt4', 'moc'], 'QT_MOC')
527         find_bin(['rcc-qt4', 'rcc'], 'QT_RCC')
528         find_bin(['lrelease-qt4', 'lrelease'], 'QT_LRELEASE')
529         find_bin(['lupdate-qt4', 'lupdate'], 'QT_LUPDATE')
530
531         env['UIC3_ST']= '%s -o %s'
532         env['UIC_ST'] = '%s -o %s'
533         env['MOC_ST'] = '-o'
534         env['ui_PATTERN'] = 'ui_%s.h'
535         env['QT_LRELEASE_FLAGS'] = ['-silent']
536         env.MOCCPPPATH_ST = '-I%s'
537         env.MOCDEFINES_ST = '-D%s'
538
539 @conf
540 def find_qt4_libraries(self):
541         qtlibs = getattr(Options.options, 'qtlibs', None) or os.environ.get("QT4_LIBDIR")
542         if not qtlibs:
543                 try:
544                         qtlibs = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_LIBS']).strip()
545                 except Errors.WafError:
546                         qtdir = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_PREFIX']).strip() + os.sep
547                         qtlibs = os.path.join(qtdir, 'lib')
548         self.msg('Found the Qt4 libraries in', qtlibs)
549
550         qtincludes =  os.environ.get("QT4_INCLUDES") or self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_HEADERS']).strip()
551         env = self.env
552         if not 'PKG_CONFIG_PATH' in os.environ:
553                 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)
554
555         try:
556                 if os.environ.get("QT4_XCOMPILE"):
557                         raise self.errors.ConfigurationError()
558                 self.check_cfg(atleast_pkgconfig_version='0.1')
559         except self.errors.ConfigurationError:
560                 for i in self.qt4_vars:
561                         uselib = i.upper()
562                         if Utils.unversioned_sys_platform() == "darwin":
563                                 # Since at least qt 4.7.3 each library locates in separate directory
564                                 frameworkName = i + ".framework"
565                                 qtDynamicLib = os.path.join(qtlibs, frameworkName, i)
566                                 if os.path.exists(qtDynamicLib):
567                                         env.append_unique('FRAMEWORK_' + uselib, i)
568                                         self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN')
569                                 else:
570                                         self.msg('Checking for %s' % i, False, 'YELLOW')
571                                 env.append_unique('INCLUDES_' + uselib, os.path.join(qtlibs, frameworkName, 'Headers'))
572                         elif env.DEST_OS != "win32":
573                                 qtDynamicLib = os.path.join(qtlibs, "lib" + i + ".so")
574                                 qtStaticLib = os.path.join(qtlibs, "lib" + i + ".a")
575                                 if os.path.exists(qtDynamicLib):
576                                         env.append_unique('LIB_' + uselib, i)
577                                         self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN')
578                                 elif os.path.exists(qtStaticLib):
579                                         env.append_unique('LIB_' + uselib, i)
580                                         self.msg('Checking for %s' % i, qtStaticLib, 'GREEN')
581                                 else:
582                                         self.msg('Checking for %s' % i, False, 'YELLOW')
583
584                                 env.append_unique('LIBPATH_' + uselib, qtlibs)
585                                 env.append_unique('INCLUDES_' + uselib, qtincludes)
586                                 env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i))
587                         else:
588                                 # Release library names are like QtCore4
589                                 for k in ("lib%s.a", "lib%s4.a", "%s.lib", "%s4.lib"):
590                                         lib = os.path.join(qtlibs, k % i)
591                                         if os.path.exists(lib):
592                                                 env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')])
593                                                 self.msg('Checking for %s' % i, lib, 'GREEN')
594                                                 break
595                                 else:
596                                         self.msg('Checking for %s' % i, False, 'YELLOW')
597
598                                 env.append_unique('LIBPATH_' + uselib, qtlibs)
599                                 env.append_unique('INCLUDES_' + uselib, qtincludes)
600                                 env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i))
601
602                                 # Debug library names are like QtCore4d
603                                 uselib = i.upper() + "_debug"
604                                 for k in ("lib%sd.a", "lib%sd4.a", "%sd.lib", "%sd4.lib"):
605                                         lib = os.path.join(qtlibs, k % i)
606                                         if os.path.exists(lib):
607                                                 env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')])
608                                                 self.msg('Checking for %s' % i, lib, 'GREEN')
609                                                 break
610                                 else:
611                                         self.msg('Checking for %s' % i, False, 'YELLOW')
612
613                                 env.append_unique('LIBPATH_' + uselib, qtlibs)
614                                 env.append_unique('INCLUDES_' + uselib, qtincludes)
615                                 env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i))
616         else:
617                 for i in self.qt4_vars_debug + self.qt4_vars:
618                         self.check_cfg(package=i, args='--cflags --libs', mandatory=False)
619
620 @conf
621 def simplify_qt4_libs(self):
622         # the libpaths make really long command-lines
623         # remove the qtcore ones from qtgui, etc
624         env = self.env
625         def process_lib(vars_, coreval):
626                 for d in vars_:
627                         var = d.upper()
628                         if var == 'QTCORE':
629                                 continue
630
631                         value = env['LIBPATH_'+var]
632                         if value:
633                                 core = env[coreval]
634                                 accu = []
635                                 for lib in value:
636                                         if lib in core:
637                                                 continue
638                                         accu.append(lib)
639                                 env['LIBPATH_'+var] = accu
640
641         process_lib(self.qt4_vars,       'LIBPATH_QTCORE')
642         process_lib(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG')
643
644 @conf
645 def add_qt4_rpath(self):
646         # rpath if wanted
647         env = self.env
648         if getattr(Options.options, 'want_rpath', False):
649                 def process_rpath(vars_, coreval):
650                         for d in vars_:
651                                 var = d.upper()
652                                 value = env['LIBPATH_'+var]
653                                 if value:
654                                         core = env[coreval]
655                                         accu = []
656                                         for lib in value:
657                                                 if var != 'QTCORE':
658                                                         if lib in core:
659                                                                 continue
660                                                 accu.append('-Wl,--rpath='+lib)
661                                         env['RPATH_'+var] = accu
662                 process_rpath(self.qt4_vars,       'LIBPATH_QTCORE')
663                 process_rpath(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG')
664
665 @conf
666 def set_qt4_libs_to_check(self):
667         if not hasattr(self, 'qt4_vars'):
668                 self.qt4_vars = QT4_LIBS
669         self.qt4_vars = Utils.to_list(self.qt4_vars)
670         if not hasattr(self, 'qt4_vars_debug'):
671                 self.qt4_vars_debug = [a + '_debug' for a in self.qt4_vars]
672         self.qt4_vars_debug = Utils.to_list(self.qt4_vars_debug)
673
674 @conf
675 def set_qt4_defines(self):
676         if sys.platform != 'win32':
677                 return
678         for x in self.qt4_vars:
679                 y = x[2:].upper()
680                 self.env.append_unique('DEFINES_%s' % x.upper(), 'QT_%s_LIB' % y)
681                 self.env.append_unique('DEFINES_%s_DEBUG' % x.upper(), 'QT_%s_LIB' % y)
682
683 def options(opt):
684         """
685         Command-line options
686         """
687         opt.add_option('--want-rpath', action='store_true', default=False, dest='want_rpath', help='enable the rpath for qt libraries')
688
689         opt.add_option('--header-ext',
690                 type='string',
691                 default='',
692                 help='header extension for moc files',
693                 dest='qt_header_ext')
694
695         for i in 'qtdir qtbin qtlibs'.split():
696                 opt.add_option('--'+i, type='string', default='', dest=i)
697
698         opt.add_option('--translate', action="store_true", help="collect translation strings", dest="trans_qt4", default=False)
699