|
Boost-Build : |
From: Vladimir Prus (ghost_at_[hidden])
Date: 2002-09-27 04:44:55
I've posted on this before, but some more comments are needed. To remind
what the problem is: file "a.cpp" include "a_parser.h" which is
generated by some other action. If we do nothing, "a.cpp" may be
compiled before "a_parser.h" is generated, and the comppilation will
fail. We could try to make a special "first" target which will be
updated first and depend on generated headers, but this is kludge: you'd
have to add many dependencies to "first" and I'm not sure this will
really work in all cases.
Let me explain what I find the right semantic, first without any
subvariants. We have a target "a.cpp" which includes "a_parser.h",
we have to search through all include directories, checking:
1. If there's such file there, or
2. If there's a target of the same name, bound to that dir via
LOCATE_TARGET.
Jam allows to do 1 via SEARCH variable, but that's not enough.
Why can't we do simpler: first check if there's target of the same name?
I.e. including of "a_parser.h" will already pick generated "a_parser.h",
regardless of search paths? Hmm... just because there's no reason to
assume that. For example, one can have an action which generated some
"dummy" header, for system which don't have the native one. Naturally,
we don't want to depend on that generated headers.
To implement proposed semantic we'd need a new builtin. We can do this
in Jam code, but really, this belongs to core. Using GLOB and jam code
would just duplicate existing binding functionality and be inefficient.
New builtin will accept a name of new target and a list of directories.
It will perform the search as explained above and return either the name
of exising target that it found, or create a new target with that name
that it was passed. So, we'd write something like
INCLUDES $(<) : [ SEARCH_FOR_TARGET $(>) : $(SEARCH_PATH) ] ;
What shall we do when using subvariants. For user, subvariants must be
more or less transparent. If without subvariant a header was generated
to a certain directory, everything must work. Suppose that file a.cpp
belongs to a dependency graph of main target a. Include paths are
"/usr/include" "/home/t" "."
We start by finding all places where headers that are part of a's
dependency graph are generated. We insert those places to the include
paths, immediately after ".". For example, we might end with:
"/usr/include" "/home/t" "." "build"
As a result:
1. File "a.cpp" will be correctly compiled. Note that it's already
necessary to adjust paths to ensure this. We'll have to add
target paths for all generated headers, because determining the
exact set of additional include path for each source -- i.e the
set of headers that it uses --- will be hard.
2. With the proposed SEARCH_FOR_TARGET rule, dependency on generated
header will work magically --- it would find the "a_parser.h"
target bound via LOCATE_TARGET to "build" and we'll call INCLUDE
on that found target, instread of creating a completely unrelated
one.
Comments?
- 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