Boost logo

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