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