From 3ff613bb770b0cd1256fea4e785263a1e76332f7 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Tue, 13 Sep 2005 10:16:37 +0000 Subject: [PATCH] Make it possible to run moc on CPP sources. [SVN r30942] --- src/tools/qt.jam | 46 +++++++++++++++++++++++++++++++ src/tools/qt4.jam | 69 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 110 insertions(+), 5 deletions(-) diff --git a/src/tools/qt.jam b/src/tools/qt.jam index be998d886..33587cc91 100644 --- a/src/tools/qt.jam +++ b/src/tools/qt.jam @@ -47,6 +47,11 @@ rule init ( prefix ? ) .prefix = $(prefix) ; generators.register-standard qt.moc : H : CPP(moc_%) : qt ; + # Note: the OBJ target type here is fake, take a look + # at qt4.jam/uic-h-generator for explanations that + # apply in this case as well. + generators.register [ new moc-h-generator + qt.moc.cpp : MOCCABLE_CPP : OBJ : qt ] ; # The UI type is defined in types/qt.jam, # and UIC_H is only used in qt.jam, but not in qt4.jam, so @@ -115,6 +120,39 @@ rule init ( prefix ? ) } } +class moc-h-generator : generator +{ + rule __init__ ( * : * ) + { + generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; + } + + rule run ( project name ? : property-set : sources * ) + { + if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_CPP + { + name = [ $(sources[0]).name ] ; + name = $(name:B) ; + + local a = [ new action $(sources[1]) : qt.moc.cpp : + $(property-set) ] ; + + local target = [ + new file-target $(name) : MOC : $(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. @@ -132,6 +170,14 @@ actions moc $(.prefix)/bin/moc -f $(>) -o $(<) } +# When moccing .cpp files, we don't need -f, otherwise generated +# code will include .cpp and we'll get duplicated symbols. +actions moc.cpp +{ + $(.prefix)/bin/moc $(>) -o $(<) +} + + space = " " ; # Sometimes it's required to make 'plugins' available during diff --git a/src/tools/qt4.jam b/src/tools/qt4.jam index b8f3c51eb..29025a50a 100644 --- a/src/tools/qt4.jam +++ b/src/tools/qt4.jam @@ -18,8 +18,21 @@ # # Example: # -# exe myapp : myapp.cpp myapp.h myapp.ui myapp.qrc /qt4//QtGui /qt4//QtNetwork ; +# exe myapp : myapp.cpp myapp.h myapp.ui myapp.qrc +# /qt4//QtGui /qt4//QtNetwork ; # +# It's also possible to run moc on cpp sources: +# +# import cast ; +# +# exe myapp : myapp.cpp [ cast _ moccable-cpp : myapp.cpp ] /qt4//QtGui ; +# +# When moccing source file myapp.cpp you need to include "myapp.moc" from +# myapp.cpp. When moccing .h files, the output of moc will be automatically +# compiled and linked in, you don't need any includes. +# +# This is consistent with Qt guidelines: +# http://doc.trolltech.com/4.0/moc.html import modules ; import feature ; @@ -65,10 +78,15 @@ rule init ( prefix ? ) # Generates cpp files from header files using "moc" tool generators.register-standard qt4.moc : H : CPP(moc_%) ; - - # Generates header file from .ui file - # The generator class is defined below the 'init' function. + + # The OBJ result type is a fake, 'H' will be really produces. + # See comments on the generator calss, defined below + # the 'init' function. generators.register [ new uic-h-generator qt4.uic-h : UI : OBJ ] ; + + # The OBJ result type is a fake here too. + generators.register [ new moc-h-generator + qt.moc.cpp : MOCCABLE_CPP : OBJ ] ; # Generates .cpp file from qrc file generators.register-standard qt4.rcc : QRC : CPP(qrc_%) ; @@ -183,7 +201,7 @@ class uic-h-generator : generator name = $(name:B) ; } - local a = [ new action $(source) : qt4.uic-h : + local a = [ new action $(sources[1]) : qt4.uic-h : $(property-set) ] ; local target = [ @@ -200,6 +218,39 @@ class uic-h-generator : generator } } +class moc-h-generator : generator +{ + rule __init__ ( * : * ) + { + generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; + } + + rule run ( project name ? : property-set : sources * ) + { + if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_CPP + { + name = [ $(sources[0]).name ] ; + name = $(name:B) ; + + local a = [ new action $(sources[1]) : qt4.moc.cpp : + $(property-set) ] ; + + local target = [ + new file-target $(name) : MOC : $(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. @@ -220,6 +271,14 @@ actions moc $(.prefix)/bin/moc -I$(INCLUDES) -I$(DEFINES) -f $(>) -o $(<) } +# When moccing .cpp files, we don't need -f, otherwise generated +# code will include .cpp and we'll get duplicated symbols. +actions moc.cpp +{ + $(.prefix)/bin/moc -I$(INCLUDES) -I$(DEFINES) $(>) -o $(<) +} + + # Generates source files from resource files actions rcc {