From 9a39b7ab142aefa58e1984ac44175d7fceb4e6ad Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Thu, 1 Sep 2005 10:22:52 +0000 Subject: [PATCH] For Qt4, don't run moc on headers produces by uic, since they never contains moccable classes. The trick here is that if we have: exe a : a.cpp b.ui ; Then we should produce b.h target that is not used by any action -- it's only indirectly used by include in a.cpp. So, we declared .ui -> .obj generator, so that it's invoked when building exe, but make it return header, not .obj. Second, the path of b.h should be added to include paths. But it was not done, because b.h is not used anywhere and so is not included in 'subvariant' for this target -- which object is used to compute extra incude path. * build/virtual-target.jam (register): Add result to .recent-targets (recent-targets, clear-recent-targets): New functions. * build/targets.jam (basic-target.generate): Create subvariant from 'virtual-target.recent-targets' not just directly returned targets. * tools/qt4.jam: Declare custom generator for ui->h conversion. [SVN r30770] --- src/build/targets.jam | 5 +++- src/build/virtual-target.jam | 20 +++++++++++++ src/tools/qt4.jam | 56 ++++++++++++++++++++++++++++++++---- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/build/targets.jam b/src/build/targets.jam index 612a5ad1a..032acb0e8 100644 --- a/src/build/targets.jam +++ b/src/build/targets.jam @@ -1130,8 +1130,11 @@ class basic-target : abstract-target local gur = $(result[1]) ; result = $(result[2-]) ; - local s = [ create-subvariant $(result) : $(property-set) : $(source-targets) + local s = [ create-subvariant + [ virtual-target.recent-targets ] + : $(property-set) : $(source-targets) : $(rproperties) : $(usage-requirements) ] ; + virtual-target.clear-recent-targets ; local ur = [ compute-usage-requirements $(s) ] ; ur = [ $(ur).add $(gur) ] ; diff --git a/src/build/virtual-target.jam b/src/build/virtual-target.jam index 4ea2d7277..b0b9833bf 100644 --- a/src/build/virtual-target.jam +++ b/src/build/virtual-target.jam @@ -830,10 +830,30 @@ rule register ( target ) .cache.$(signature) += $(target) ; result = $(target) ; } + + .recent-targets += $(result) ; return $(result) ; } + +# Each target returned by 'register' is added to a list of +# 'recent-target', returned by this function. So, this allows +# us to find all targets created when building a given main +# target, even if the target +rule recent-targets ( ) +{ + return $(.recent-targets) ; +} + +rule clear-recent-targets ( ) +{ + .recent-targets = ; +} + + + + rule register-actual-name ( actual-name : virtual-target ) { if $(.actual.$(actual-name)) diff --git a/src/tools/qt4.jam b/src/tools/qt4.jam index 99e0628e3..72fd3becf 100644 --- a/src/tools/qt4.jam +++ b/src/tools/qt4.jam @@ -30,6 +30,7 @@ import generators ; import project ; import toolset : flags ; import os ; +import virtual-target ; project.initialize $(__name__) ; project qt4 ; @@ -67,12 +68,13 @@ rule init ( prefix ? ) # Generates header file from .ui file type.register UI : ui ; - generators.register-standard qt4.uic-h : UI : H ; + # The generator class is defined after 'init'. + generators.register [ new uic-h-generator qt4.uic-h : UI : OBJ ] ; # Generates .cpp file from qrc file type.register QRC : qrc ; generators.register-standard qt4.rcc : QRC : CPP(qrc_%) ; - + local usage-requirements = $(.prefix)/include $(.prefix)/lib @@ -156,19 +158,63 @@ rule init ( prefix ? ) } } +# This custom generator is needed because it QT4, UI files are translated +# only in H files, and no C++ files are created. Further, the H files +# need not be passed via MOC. The header is used only via inclusion. +# If we define standard UI -> H generator, Boost.Build will run +# MOC on H, and the compile resulting cpp. It will give a warning, since +# output from moc will be empty. +# +# This generator is declared with UI -> OBJ signature, so it's +# invoked when linking generator tries to convert sources to OBJ, +# but it produces target of type H. This is non-standard, but allowed. +# That header won't be mocced. +# +class uic-h-generator : generator +{ + rule __init__ ( * : * ) + { + generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; + } + + rule run ( project name ? : property-set : sources * ) + { + if ! $(name) + { + name = [ $(sources[0]).name ] ; + name = $(name:B) ; + } + + local a = [ new action $(source) : qt4.uic-h : + $(property-set) ] ; + + local target = [ + new file-target $(name) : H : $(project) : $(a) ] ; + + # Since this generator will return H target, the linking generator + # won't use it at all, and won't set any dependency on it. + # However, we need to target to be seen by bjam, so that dependency + # from sources to this generated header is detected -- if jam does + # not know about this target, it won't do anything. + DEPENDS all : [ $(target).actualize ] ; + + return [ virtual-target.register $(target) ] ; + } +} + # Query the installation directory # This is needed in at least two scenarios # First, when re-using sources from the Qt-Tree. # Second, to "install" custom Qt plugins to the Qt-Tree. rule directory { - return $(.prefix) ; + return $(.prefix) ; } # Processes headers to create Qt MetaObject information actions moc { - $(.prefix)/bin/moc -I$(.prefix)/include -I$(.prefix)/include/QtCore -f $(>) -o $(<) + $(.prefix)/bin/moc -I$(.prefix)/include -I$(.prefix)/include/QtCore -f $(>) -o $(<) } # Generates source files from resource files @@ -180,5 +226,5 @@ actions rcc # Generates user-interface source from .ui files actions uic-h { - $(.prefix)/bin/uic $(>) -o $(<) + $(.prefix)/bin/uic $(>) -o $(<) }