|
Boost-Build : |
From: Thomas Witt (witt_at_[hidden])
Date: 2003-01-16 11:03:25
Felix E. Klee wrote:
> On Thursday 16 January 2003 08:57 am, Vladimir Prus wrote:
>
>>>>1. User explicitly specifies the list of headers that must be processes
>>>>with MOC, for example
>>>>
>>>>qt.exe hello : hello.cpp hello.h ;
To me this is actually the correct way to handle things. These headers
are sources with respect to the build system.
Furthermore mangement of this header list isn't as much of a problem as
it may sound. Adding a header that does not contain a Q_OBJECT macro is
harmless moc will just issue a warning and that's it.
>>>
>>>IMHO, this solution has two disadvantages. Firstly, the user has to
>>>change the header file list almost each time he adds or removes a
>>>Q_OBJECT. Secondly, you need to introduce extra target types (qt.exe,
>>>qt.lib, etc.).
>>
>>Speaking of the first, is this a problem in practice. As I understand it,
>>qmake requires to declare all mocced header, too.
>
>
> qmake requires you to list all headers in the current project.
No it doesn't.
Upon invocation
> it scans these headers and adds moc targets to the Makefile for all headers
> requiring it.
Yes, it requires you to list all headers that eventually need moc'ing
>
>
>>To avoid it, one can:
>>
>>1. Use "moc_h" extension for headers and then do
>>
>>qt.exe hello : hello.cpp [ GLOB . : *.moc_h ] ;
>>
>>However, your observation still applies: it's another way to explicitly
>>specify the list of mocced files. If you add Q_OBJECT, you need to change
>>that list. And in this requires file renaming. (How do you do that
>>in CVS, for one thing?)
>
>
> Yes, but I like really this solution because, as David pointed out, these
> header files are actually non-C++ source files.
Again, as Vladimir already said, they are ordinary C++ source files.
> I recommend ".qpp" as an
> extension which fits nicely with the common ".hpp" and ".cpp" extensions.
>
I strongly object against the idea of using a special extension for
these files it is just unneeded.
>
>>2. Auto-detect the list of mocced headers. But this is non-trivial. (And
>>non-explicit).
Autodetecting headers that need to be moced is just overkill. IIUC this
is also doomed to fail. You may well include library headers that
contain Q_OBJECT macros that you don't want to moc.
FWIW here is what I use with v1.
No special targets no magic. Just a few lines of code.
# dwa 6/4/01 - added for boost
# thw 11/30/01 - added Qt handling
# Build a generated source file from input-target, and build whatever
that file generates.
# Return a list of all object target names ultimately generated by
recursively
# building the products of input-target.
rule gen-source # source => object-file-names
{
local suffix = .c ;
if $(<:S) in .lpp .ypp .ui .h
{
suffix = .cpp ;
}
local immediate-target ; # = $(<:D=:S=$(suffix):G=$(SOURCE_GRIST)) ;
switch $(<:S)
{
case .l* :
immediate-target = $(<:D=:S=$(suffix):G=$(SOURCE_GRIST) ;
Lex $(immediate-target) : $(<) ;
SEARCH on $(<) = $(SEARCH_SOURCE) ;
case .y* :
immediate-target = $(<:D=:S=$(suffix):G=$(SOURCE_GRIST) ;
Yacc $(immediate-target) : $(<) ;
SEARCH on $(<) = $(SEARCH_SOURCE) ;
case .h* :
immediate-target = [ moc $(<) ] ;
SEARCH on $(<) = $(SEARCH_SOURCE) ;
case .ui :
immediate-target = [ uic $(<) ] ;
SEARCH on $(<) = $(SEARCH_SOURCE) ;
}
return [ Objects $(immediate-target) ] ;
}
UIC_HEADER_PATH ?= ..$(SLASH)include$(SLASH)ui ;
UIC_CPP_PATH ?= cpp ;
UIC_NAME_EXTENSION ?= _uic ;
MOC_NAME_EXTENSION ?= _moc ;
MOC_CPP_PATH ?= cpp ;
#
# Long paths cause no end of problems on Windows.
# We better not use LOCATE_TARGET there.
#
if $(NT)
{
QT_LOCATE_VAR ?= LOCATE_SOURCE ;
}
else
{
QT_LOCATE_VAR ?= LOCATE_TARGET ;
}
rule uic
{
local immediate-targets ;
for local uic-file in $(<)
{
local base-name =
$(uic-file:D=:B=$(uic-file:B)_uic:G=$(SOURCE_GRIST)) ;
local header-file = $(base-name:S=.h) ;
local cpp-file = $(base-name:S=.cpp) ;
local cpp-path = [ FDirName $($(QT_LOCATE_VAR)) $(UIC_CPP_PATH) ] ;
local header-path = [ FDirName $(RELATIVE_SUBDIR)
$(UIC_HEADER_PATH) ] ;
local rooted-cpp-path = [ tokens-to-simple-path [ split-path [
FDirName [ PWD ] $(cpp-path) ] ] ] ;
local rooted-header-path = [ tokens-to-simple-path [ split-path [
FDirName [ PWD ] $(header-path) ] ] ] ;
local cpp-to-header-path = [ FRelPath [ split-path
$(rooted-cpp-path) ] : [ split-path $(rooted-header-path) ] ] ;
DEPENDS $(header-file) : $(uic-file) ;
MakeLocate $(header-file) : $(header-path) ;
SEARCH on $(header-file) = $(header-path) ;
Clean clean : $(header-file) ;
DEPENDS $(cpp-file) : $(uic-file) ;
INCLUDES $(cpp-file) : $(header-file) ;
MakeLocate $(cpp-file) : $(cpp-path) ;
SEARCH on $(cpp-file) = $(cpp-path) ;
Clean clean : $(cpp-file) ;
UIC_HEADER_FILE on $(cpp-file) =
$(cpp-to-header-path)/$(header-file:G=:D=) ;
uic-create-header-action $(header-file) : $(uic-file) ;
uic-create-cpp-action $(cpp-file) : $(uic-file) ;
immediate-targets += $(header-file) $(cpp-file) ;
}
return $(immediate-targets) ;
}
actions uic-create-cpp-action
{
$(QTDIR)$(SLASH)bin$(SLASH)uic -o $(<) -impl $(UIC_HEADER_FILE) $(>)
}
actions updated uic-create-header-action
{
$(QTDIR)$(SLASH)bin$(SLASH)uic -o $(<) $(>)
}
rule moc
{
local immediate-targets ;
for local header in $(<)
{
local moc-file =
$(header:D=:B=$(header:B)$(MOC_NAME_EXTENSION):S=.cpp:G=$(SOURCE_GRIST)) ;
#echo $(moc-file) ;
DEPENDS $(moc-file) : $(header) ;
MakeLocate $(moc-file) : $($(QT_LOCATE_VAR))$(SLASH)$(MOC_CPP_PATH) ;
SEARCH on $(moc-file) = $($(QT_LOCATE_VAR))$(SLASH)$(MOC_CPP_PATH) ;
Clean clean : $(moc-file) ;
moc-action $(moc-file) : $(header) ;
immediate-targets += $(moc-file) ;
}
return $(immediate-targets) ;
}
actions together moc-action
{
$(QTDIR)$(SLASH)bin$(SLASH)moc -o $(<) $(>)
}
#
# Add Qt generating extension
SOURCE_GENERATING_EXTENSIONS += .h .ui ;
Thomas
-- Dipl.-Ing. Thomas Witt Institut fuer Verkehrswesen, Eisenbahnbau und -betrieb, Universitaet Hannover voice: +49(0) 511 762 - 4273, fax: +49(0) 511 762-3001 http://www.ive.uni-hannover.de
Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk