added "C++FLAGS.all" (and "OBJCFLAGS.all"); "CFLAGS.all" is still in effect
[k8jam.git] / defaults / Jambase.subdir
blobb4a6b890cc85370a0f9e947243ca51c06ee9fa8b
1 # This program is free software: you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation, version 3 of the License ONLY.
5 # This program is distributed in the hope that it will be useful,
6 # but WITHOUT ANY WARRANTY; without even the implied warranty of
7 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8 # GNU General Public License for more details.
10 # You should have received a copy of the GNU General Public License
11 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
13 rule FSubDirPath {
14   # FSubDirPath TOP d1 ... ;
16   # Returns path to named directory.
18   # If jam is invoked in a subdirectory of the TOP, then we
19   # need to prepend a ../ for every level we must climb up
20   # (TOP-UP), and then append the directory names we must
21   # climb down (TOP-DOWN), plus the named directories d1 ...
22   # If TOP was set externally, or computed from another TOP
23   # that was, we'll have to reroot the whole thing at TOP-ROOT.
24   local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;
25   return $(_r:R=$($(<[1])-ROOT)) ;
29 rule SubDir {
30   #
31   # SubDir TOP d1 d2 ... ;
32   #
33   # Support for a project tree spanning multiple directories.
34   #
35   # SubDir declares a Jamfile's location in a project tree, setting
36   # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source
37   # files can be found.
38   #
39   # TOP is a user-select variable name for root of the tree, and
40   # d1 d2 ...  are the directory elements that lead from the root
41   # of the tree to the directory of the Jamfile.
42   #
43   # TOP can be set externally, but normally the first SubDir call
44   # computes TOP as the path up from the current directory; the
45   # path contains one ../ for each of d1 d2 ...
46   #
47   # SubDir reads once the project-specific rules file Jamrules
48   # in the TOP directory, if present.  This can be overridden
49   # with the variable TOPRULES.
50   #
51   # SubDir supports multiple, overlaid project trees:  SubDir
52   # invocations with different TOPs can appear in the same Jamfile.
53   # The location established by the first SubDir call is used set
54   # the TOPs for the subsequent SubDir calls.
55   #
56   # SubDir's public variables:
57   #
58   #   $(TOP) = path from CWD to root.
59   #   $(SUBDIR) = path from CWD to the directory SubDir names.
60   #   $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names
61   #   $(SEARCH_SOURCE) = $(SUBDIR)
62   #   ###$(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR)
63   #   $(LOCATE_SOURCE) = $(SUBDIR)
64   #   $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR)
65   #   $(LOCATE_BIN) = $(ALL_LOCATE_BIN) $(ALL_LOCATE_TARGET) $(SUBDIR)
66   #   $(LOCATE_LIB) = $(ALL_LOCATE_LIB) $(ALL_LOCATE_TARGET) $(SUBDIR)
67   #   $(LOCATE_LIBSO) = $(ALL_LOCATE_LIBSO) $(ALL_LOCATE_LIB) $(ALL_LOCATE_TARGET) $(SUBDIR)
68   #   $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s
69   #
70   local _top = $(<[1]) ;
71   local _tokens = $(<[2-]) ;
72   local _xpath = $(_tokens:J=$(PATH_SEPARATOR)) ;
74   #Echo "$(_tokens)" ;
75   #Echo "$(_xpath) ";
77   # First time through sets up relative root and includes Jamrules.
78   if ! $(_top) { Exit 'SubDir syntax error' ; }
80   if ! $($(_top)-SET) {
81     $(_top)-SET = true ;
82     # First time we've seen this TOP.
83     # We'll initialize a number of internal variables:
84     #
85     #   $(TOP-UP) = directories from ROOT to a common point
86     #   $(TOP-DOWN) = directories from common point to TOP
87     #   $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD
88     #   $(SUBDIR_UP) = current value of $(TOP-UP)
89     #   $(SUBDIR_DOWN) = current value of $(TOP-DOWN)
90     #   $(SUBDIR_ROOT) = current value of $(TOP-ROOT)
91     #
92     if $($(_top)) {
93       # TOP externally set.
94       # We'll ignore the relative (UP/DOWN) path that
95       # got us here, and instead remember the hard ROOT.
96       $(_top)-UP = ;
97       $(_top)-DOWN = ;
98       $(_top)-ROOT = $($(_top)) ;
99     } else {
100       # TOP not preset.
102       # Establishing a new TOP.  In the simplest case,
103       # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's
104       # merely a certain number of directories down from
105       # the current directory, and FSubDirPath will set
106       # TOP to a path consisting of ../ for each of the
107       # elements of _tokens, because that represents how
108       # far below TOP the current directory sits.
109       #
110       # In the more complicated case, the starting directory
111       # isn't the directory of jam's invocation but an
112       # location established by previous SubDir call.  The
113       # starting directory is SUBDIR_UP directories up from
114       # SUBDIR_ROOT, and then SUBDIR_DOWN directories down
115       # from that.   If SUBDIR_ROOT is not set, that means
116       # SUBDIR_DOWN and SUBDIR_UP represent the path from
117       # the directory of jam's invocation.
118       #
119       # In the most complicated case, the _tokens also
120       # represents directories down, because TOP is being
121       # estalished in a directory other than TOP's root.
122       # Hopefully, _tokens and SUBDIR_DOWN represent the
123       # same final directory, relative to the new TOP and
124       # the previous SubDIr's TOP.  To find the new TOP,
125       # we have to chop off any common directories from
126       # then ends of _tokens and SUBDIR_DOWN.  To do so,
127       # we reverse each of them, call FStripCommon to
128       # remove the initial common elements, and then
129       # reverse them again.  After this process, if
130       # both _tokens and SUBDIR_DOWN have elements, it
131       # means the directory names estalished by the two
132       # SubDir calls don't match, and a warning is issued.
133       # All hell will likely break loose at this point,
134       # since the whole SubDir scheme relies on the SubDir
135       # calls accurately naming the current directory.
137       # Strip common trailing elements of _tokens and SUBDIR_DOWN.
138       _tokens = [ ListReverse $(_tokens) ] ;
139       SUBDIR_DOWN = [ ListReverse $(SUBDIR_DOWN) ] ;
140       FStripCommon _tokens : SUBDIR_DOWN ;
141       SUBDIR_DOWN = [ ListReverse $(SUBDIR_DOWN) ] ;
142       _tokens = [ ListReverse $(_tokens) ] ;
144       if $(SUBDIR_DOWN) && $(_tokens) { Echo 'Warning:' SubDir $(<) 'misplaced!' ; }
146       # We'll remember the relative (UP/DOWN) path that
147       # got us here, plus any hard ROOT starting point
148       # for the UP/DOWN.  If TOP is never set externally,
149       # ROOT will always be "" (directory of jam's invocation).
150       $(_top)-UP = $(SUBDIR_UP) $(_tokens) ;
151       $(_top)-DOWN = $(SUBDIR_DOWN) ;
152       $(_top)-ROOT = $(SUBDIR_ROOT:E="") ;
153       $(_top) = [ FSubDirPath $(_top) ] ;
154     }
156     # Set subdir vars for the inclusion of the Jamrules,
157     # just in case they have SubDir rules of their own.
158     # Note that SUBDIR_DOWN is empty: it's all the way
159     # up where the Jamrules live.  These gets overrided
160     # just after the inclusion.
161     SUBDIR_UP = $($(_top)-UP) ;
162     SUBDIR_DOWN = ;
163     SUBDIR_ROOT = $($(_top)-ROOT) ;
165     # Include $(TOPRULES) or $(TOP)/Jamrules.
166     # Include $(TOPRULES) if set.
167     # Otherwise include $(TOP)/Jamrules if present.
168     if $($(_top)RULES) {
169       softinclude $($(_top)RULES) ;
170     } else {
171       NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;
172       softinclude $(JAMRULES:R=$($(_top)):G=$(_top)) ;
173     }
175     # soft-include "Jamrules.configure"
176     softinclude $($(_top))/Jamrules.configure ;
177   }
179   # Get path from $(TOP) to named directory.
180   # Save dir tokens for other potential uses.
181   SUBDIR_UP = $($(_top)-UP) ;
182   SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;
183   SUBDIR_ROOT = $($(_top)-ROOT) ;
184   SUBDIR_TOKENS = $(SUBDIR_DOWN) ;
186   SUBDIR = [ FSubDirPath $(<) ] ;
188   # Now set up SEARCH_SOURCE, LOCATE_TARGET, LOCATE_BIN, SOURCE_GRIST
189   # These can be reset if needed.  For example, if the source
190   # directory should not hold object files, LOCATE_TARGET can
191   # subsequently be redefined.
192   SEARCH_SOURCE = $(SUBDIR) ;
194   #if $(SUBDIR) = '.' { sdr = "" ; } else { sdr = "$(PATH_SEPARATOR)$(SUBDIR)" ; }
196   if $(ALL_LOCATE_TARGET) {
197     if ! ( $(_xpath) ~= '^/' ) { _xpath = "$(PATH_SEPARATOR[1])$(_xpath)" ; }
198     LOCATE_TARGET = "$(ALL_LOCATE_TARGET[1])$(_xpath)" ;
199     #LOCATE_SOURCE = "$(ALL_LOCATE_TARGET)$(_xpath)" ;
200     LOCATE_SOURCE = $(SUBDIR) ;
201   } else {
202     LOCATE_TARGET = $(SUBDIR) ;
203     LOCATE_SOURCE = $(SUBDIR) ;
204   }
206   if $(ALL_LOCATE_BIN) {
207     LOCATE_BIN = $(ALL_LOCATE_BIN) ;
208   } else {
209     LOCATE_BIN = $(LOCATE_TARGET) ;
210   }
212   if $(ALL_LOCATE_LIB) {
213     LOCATE_LIB = $(ALL_LOCATE_LIB) ;
214   } else {
215     LOCATE_LIB = $(LOCATE_TARGET) ;
216   }
218   if $(ALL_LOCATE_LIBSO) {
219     LOCATE_LIBSO = $(ALL_LOCATE_LIBSO) ;
220   } else {
221     LOCATE_LIBSO = $(LOCATE_LIB) ;
222   }
224   #Echo "ALL_LOCATE_LIB = $(ALL_LOCATE_LIB)" ;
225   #Echo "LOCATE_LIB = $(LOCATE_LIB)" ;
227   SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;
228   #if ! $(LOCATE_BIN) { LOCATE_BIN = $(LOCATE_TARGET) ; }
230   ## OPT_HEADER_CACHE_EXT
231   # With the header cache, we can grist all files found
232   # during a header scan without incurring a performance
233   # penalty.
234   #
235   HDRGRIST = $(SOURCE_GRIST) ;
237   # Reset per-directory ccflags, hdrs, etc,
238   # listed in SUBDIRRESET.
239   # Note use of variable expanded assignment var
240   SUBDIR$(SUBDIRRESET) = ;
242   # Invoke user-specific SubDir extensions,
243   # rule names listed in SUBDIRRULES.
244   # Note use of variable expanded rule invocation
245   $(SUBDIRRULES) $(<) ;
249 #rule SubDirDcFlags {
250 #  SUBDIRDCFLAGS += $(<) ;
254 rule SubDirCcFlags {
255   SUBDIRCCFLAGS += $(<) ;
259 rule SubDirC++Flags {
260   SUBDIRC++FLAGS += $(<) ;
264 rule SubDirObjCFlags {
265   SUBDIROBJCFLAGS += $(<) ;
269 rule SubDirHdrs {
270   SUBDIRHDRS += [ FDirName $(<) ] ;
274 rule SubDirDefines {
275   SUBDIRDEFINES += $(<) ;
279 rule SubIncludeMany {
280   # SubIncludeMany TOP d1 ... ;
281   #
282   # Include a subdirectory's Jamfile.
284   # We use SubDir to get there, in case the included Jamfile
285   # either doesn't have its own SubDir (naughty) or is a subtree
286   # with its own TOP.
287   #Echo 'including ' $(<) ':' $(>) ;
289   if ! $($(<[1])) { Exit 'SubIncludeMany' $(<[1]) 'without prior SubDir' $(<[1]) ; }
290   SubDir $(<) ;
291   include $(JAMFILE:D=$(SUBDIR)) ;
295 rule SubIncludeOnce {
296   # SubIncludeOnce varname : TOP d1 ... ;
297   #
298   # Include a subdirectory's Jamfile.
300   local _vn = $(<[1]) ;
301   if ! $($(_vn)) {
302     #Echo "processing $(_vn)" ;
303     #Echo "$(>)" ;
304     $(_vn) = tan ;
305     SubIncludeMany $(>) ;
306   #} else {
307   #  Echo "skiped $(_vn) -- $($(_vn))" ;
308   #  Echo "$(>)" ;
309   }
313 rule SubInclude {
314   # SubInclude TOP d1 ... ;
315   #
316   # Include a subdirectory's Jamfile.
317   if ! $($(<[1])) { Exit 'SubInclude' $(<[1]) 'without prior SubDir' $(<[1]) ; }
318   local _sbiguard = _K8JAM_SUB_GUARD_$(<:J=_) ;
319   SubIncludeOnce $(_sbiguard) : $(<) ;
323 rule SubRules {
324   # SubRules TOP d1 ... : Other-TOP ;
325   #
326   # Read another tree's Jamrules, by giving it's path according
327   # to this tree and it's own name.
328   if ! $($(<[1])) { Exit 'SubRules' $(<[1]) 'without prior SubDir' $(<[1]) ; }
329   SubDir $(<) ;
330   SubDir $(>) ;
334 # /MakeLocate  targets : directory
336 # Creates _dir_ and causes _target_ to be built into _dir_
338 # This is done by setting the target-specific variable LOCATE
339 # on _targets_, and arranges with @MkDir to create the target
340 # directory
342 rule MakeLocate {
343   # Note we grist the directory name with 'dir',
344   # so that directory path components and other
345   # targets don't conflict.
346   local srcname = $(<[1]:G=) ;
347   local srcdir = $(srcname:D) ;
348   local outdir = $(>[1]:G=dir) ;
349   local odir ;
350   if $(srcdir) {
351     odir = $(outdir)$(PATH_SEPARATOR)$(srcdir) ;
352   } else {
353     odir = $(outdir) ;
354   }
355   #Echo 'MakeLocate:' "$(<)" '|' "$(>)" ;
356   #Echo 'srcname:' "$(srcname)" ;
357   #Echo 'srcdir :' "$(srcdir)" ;
358   #Echo 'outdir :' "$(outdir)" ;
359   #Echo 'odir   :' "$(odir)" ;
360   if $(>) {
361     LOCATE on $(<) = $(>) ;
362     Depends $(<) : $(odir) ;
363     MkDir $(odir) ;
364   }