Boost logo

Boost-Build :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2003-10-27 02:40:49


Hi Christopher,

> > 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/...').

There's some difficulty. The conflict only exists when and object is used to
two different main targets. To detect if this is the case, and adjust target
paths, one need to find target paths of all targets, which is not trivially
doable in current code.

Now, when each target is assigned a path name, we check if there's another
target with the same path name. If so, it's a conflict, and an error is
reported. But it would be really hard to go back to previous target and
change its path.

> 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

Yea, that was my original proposal. I was thinking on implementation details
and realized that adding main target name would require artificial trick.

Consider:

exe a : a.cpp ;
exe b : a.cpp ;

Current V2 detects that both a.o have the same properties, so a.o is shared
between main targets. The only way to prevent this would be to add some
property, which is different for "a" and "b" main target. For example, "a"
can have <main-target>a property and "b" can have "<main-target>b" property.

Workable but still seems unclear for me.

> 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).

Could you explain what's the problem with CC in this case?

> 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).

You know, I can use your example to prove completely different thing. If
object files are secondary, then I can avoid storing them in filesystem at
all. For example, I can store them in database, using project/name/properties
as a key. And in that case, sharing of object files would be a natural
solution.

At the same time, since objects are not stored in filesystem, storing of "exe"
and "lib" target in "bin/gcc/debug" would be natural, too.

Ok... well, I think I should stop thinking as V2 user and as V2 developer
propose something. That something is:

1. Use the scheme I've proposed.
2. If that causes issues in practice, as opposed to theory, change the scheme
to add <main-target> properties for main targets. This will automatically
place objects from different main targets into different directories.

How does that sound?

- Volodya

 


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