Boost logo

Boost-Build :

From: Christopher Currie (Christopher_at_[hidden])
Date: 2003-10-31 16:16:04

I'm trying to build a toolset that implements the following scenario:

exe xmlapp : main.cpp [ xml-cpp Person.cpp Name.cpp : schema.xml ] ;

I'm writing for a tool called XML ObjectLink. This tool creates a set of
C++ source files to implement parsing and generating elements of an
XML schema. Roughly, one source and one header are created for each
top-level element and named type in the schema.

The trouble of course, is that there is no way to deduce the name of
these source file from the name of the schema file. So I needed to write
a rule that took the expected names as arguments, putting some burden
upon the user to give the correct generated names.

I've been pretty successful so far, I've almost got it working. Here is
my current implementation:

# objectlink.jam

import type ;
import "class" : new ;
import generators ;
import targets ;

type.register XSD : xsd ;

rule xsd-cpp ( targets + : source : requirements * : default-build *
: usage-requirements * )
local project = [ CALLER_MODULE ] ;

targets = $(targets:B) ;

for local name in $(targets)
targets.create-typed-target CPP
: $(project) : $(name) : $(source) : $(requirements)
: $(default-build) : $(usage-requirements) ;

return $(targets) ;
IMPORT $(__name__) : xsd-cpp : : xsd-cpp ;

generators.register-standard objectlink.schema-compile : XSD : CPP ;

actions schema-compile
xsd2cpp -outdir "$(<:D)" "$(>)" ;

So far, so good. The only problem is that the system now runs the
schema-compile action once for each generated CPP file, even though the
tool will create them all at the same time.

Obviously I needed a way to specify that the generator was going to
create multiple targets, and so I tried adding:

generators.register [
new generator objectlink.schema-compile
: XSD : CPP($(targets).cpp)
] ;

into my rule, just before the return, and removing the standard
generator below. This broke the build, because somewhere my CPP targets
are getting defined twice. My build now gives the errors below.

I figure that the generator is defining new virtual-targets with the
same file-target name, because my generator output is fixed. So what I
probably need to do is not create the typed-targets, and return the
virtual-targets from the generator. Trouble is, I can't figure out how
to get those target id's out of the generator.

Am I on the right track? Or is there another way to solve this dilemma?


$ bjam
/home/ccurrie/src/boost/tools/build/v2/build/virtual-target.jam:758: in
virtual-target.register-actual-name from module virtual-target
error: Duplicate name of actual target: <./sun/debug>Person.cpp
previous virtual target {
objectlink%objectlink.schema-compile-Person.CPP { test.XSD } }
another virtual target { objectlink%objectlink.schema-compile-Person.CPP
{ test.XSD } }
/home/ccurrie/src/boost/tools/build/v2/build/virtual-target.jam:176: in
actualize-no-scanner from module object(file-target)@3
/home/ccurrie/src/boost/tools/build/v2/build/virtual-target.jam:110: in
object(file-target)@3.actualize from module object(file-target)@3
/home/ccurrie/src/boost/tools/build/v2/build/virtual-target.jam:568: in
object(action)@1.actualize from module object(action)@1
/home/ccurrie/src/boost/tools/build/v2/build/virtual-target.jam:279: in
actualize-action from module object(file-target)@2
/home/ccurrie/src/boost/tools/build/v2/build/virtual-target.jam:184: in
actualize-no-scanner from module object(file-target)@2
/home/ccurrie/src/boost/tools/build/v2/build/virtual-target.jam:110: in
object(file-target)@2.actualize from module object(file-target)@2
/home/ccurrie/src/boost/tools/build/v2/build-system.jam:168: in load
from module build-system
/home/ccurrie/src/boost/tools/build/v2/kernel/modules.jam:259: in import
from module modules
/home/ccurrie/src/boost/tools/build/v2/kernel/bootstrap.jam:120: in
boost-build from module
/home/ccurrie/src/xml/boost-build.jam:1: in module scope from module


Boost-Build list run by bdawes at, david.abrahams at, gregod at, cpdaniel at, john at