|
Boost-Build : |
From: Craig Bachelor (craig.bachelor_at_[hidden])
Date: 2007-10-21 14:15:28
Hi,
I've just started playing with Boost.Build and so far I love it. I am
however, having quite a bit of trouble extending it :(
What I'm trying to do is write a tool for the ZeroC "Slice" interface
language and its compilers. If you haven't heard of slice, it's
functionally similar to IDL and midl.exe, e.g. a compiler, slice2cpp,
generates c++ code from an interface definition, foo.ice.
I have it working basically, but have two more requirements of it
which I can't figure out how to implement.
Background:
The slice language uses C preprocessor style #includes.
e.g.
A.ice
-------
#include <blah/B.ice>
interface X
{
...
};
Unlike the C preprocessor though, this does not insert B.ice verbatim
into A.ice before compiling. Instead, it produces something like this:
A.cpp
---------
#include <blah/B.cpp>
class X
{
...
};
This means that to use A.ice in my project, I also need to compile
B.ice. i.e. there is an implicit dependency in A.ice that I need to
make explicit.
Requirement 1:
I want BB to automagically compile any slice source files #included by
another slice source file. To do this I need to get the list of
includes from the scanner and create new source targets out of these.
I know this must be possible, but I can't quite get it.
Requirement 2:
In order to put both A.cpp and B.cpp into the build output directory,
it is necessary to pass directory paths to slice2cpp. To do this I
again need the list of includes from the scanner, but this time I need
them in the action. This surely is easy if you know what you are doing
:)
Here is a working slice.jam with some comments, that can't yet handle
the above requirements.
slice.jam
-------------
import type ;
import generators ;
import feature ;
import "class" : new ;
import scanner ;
type.register SLICE : ice ;
class slice-scanner : scanner
{
import path property-set regex scanner type virtual-target ;
rule __init__ ( includes * )
{
scanner.__init__ ;
self.includes = $(includes) ;
}
rule pattern ( )
{
return "^[ \t]*#[ \t]*include[ ]*(<(.*)>|\"(.*)\")" ;
}
rule process ( target : matches * : binding )
{
local included = [ regex.transform $(matches) : "\"(.*)\"" : 1 ] ;
local g = [ on $(target) return $(HDRGRIST) ] ;
local b = [ NORMALIZE_PATH $(binding:D) ] ;
local g2 = $(g)"#"$(b) ;
included = $(included:G=$(g2)) ;
#this seems to add the dependency ok to the tree, but
#I can't get these new dependencies to build
#I've seen virtual-target.register but I don't have access to properties
#and project names to do that here.
INCLUDES $(target) : $(included) ;
scanner.propagate $(__name__) : $(matches) : $(target) ;
}
}
scanner.register slice-scanner : include ;
type.set-scanner SLICE : slice-scanner ;
class slice-generator : generator
{
import "class" : new ;
rule __init__ ( * : * )
{
generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) :
$(7) : $(8) : $(9) ;
}
rule run ( project name ? : property-set : sources * )
{
#could I register new virtual targets here? The problem is I
can't seem to
#be able to get the list of includes that the scanner built
from anywhere
return [ generator.run $(project) $(name) : $(property-set) :
$(sources) ] ;
}
rule generated-targets ( sources + : property-set : project name ? )
{
return [ generator.generated-targets $(sources) :
$(property-set) : $(project) $(name) ] ;
}
}
generators.register [ new slice-generator slice.slice2cpp : SLICE : CPP HPP ] ;
#rule slice2cpp ( targets + : sources + : properties * )
#{
#}
#I need the the list of includes here in this action!
actions slice2cpp
{
slice2cpp --checksum --header-ext hpp --output-dir $(1[1]:D) $(2)
}
Thanks in advance,
Craig
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