diff --git a/doc/architecture.html b/doc/architecture.html index bf00cae21..e6d2d2ebc 100644 --- a/doc/architecture.html +++ b/doc/architecture.html @@ -21,12 +21,12 @@ br.clear { clear: left } div.alert { color: red } table { align: center; border: thin; } - + + - build request, build request expansion and directly requested targets + - conditional properties + -->
The solution in Boost.Jam is to perform additional dependency scans after targets are updated. This break separation between build stages in @@ -189,53 +261,43 @@ B --/ C-includes ---> D - Both A and B have dependency on C and C-includes (the latter is not - shown). Say during building we've tried to create A, then tried to create - C and successfully created C. The B node wasn't seen yet. The C target is - rescanned, which creates new internal node. If we had those includes from - the start, we'd add this node to the list of A dependencies and B - dependencies. As it stands, we need to add it now. + Both A and B have dependency on C and C-includes (the latter dependency + is not shown). Say during building we've tried to create A, then tried to + create C and successfully created C. -
We determine what should be done with C-includes-2, add C-includes-2 - to A's dependencies, and build the target. Unfortunately, we cannot do - the same with B, since we don't know that B is parent of C until we visit - B. So we add a special flag to C telling that it was rescanned. When we - process B, we'll add new dependency node to B's dependencies. this point - of time the target is requested by some parents. So parents were not yet - visited. Both visited and unvisited parents have 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
+In that case, the set of includes in C might well have changed. We do + not bother to detect precisely which includes were added or removed. + Instead we create another internal node C-includes-2. Then we determine + what actions should be run to update the target. In fact this mean that + we perform logic of first stage while already executing stage.
-+- 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: -After actions for C-includes-2 are determined, we add C-includes-2 to + the list of A's dependents, and stage 2 proceeds as usual. Unfortunately, + we can't do the same with target B, since when it's not visited, C target + does not know B depends on it. So, we add a flag to C which tells and it + was rescanned. When visiting B target, the flag is notices and + C-includes-2 will be added to the list of B's dependencies.
+ +Note also that internal nodes are sometimes updated too. Consider this + dependency graph:
- "/usr/include" "/home/t" "." + a.o ---> a.cpp + a.cpp-includes --> a.h (scanned) + a.h-includes ------> a.h (generated) + | + | + a.pro <-------------------------------------------+-
-- As a result: +- "/usr/include" "/home/t" "." "build" --
Here, out handling of generated headers come into play. Say that a.h + exists but is out of date with respect to "a.pro", then "a.h (generated)" + and "a.h-includes" will be marking for updating, but "a.h (scanned)" + won't be marked. We have to rescan "a.h" file after it's created, but + since "a.h (generated)" has no scanner associated with it, it's only + possible to rescan "a.h" after "a.h-includes" target was updated.
-Tbe above consideration lead to decision that we'll rescan a target + whenever it's updated, no matter if this target is internal or not.
The solution in Boost.Jam is to perform additional dependency scans after targets are updated. This break separation between build stages in @@ -189,53 +261,43 @@ B --/ C-includes ---> D - Both A and B have dependency on C and C-includes (the latter is not - shown). Say during building we've tried to create A, then tried to create - C and successfully created C. The B node wasn't seen yet. The C target is - rescanned, which creates new internal node. If we had those includes from - the start, we'd add this node to the list of A dependencies and B - dependencies. As it stands, we need to add it now. + Both A and B have dependency on C and C-includes (the latter dependency + is not shown). Say during building we've tried to create A, then tried to + create C and successfully created C. -
We determine what should be done with C-includes-2, add C-includes-2 - to A's dependencies, and build the target. Unfortunately, we cannot do - the same with B, since we don't know that B is parent of C until we visit - B. So we add a special flag to C telling that it was rescanned. When we - process B, we'll add new dependency node to B's dependencies. this point - of time the target is requested by some parents. So parents were not yet - visited. Both visited and unvisited parents have 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
+In that case, the set of includes in C might well have changed. We do + not bother to detect precisely which includes were added or removed. + Instead we create another internal node C-includes-2. Then we determine + what actions should be run to update the target. In fact this mean that + we perform logic of first stage while already executing stage.
-+- 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: -After actions for C-includes-2 are determined, we add C-includes-2 to + the list of A's dependents, and stage 2 proceeds as usual. Unfortunately, + we can't do the same with target B, since when it's not visited, C target + does not know B depends on it. So, we add a flag to C which tells and it + was rescanned. When visiting B target, the flag is notices and + C-includes-2 will be added to the list of B's dependencies.
+ +Note also that internal nodes are sometimes updated too. Consider this + dependency graph:
- "/usr/include" "/home/t" "." + a.o ---> a.cpp + a.cpp-includes --> a.h (scanned) + a.h-includes ------> a.h (generated) + | + | + a.pro <-------------------------------------------+-
-- As a result: +- "/usr/include" "/home/t" "." "build" --
Here, out handling of generated headers come into play. Say that a.h + exists but is out of date with respect to "a.pro", then "a.h (generated)" + and "a.h-includes" will be marking for updating, but "a.h (scanned)" + won't be marked. We have to rescan "a.h" file after it's created, but + since "a.h (generated)" has no scanner associated with it, it's only + possible to rescan "a.h" after "a.h-includes" target was updated.
-Tbe above consideration lead to decision that we'll rescan a target + whenever it's updated, no matter if this target is internal or not.