Boost logo

Boost-Build :

From: Christopher Currie (Christopher_at_[hidden])
Date: 2003-10-24 11:24:25


Vladimir Prus wrote:
> However, I think it's acceptable to ask the user for help in this case. V2
> already has a code to detect situation when two different targets are
> assigned the same filename. We can decide that main target name is not
> encoded in path. In the case above, user will get an error telling that two
> target conflict. The user then can manually resolve conflict by writing
>
> exe a : a.cpp : <define>A <location-prefix>a ;
> exe b : a.cpp : <define>B ;
>
> And targets will be generated to "bin/a/gcc/debug/a.o" and "bin/gcc/debug/
> a.o".

I'm not sure that I like this proposal, if possibly for no better reason
than programmer laziness. IMO, if the build system is intelligent enough
to detect that there is potential conflict, then it ought to "do the
right" thing, with out any prompting from the user. Granted the above is
a simple example, but it seems obvious that if 'a' and 'b' need
different versions of a.o, then they need to be built in different
directories (i.e. 'bin/a/...' and 'bin/b/...').

Personally, I think that ALL declared targets (exes, libs, precompiled
headers, or what have you; but not implied or intermediate targets)
should always be built in their own named subdirectory. So ...

lib liba : a.cpp ;
exe b : b.cpp liba ;
exe c : c.cpp liba ;

... would produce (on Unix):

bin/liba/.../a.o
bin/liba/.../liba.so
bin/b/.../b.o
bin/b/.../b
bin/c/.../c.o
bin/c/.../c

None of these targets 'share' any intermediate objects , but each exists
in it's own subdirectory. I believe this is more straightforward and
less prone to error. This may be easier to implement, as well. Some
compilers, such as the much bemoaned Sun C++ compiler, actually operate
more reliably when this is the case, although this is a secondary
concern (except for we unfortunates without an alternative).

Look at it from this perspective: if you're specifiying the cpp file as
a dependency of an executable, you in effect say that you depend on the
source code, not on some intermediate target. If you want to depend on
an intermediate target, you do as you suggest in an earlier message, and
declare it:

obj a : a.cpp ;
exe b : b.cpp d.cpp a ;
exe c : c.cpp d.cpp a ;

... which would produce:

bin/a/.../a.o
bin/b/.../b.o
bin/b/.../d.o
bin/b/.../b
bin/c/.../c.o
bin/c/.../d.o
bin/c/.../c

The results reflect the intent: the exe depends on the source, not the
object. The fact that the object exists is secondary; the results would
be equally correct if d.cpp were passed to the link line, assuming you
don't use a standalone linker (although it would be less efficient in
the long run, of course).

My $0.02, with interest.

Christopher

 


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