1# Copyright 2002-2006 Vladimir Prus
2# Copyright 2005 Alo Sarv
3# Copyright 2005-2009 Juergen Hunold
4#
5# Distributed under the Boost Software License, Version 1.0. (See
6# accompanying file LICENSE_1_0.txt or copy at
7# http://www.boost.org/LICENSE_1_0.txt)
8
9# Qt4 library support module
10#
11# The module attempts to auto-detect QT installation location from QTDIR
12# environment variable; failing that, installation location can be passed as
13# argument:
14#
15# toolset.using qt4 : /usr/local/Trolltech/Qt-4.0.0 ;
16#
17# The module supports code generation from .ui and .qrc files, as well as
18# running the moc preprocessor on headers. Note that you must list all your
19# moc-able headers in sources.
20#
21# Example:
22#
23#     exe myapp : myapp.cpp myapp.h myapp.ui myapp.qrc
24#                 /qt4//QtGui /qt4//QtNetwork ;
25#
26# It's also possible to run moc on cpp sources:
27#
28#   import cast ;
29#
30#   exe myapp : myapp.cpp [ cast _ moccable-cpp : myapp.cpp ] /qt4//QtGui ;
31#
32# When moccing source file myapp.cpp you need to include "myapp.moc" from
33# myapp.cpp. When moccing .h files, the output of moc will be automatically
34# compiled and linked in, you don't need any includes.
35#
36# This is consistent with Qt guidelines:
37# http://qt-project.org/doc/qt-4.8/moc.html
38#
39# The .qrc processing utility supports various command line option (see
40# http://qt-project.org/doc/qt-4.8/rcc.html for a complete list). The
41# module provides default arguments for the "output file" and
42# "initialization function name" options. Other options can be set through
43# the <rccflags> build property. E.g. if you wish the compression settings
44# to be more aggressive than the defaults, you can apply them too all .qrc
45# files like this:
46#
47#   project my-qt-project :
48#               requirements
49#               <rccflags>"-compress 9 -threshold 10"
50#           ;
51#
52# Of course, this property can also be specified on individual targets.
53
54
55import modules ;
56import feature ;
57import errors ;
58import type ;
59import "class" : new ;
60import generators ;
61import project ;
62import toolset : flags ;
63import os ;
64import virtual-target ;
65import scanner ;
66
67# Qt3Support control feature
68#
69# Qt4 configure defaults to build Qt4 libraries with Qt3Support.
70# The autodetection is missing, so we default to disable Qt3Support.
71# This prevents the user from inadvertedly using a deprecated API.
72#
73# The Qt3Support library can be activated by adding
74# "<qt3support>on" to requirements
75#
76# Use "<qt3support>on:<define>QT3_SUPPORT_WARNINGS"
77# to get warnings about deprecated Qt3 support funtions and classes.
78# Files ported by the "qt3to4" conversion tool contain _tons_ of
79# warnings, so this define is not set as default.
80#
81# Todo: Detect Qt3Support from Qt's configure data.
82#       Or add more auto-configuration (like python).
83feature.feature qt3support : off on : propagated link-incompatible ;
84
85# The Qt version used for requirements
86# Valid are <qt>4.4 or <qt>4.5.0
87# Auto-detection via qmake sets '<qt>major.minor.patch'
88feature.feature qt : : propagated ;
89
90# Extra flags for rcc
91feature.feature rccflags : : free ;
92
93project.initialize $(__name__) ;
94project qt ;
95
96# Save the project so that we tolerate 'import + using' combo.
97.project = [ project.current ] ;
98
99# Helper utils for easy debug output
100if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
101{
102    .debug-configuration = TRUE ;
103}
104
105local rule debug-message ( message * )
106{
107    if $(.debug-configuration) = TRUE
108    {
109        ECHO notice: [qt4-cfg] $(message) ;
110    }
111}
112
113# Capture qmake output line by line
114local rule read-output ( content )
115{
116    local lines ;
117    local nl = "
118" ;
119    local << = "([^$(nl)]*)[$(nl)](.*)" ;
120    local line+ = [ MATCH "$(<<)" : "$(content)" ] ;
121    while $(line+)
122    {
123        lines += $(line+[1]) ;
124        line+ = [ MATCH "$(<<)" : "$(line+[2])" ] ;
125    }
126    return $(lines) ;
127}
128
129# Capture Qt version from qmake
130local rule check-version ( bin_prefix )
131{
132    full-cmd = $(bin_prefix)"/qmake -v" ;
133    debug-message Running '$(full-cmd)' ;
134    local output = [ SHELL $(full-cmd) ] ;
135    for line in [ read-output $(output) ]
136    {
137        # Parse the output to get all the results.
138        if [ MATCH "QMake" : $(line) ]
139        {
140            # Skip first line of output
141        }
142        else
143        {
144            temp = [ MATCH "([0-9]*)\\.([0-9]*)\\.([0-9]*)" : $(line) ] ;
145        }
146    }
147    return $(temp) ;
148}
149
150# Validate the version string and extract the major/minor part we care about.
151#
152local rule split-version ( version )
153{
154    local major-minor = [ MATCH ^([0-9]+)\.([0-9]+)(.*)$ : $(version) : 1 2 3 ] ;
155    if ! $(major-minor[2]) || $(major-minor[3])
156    {
157        ECHO "Warning: 'using qt' expects a two part (major, minor) version number; got" $(version) instead ;
158
159        # Add a zero to account for the missing digit if necessary.
160        major-minor += 0 ;
161    }
162
163    return $(major-minor[1]) $(major-minor[2]) ;
164}
165
166# Initialize the QT support module.
167# Parameters:
168# - 'prefix'    parameter tells where Qt is installed.
169# - 'full_bin'  optional full path to Qt binaries (qmake,moc,uic,rcc)
170# - 'full_inc'  optional full path to Qt top-level include directory
171# - 'full_lib'  optional full path to Qt library directory
172# - 'version'   optional version of Qt, else autodetected via 'qmake -v'
173# - 'condition' optional requirements
174rule init ( prefix : full_bin ? : full_inc ? : full_lib ? : version ? : condition * )
175{
176    project.push-current $(.project) ;
177
178    debug-message "==== Configuring Qt ... ====" ;
179    for local v in version cmd-or-prefix includes libraries condition
180    {
181        if $($(v))
182        {
183            debug-message "  user-specified "$(v): '$($(v))' ;
184        }
185    }
186
187    # Needed as default value
188    .prefix = $(prefix) ;
189
190    # pre-build paths to detect reinitializations changes
191    local inc_prefix lib_prefix bin_prefix ;
192    if $(full_inc)
193    {
194        inc_prefix = $(full_inc) ;
195    }
196    else
197    {
198        inc_prefix = $(prefix)/include ;
199    }
200    if $(full_lib)
201    {
202        lib_prefix = $(full_lib) ;
203    }
204    else
205    {
206        lib_prefix = $(prefix)/lib ;
207    }
208    if $(full_bin)
209    {
210        bin_prefix = $(full_bin) ;
211    }
212    else
213    {
214        bin_prefix = $(prefix)/bin ;
215    }
216
217    # Globally needed variables
218    .incprefix = $(inc_prefix) ;
219    .libprefix = $(lib_prefix) ;
220    .binprefix = $(bin_prefix) ;
221
222    if ! $(.initialized)
223    {
224        # Make sure this is initialised only once
225        .initialized = true ;
226
227        # Generates cpp files from header files using "moc" tool
228        generators.register-standard qt4.moc : H : CPP(moc_%) : <allow>qt4 ;
229
230        # The OBJ result type is a fake, 'H' will be really produced. See
231        # comments on the generator class, defined below the 'init' function.
232        generators.register [ new uic-generator qt4.uic : UI : OBJ :
233            <allow>qt4  ] ;
234
235        # The OBJ result type is a fake here too.
236        generators.register [ new moc-h-generator
237            qt4.moc.inc : MOCCABLE_CPP : OBJ : <allow>qt4 ] ;
238
239        generators.register [ new moc-inc-generator
240            qt4.moc.inc : MOCCABLE_H : OBJ : <allow>qt4 ] ;
241
242        # Generates .cpp files from .qrc files.
243        generators.register-standard qt4.rcc : QRC : CPP(qrc_%) : <allow>qt4 ;
244
245        # dependency scanner for wrapped files.
246        type.set-scanner QRC : qrc-scanner ;
247
248        # Save value of first occuring prefix
249        .PREFIX = $(prefix) ;
250    }
251
252    if $(version)
253    {
254        major-minor = [ split-version $(version) ] ;
255        version = $(major-minor:J=.) ;
256    }
257    else
258    {
259        version = [ check-version $(bin_prefix) ] ;
260        if $(version)
261        {
262            version = $(version:J=.) ;
263        }
264        debug-message Detected version '$(version)' ;
265    }
266
267    local target-requirements = $(condition) ;
268
269    # Add the version, if any, to the target requirements.
270    if $(version)
271    {
272        if ! $(version) in [ feature.values qt ]
273        {
274            feature.extend qt : $(version) ;
275        }
276        target-requirements += <qt>$(version:E=default) ;
277    }
278
279    local target-os = [ feature.get-values target-os : $(condition) ] ;
280    if ! $(target-os)
281    {
282        target-os ?= [ feature.defaults target-os ] ;
283        target-os = $(target-os:G=) ;
284        target-requirements += <target-os>$(target-os) ;
285    }
286
287    # Build exact requirements for the tools
288    local tools-requirements = $(target-requirements:J=/) ;
289
290    debug-message "Details of this Qt configuration:" ;
291    debug-message "  prefix:      " '$(prefix:E=<empty>)' ;
292    debug-message "  binary path: " '$(bin_prefix:E=<empty>)' ;
293    debug-message "  include path:" '$(inc_prefix:E=<empty>)' ;
294    debug-message "  library path:" '$(lib_prefix:E=<empty>)' ;
295    debug-message "  target requirements:" '$(target-requirements)' ;
296    debug-message "  tool requirements:  " '$(tools-requirements)' ;
297
298    # setup the paths for the tools
299    toolset.flags qt4.moc .BINPREFIX $(tools-requirements) : $(bin_prefix) ;
300    toolset.flags qt4.rcc .BINPREFIX $(tools-requirements) : $(bin_prefix) ;
301    toolset.flags qt4.uic .BINPREFIX $(tools-requirements) : $(bin_prefix) ;
302
303    # TODO: 2009-02-12: Better support for directories
304    # Most likely needed are separate getters for: include,libraries,binaries and sources.
305    toolset.flags qt4.directory .PREFIX $(tools-requirements) : $(prefix) ;
306
307    # Test for a buildable Qt.
308    if [ glob $(.prefix)/Jamroot ]
309    {
310       .bjam-qt = true
311
312       # this will declare QtCore (and qtmain on <target-os>windows)
313       add-shared-library QtCore ;
314   }
315   else
316   # Setup common pre-built Qt.
317   # Special setup for QtCore on which everything depends
318   {
319       local link = [ feature.get-values link : $(condition) ] ;
320
321       local usage-requirements =
322           <include>$(.incprefix)
323           <library-path>$(.libprefix)
324           <threading>multi
325           <allow>qt4 ;
326
327       if $(link) in shared
328       {
329           usage-requirements += <dll-path>$(.libprefix) ;
330       }
331
332       local suffix ;
333
334       # Since Qt-4.2, debug versions on unix have to be built
335       # separately and therefore have no suffix.
336       .suffix_version = "" ;
337       .suffix_debug = "" ;
338
339       # Control flag for auto-configuration of the debug libraries.
340       # This setup requires Qt 'configure -debug-and-release'.
341       # Only available on some platforms.
342       # ToDo: 2009-02-12: Maybe throw this away and
343       # require separate setup with <variant>debug as condition.
344       .have_separate_debug = FALSE ;
345
346       # Setup other platforms
347       if $(target-os) in windows cygwin
348       {
349           .have_separate_debug = TRUE ;
350
351           # On NT, the shared libs have "4" suffix, and "d" suffix in debug builds.
352           if $(link) in shared
353           {
354                .suffix_version = "4" ;
355           }
356           .suffix_debug = "d" ;
357
358           # On Windows we must link against the qtmain library
359           lib qtmain
360               : # sources
361               : # requirements
362                  <name>qtmain$(.suffix_debug)
363                  <variant>debug
364                  $(target-requirements)
365               ;
366
367           lib qtmain
368               : # sources
369               : # requirements
370                   <name>qtmain
371                   $(target-requirements)
372               ;
373       }
374       else if $(target-os) = darwin
375       {
376           # On MacOS X, both debug and release libraries are available.
377           .suffix_debug = "_debug" ;
378
379           .have_separate_debug = TRUE ;
380
381           alias qtmain ;
382       }
383       else
384       {
385           alias qtmain : : $(target-requirements) ;
386       }
387
388       lib QtCore : qtmain
389           : # requirements
390             <name>QtCore$(.suffix_version)
391             $(target-requirements)
392           : # default-build
393           : # usage-requirements
394             <define>QT_CORE_LIB
395             <define>QT_NO_DEBUG
396             <include>$(.incprefix)/QtCore
397             $(usage-requirements)
398           ;
399
400       if $(.have_separate_debug) = TRUE
401       {
402           debug-message Configure debug libraries with suffix '$(.suffix_debug)' ;
403
404           lib QtCore : $(main)
405               : # requirements
406                 <name>QtCore$(.suffix_debug)$(.suffix_version)
407                 <variant>debug
408                 $(target-requirements)
409               : # default-build
410               : # usage-requirements
411                 <define>QT_CORE_LIB
412                 <include>$(.incprefix)/QtCore
413                 $(usage-requirements)
414               ;
415        }
416    }
417
418    # Initialising the remaining libraries is canonical
419    # parameters 'module' : 'depends-on' : 'usage-define' : 'requirements' : 'include'
420    # 'include' only for non-canonical include paths.
421    add-shared-library QtGui     : QtCore : QT_GUI_LIB     : $(target-requirements) ;
422    add-shared-library QtNetwork : QtCore : QT_NETWORK_LIB : $(target-requirements) ;
423    add-shared-library QtSql     : QtCore : QT_SQL_LIB     : $(target-requirements) ;
424    add-shared-library QtXml     : QtCore : QT_XML_LIB     : $(target-requirements) ;
425
426    add-shared-library Qt3Support : QtGui QtNetwork QtXml QtSql
427                                  : QT_QT3SUPPORT_LIB QT3_SUPPORT
428                                  : <qt3support>on $(target-requirements) ;
429
430    # Dummy target to enable "<qt3support>off" and
431    # "<library>/qt//Qt3Support" at the same time. This enables quick
432    # switching from one to the other for test/porting purposes.
433    alias Qt3Support : : <qt3support>off $(target-requirements) ;
434
435    # OpenGl Support
436    add-shared-library QtOpenGL : QtGui : QT_OPENGL_LIB : $(target-requirements) ;
437
438    # SVG-Support (Qt 4.1)
439    add-shared-library QtSvg : QtXml QtOpenGL : QT_SVG_LIB : $(target-requirements) ;
440
441    # Test-Support (Qt 4.1)
442    add-shared-library QtTest : QtCore : : $(target-requirements) ;
443
444    # Qt designer library
445    add-shared-library QtDesigner : QtGui QtXml : : $(target-requirements) ;
446    add-shared-library QtDesignerComponents : QtGui QtXml : : $(target-requirements) ;
447
448    # Support for dynamic Widgets (Qt 4.1)
449    add-static-library  QtUiTools : QtGui QtXml : $(target-requirements) ;
450
451    # DBus-Support (Qt 4.2)
452    add-shared-library QtDBus : QtXml : : $(target-requirements) ;
453
454    # Script-Engine (Qt 4.3)
455    add-shared-library QtScript : QtGui QtXml : QT_SCRIPT_LIB : $(target-requirements) ;
456
457    # Tools for the Script-Engine (Qt 4.5)
458    add-shared-library QtScriptTools : QtScript : QT_SCRIPTTOOLS_LIB : $(target-requirements) ;
459
460    # WebKit (Qt 4.4)
461    add-shared-library QtWebKit : QtGui : QT_WEBKIT_LIB : $(target-requirements) ;
462
463    # Phonon Multimedia (Qt 4.4)
464    add-shared-library phonon : QtGui QtXml : QT_PHONON_LIB : $(target-requirements) ;
465
466    # Multimedia engine (Qt 4.6)
467    add-shared-library QtMultimedia : QtGui : QT_MULTIMEDIA_LIB : $(target-requirements) ;
468
469    # XmlPatterns-Engine (Qt 4.4)
470    add-shared-library QtXmlPatterns : QtNetwork : QT_XMLPATTERNS_LIB : $(target-requirements) ;
471
472    # Help-Engine (Qt 4.4)
473    add-shared-library QtHelp    : QtGui QtSql QtXml : : $(target-requirements) ;
474    add-shared-library QtCLucene : QCore QtSql QtXml : : $(target-requirements) ;
475
476    # QML-Engine (Qt 4.7)
477    add-shared-library QtDeclarative : QtGui QtXml : : $(target-requirements) ;
478
479    # AssistantClient Support
480    # Compat library removed in 4.7.0
481    # Pre-4.4 help system, use QtHelp for new programs
482    if $(version) < "4.7"
483    {
484       add-shared-library QtAssistantClient : QtGui : : $(target-requirements) : QtAssistant ;
485    }
486    debug-message "==== Configured Qt-$(version) ====" ;
487
488    project.pop-current ;
489}
490
491rule initialized ( )
492{
493    return $(.initialized) ;
494}
495
496
497
498# This custom generator is needed because in QT4, UI files are translated only
499# into H files, and no C++ files are created. Further, the H files need not be
500# passed via MOC. The header is used only via inclusion. If we define a standard
501# UI -> H generator, Boost.Build will run MOC on H, and then compile the
502# resulting cpp. It will give a warning, since output from moc will be empty.
503#
504# This generator is declared with a UI -> OBJ signature, so it gets invoked when
505# linking generator tries to convert sources to OBJ, but it produces target of
506# type H. This is non-standard, but allowed. That header won't be mocced.
507#
508class uic-generator : generator
509{
510    rule __init__ ( * : * )
511    {
512        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
513    }
514
515    rule run ( project name ? : property-set : sources * )
516    {
517        if ! $(name)
518        {
519            name = [ $(sources[0]).name ] ;
520            name = $(name:B) ;
521        }
522
523        local a = [ new action $(sources[1]) : qt4.uic : $(property-set) ] ;
524
525        # The 'ui_' prefix is to match qmake's default behavior.
526        local target = [ new file-target ui_$(name) : H : $(project) : $(a) ] ;
527
528        local r = [ virtual-target.register $(target) ] ;
529
530        # Since this generator will return a H target, the linking generator
531        # won't use it at all, and won't set any dependency on it. However, we
532        # need the target to be seen by bjam, so that dependency from sources to
533        # this generated header is detected -- if jam does not know about this
534        # target, it won't do anything.
535        DEPENDS all : [ $(r).actualize ] ;
536
537        return $(r) ;
538    }
539}
540
541
542class moc-h-generator : generator
543{
544    rule __init__ ( * : * )
545    {
546        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
547    }
548
549    rule run ( project name ? : property-set : sources * )
550    {
551        if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_CPP
552        {
553            name = [ $(sources[0]).name ] ;
554            name = $(name:B) ;
555
556            local a = [ new action $(sources[1]) : qt4.moc.inc :
557                $(property-set) ] ;
558
559            local target = [ new file-target $(name) : MOC : $(project) : $(a)
560                ] ;
561
562            local r = [ virtual-target.register $(target) ] ;
563
564            # Since this generator will return a H target, the linking generator
565            # won't use it at all, and won't set any dependency on it. However,
566            # we need the target to be seen by bjam, so that dependency from
567            # sources to this generated header is detected -- if jam does not
568            # know about this target, it won't do anything.
569            DEPENDS all : [ $(r).actualize ] ;
570
571            return $(r) ;
572        }
573    }
574}
575
576
577class moc-inc-generator : generator
578{
579    rule __init__ ( * : * )
580    {
581        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
582    }
583
584    rule run ( project name ? : property-set : sources * )
585    {
586        if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_H
587        {
588            name = [ $(sources[0]).name ] ;
589            name = $(name:B) ;
590
591            local a = [ new action $(sources[1]) : qt4.moc.inc :
592                $(property-set) ] ;
593
594            local target = [ new file-target moc_$(name) : CPP : $(project) :
595                $(a) ] ;
596
597            # Since this generator will return a H target, the linking generator
598            # won't use it at all, and won't set any dependency on it. However,
599            # we need the target to be seen by bjam, so that dependency from
600            # sources to this generated header is detected -- if jam does not
601            # know about this target, it won't do anything.
602            DEPENDS all : [ $(target).actualize ] ;
603
604            return [ virtual-target.register $(target) ] ;
605        }
606    }
607}
608
609
610# Query the installation directory. This is needed in at least two scenarios.
611# First, when re-using sources from the Qt-Tree. Second, to "install" custom Qt
612# plugins to the Qt-Tree.
613#
614rule directory
615{
616    return $(.PREFIX) ;
617}
618
619# Add a shared Qt library.
620rule add-shared-library ( lib-name : depends-on * : usage-defines * : requirements * :  include ? )
621{
622     add-library $(lib-name) : $(.suffix_version) : $(depends-on) : $(usage-defines) : $(requirements) : $(include) ;
623}
624
625# Add a static Qt library.
626rule add-static-library ( lib-name : depends-on * : usage-defines * : requirements * : include ? )
627{
628     add-library $(lib-name) : : $(depends-on) : $(usage-defines) : $(requirements) : $(include) ;
629}
630
631# Add a Qt library.
632# Static libs are unversioned, whereas shared libs have the major number as suffix.
633# Creates both release and debug versions on platforms where both are enabled by Qt configure.
634# Flags:
635# - lib-name Qt library Name
636# - version  Qt major number used as shared library suffix (QtCore4.so)
637# - depends-on other Qt libraries
638# - usage-defines those are set by qmake, so set them when using this library
639# - requirements addional requirements
640# - include non-canonical include path. The canonical path is $(.incprefix)/$(lib-name).
641rule add-library ( lib-name : version ? : depends-on * : usage-defines * : requirements * : include ? )
642{
643    if $(.bjam-qt)
644    {
645        # Import Qt module
646        # Eveything will be setup there
647        alias $(lib-name)
648           : $(.prefix)//$(lib-name)
649           :
650           :
651           : <allow>qt4 ;
652    }
653    else
654    {
655        local real_include ;
656        real_include ?= $(include) ;
657        real_include ?= $(lib-name) ;
658
659        lib $(lib-name)
660           : # sources
661             $(depends-on)
662           : # requirements
663             <name>$(lib-name)$(version)
664             $(requirements)
665           : # default-build
666           : # usage-requirements
667             <define>$(usage-defines)
668             <include>$(.incprefix)/$(real_include)
669           ;
670
671        if $(.have_separate_debug) = TRUE
672        {
673            lib $(lib-name)
674               : # sources
675                 $(depends-on)
676               : # requirements
677                 <name>$(lib-name)$(.suffix_debug)$(version)
678                 $(requirements)
679                 <variant>debug
680               : # default-build
681               : # usage-requirements
682                 <define>$(usage-defines)
683                 <include>$(.incprefix)/$(real_include)
684               ;
685        }
686    }
687
688    # Make library explicit so that a simple <use>qt4 will not bring in everything.
689    # And some components like QtDBus/Phonon may not be available on all platforms.
690    explicit $(lib-name) ;
691}
692
693# Use $(.BINPREFIX[-1]) for the paths as several tools-requirements can match.
694# The exact match is the last one.
695
696# Get <include> and <defines> from current toolset.
697flags qt4.moc INCLUDES <include> ;
698flags qt4.moc DEFINES <define> ;
699
700# need a newline for expansion of DEFINES and INCLUDES in the response file.
701.nl  = "
702" ;
703
704# Processes headers to create Qt MetaObject information. Qt4-moc has its
705# c++-parser, so pass INCLUDES and DEFINES.
706# We use response file with one INCLUDE/DEFINE per line
707#
708actions moc
709{
710    $(.BINPREFIX[-1])/moc -f $(>) -o $(<) @"@($(<).rsp:E=-D$(DEFINES)$(.nl) -I$(INCLUDES:T)$(.nl))"
711}
712
713# When moccing files for include only, we don't need -f, otherwise the generated
714# code will include the .cpp and we'll get duplicated symbols.
715#
716actions moc.inc
717{
718    $(.BINPREFIX[-1])/moc $(>) -o $(<) @"@($(<).rsp:E=-D$(DEFINES)$(.nl) -I$(INCLUDES:T)$(.nl))"
719}
720
721
722# Get extra options for RCC
723flags qt4.rcc RCC_OPTIONS <rccflags> ;
724
725# Generates source files from resource files.
726#
727actions rcc
728{
729    $(.BINPREFIX[-1])/rcc $(>) -name $(>:B) $(RCC_OPTIONS) -o $(<)
730}
731
732
733# Generates user-interface source from .ui files.
734#
735actions uic
736{
737    $(.BINPREFIX[-1])/uic $(>) -o $(<)
738}
739
740
741# Scanner for .qrc files. Look for the CDATA section of the <file> tag. Ignore
742# the "alias" attribute. See http://doc.trolltech.com/qt/resources.html for
743# detailed documentation of the Qt Resource System.
744#
745class qrc-scanner : common-scanner
746{
747    rule pattern ( )
748    {
749        return "<file.*>(.*)</file>" ;
750    }
751}
752
753
754# Wrapped files are "included".
755scanner.register qrc-scanner : include ;
756