2 # FSubDirPath TOP d1 ... ;
4 # Returns path to named directory.
6 # If jam is invoked in a subdirectory of the TOP, then we
7 # need to prepend a ../ for every level we must climb up
8 # (TOP-UP), and then append the directory names we must
9 # climb down (TOP-DOWN), plus the named directories d1 ...
10 # If TOP was set externally, or computed from another TOP
11 # that was, we'll have to reroot the whole thing at TOP-ROOT.
12 local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;
14 return $(_r:R=$($(<[1])-ROOT)) ;
20 # SubDir TOP d1 d2 ... ;
22 # Support for a project tree spanning multiple directories.
24 # SubDir declares a Jamfile's location in a project tree, setting
25 # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source
28 # TOP is a user-select variable name for root of the tree, and
29 # d1 d2 ... are the directory elements that lead from the root
30 # of the tree to the directory of the Jamfile.
32 # TOP can be set externally, but normally the first SubDir call
33 # computes TOP as the path up from the current directory; the
34 # path contains one ../ for each of d1 d2 ...
36 # SubDir reads once the project-specific rules file Jamrules
37 # in the TOP directory, if present. This can be overridden
38 # with the variable TOPRULES.
40 # SubDir supports multiple, overlaid project trees: SubDir
41 # invocations with different TOPs can appear in the same Jamfile.
42 # The location established by the first SubDir call is used set
43 # the TOPs for the subsequent SubDir calls.
45 # SubDir's public variables:
47 # $(TOP) = path from CWD to root.
48 # $(SUBDIR) = path from CWD to the directory SubDir names.
49 # $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names
50 # $(SEARCH_SOURCE) = $(SUBDIR)
51 # $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR)
52 # $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR)
53 # $(LOCATE_BIN) = $(ALL_LOCATE_BIN) $(ALL_LOCATE_TARGET) $(SUBDIR)
54 # $(LOCATE_LIB) = $(ALL_LOCATE_LIB) $(ALL_LOCATE_TARGET) $(SUBDIR)
55 # $(LOCATE_LIBSO) = $(ALL_LOCATE_LIBSO) $(ALL_LOCATE_LIB) $(ALL_LOCATE_TARGET) $(SUBDIR)
56 # $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s
58 local _top = $(<[1]) ;
59 local _tokens = $(<[2-]) ;
60 local _xpath = $(_tokens:J=$(PATH_SEPARATOR)) ;
64 if $(_xpath) != "" { _xpath = "$(PATH_SEPARATOR)$(_xpath)" ; }
68 # First time through sets up relative root and includes Jamrules.
69 if ! $(_top) { Exit "SubDir syntax error" ; }
73 # First time we've seen this TOP.
74 # We'll initialize a number of internal variables:
76 # $(TOP-UP) = directories from ROOT to a common point
77 # $(TOP-DOWN) = directories from common point to TOP
78 # $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD
79 # $(SUBDIR_UP) = current value of $(TOP-UP)
80 # $(SUBDIR_DOWN) = current value of $(TOP-DOWN)
81 # $(SUBDIR_ROOT) = current value of $(TOP-ROOT)
85 # We'll ignore the relative (UP/DOWN) path that
86 # got us here, and instead remember the hard ROOT.
89 $(_top)-ROOT = $($(_top)) ;
93 # Establishing a new TOP. In the simplest case,
94 # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's
95 # merely a certain number of directories down from
96 # the current directory, and FSubDirPath will set
97 # TOP to a path consisting of ../ for each of the
98 # elements of _tokens, because that represents how
99 # far below TOP the current directory sits.
101 # In the more complicated case, the starting directory
102 # isn't the directory of jam's invocation but an
103 # location established by previous SubDir call. The
104 # starting directory is SUBDIR_UP directories up from
105 # SUBDIR_ROOT, and then SUBDIR_DOWN directories down
106 # from that. If SUBDIR_ROOT is not set, that means
107 # SUBDIR_DOWN and SUBDIR_UP represent the path from
108 # the directory of jam's invocation.
110 # In the most complicated case, the _tokens also
111 # represents directories down, because TOP is being
112 # estalished in a directory other than TOP's root.
113 # Hopefully, _tokens and SUBDIR_DOWN represent the
114 # same final directory, relative to the new TOP and
115 # the previous SubDIr's TOP. To find the new TOP,
116 # we have to chop off any common directories from
117 # then ends of _tokens and SUBDIR_DOWN. To do so,
118 # we reverse each of them, call FStripCommon to
119 # remove the initial common elements, and then
120 # reverse them again. After this process, if
121 # both _tokens and SUBDIR_DOWN have elements, it
122 # means the directory names estalished by the two
123 # SubDir calls don't match, and a warning is issued.
124 # All hell will likely break loose at this point,
125 # since the whole SubDir scheme relies on the SubDir
126 # calls accurately naming the current directory.
128 # Strip common trailing elements of _tokens and SUBDIR_DOWN.
129 _tokens = [ FReverse $(_tokens) ] ;
130 SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
131 FStripCommon _tokens : SUBDIR_DOWN ;
132 SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
133 _tokens = [ FReverse $(_tokens) ] ;
135 if $(SUBDIR_DOWN) && $(_tokens) { Echo "Warning:" SubDir $(<) "misplaced!" ; }
137 # We'll remember the relative (UP/DOWN) path that
138 # got us here, plus any hard ROOT starting point
139 # for the UP/DOWN. If TOP is never set externally,
140 # ROOT will always be "" (directory of jam's invocation).
141 $(_top)-UP = $(SUBDIR_UP) $(_tokens) ;
142 $(_top)-DOWN = $(SUBDIR_DOWN) ;
143 $(_top)-ROOT = $(SUBDIR_ROOT:E="") ;
144 $(_top) = [ FSubDirPath $(_top) ] ;
147 # Set subdir vars for the inclusion of the Jamrules,
148 # just in case they have SubDir rules of their own.
149 # Note that SUBDIR_DOWN is empty: it's all the way
150 # up where the Jamrules live. These gets overrided
151 # just after the inclusion.
152 SUBDIR_UP = $($(_top)-UP) ;
154 SUBDIR_ROOT = $($(_top)-ROOT) ;
156 # Include $(TOPRULES) or $(TOP)/Jamrules.
157 # Include $(TOPRULES) if set.
158 # Otherwise include $(TOP)/Jamrules if present.
160 softinclude $($(_top)RULES) ;
162 NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;
163 softinclude $(JAMRULES:R=$($(_top)):G=$(_top)) ;
167 # Get path from $(TOP) to named directory.
168 # Save dir tokens for other potential uses.
169 SUBDIR_UP = $($(_top)-UP) ;
170 SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;
171 SUBDIR_ROOT = $($(_top)-ROOT) ;
172 SUBDIR_TOKENS = $(SUBDIR_DOWN) ;
174 SUBDIR = [ FSubDirPath $(<) ] ;
176 # Now set up SEARCH_SOURCE, LOCATE_TARGET, LOCATE_BIN, SOURCE_GRIST
177 # These can be reset if needed. For example, if the source
178 # directory should not hold object files, LOCATE_TARGET can
179 # subsequently be redefined.
180 SEARCH_SOURCE = $(SUBDIR) ;
182 #if $(SUBDIR) = "." { sdr = "" ; } else { sdr = "$(PATH_SEPARATOR)$(SUBDIR)" ; }
184 if $(ALL_LOCATE_TARGET) {
185 LOCATE_TARGET = "$(ALL_LOCATE_TARGET)$(_xpath)" ;
186 LOCATE_SOURCE = "$(ALL_LOCATE_TARGET)$(_xpath)" ;
188 LOCATE_TARGET = $(SUBDIR) ;
189 LOCATE_SOURCE = $(SUBDIR) ;
192 if $(ALL_LOCATE_BIN) {
193 LOCATE_BIN = $(ALL_LOCATE_BIN) ;
195 LOCATE_BIN = $(LOCATE_TARGET) ;
198 if $(ALL_LOCATE_LIB) {
199 LOCATE_LIB = $(ALL_LOCATE_LIB) ;
201 LOCATE_LIB = $(LOCATE_TARGET) ;
204 if $(ALL_LOCATE_LIBSO) {
205 LOCATE_LIBSO = $(ALL_LOCATE_LIBSO) ;
207 LOCATE_LIBSO = $(LOCATE_LIB) ;
210 #Echo "ALL_LOCATE_LIB = $(ALL_LOCATE_LIB)" ;
211 #Echo "LOCATE_LIB = $(LOCATE_LIB)" ;
213 SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;
214 #if ! $(LOCATE_BIN) { LOCATE_BIN = $(LOCATE_TARGET) ; }
216 ## OPT_HEADER_CACHE_EXT
217 # With the header cache, we can grist all files found
218 # during a header scan without incurring a performance
221 HDRGRIST = $(SOURCE_GRIST) ;
223 # Reset per-directory ccflags, hdrs, etc,
224 # listed in SUBDIRRESET.
225 # Note use of variable expanded assignment var
226 SUBDIR$(SUBDIRRESET) = ;
228 # Invoke user-specific SubDir extensions,
229 # rule names listed in SUBDIRRULES.
230 # Note use of variable expanded rule invocation
231 $(SUBDIRRULES) $(<) ;
235 #rule SubDirDcFlags {
236 # SUBDIRDCFLAGS += $(<) ;
241 SUBDIRCCFLAGS += $(<) ;
245 rule SubDirC++Flags {
246 SUBDIRC++FLAGS += $(<) ;
250 rule SubDirObjCFlags {
251 SUBDIROBJCFLAGS += $(<) ;
256 SUBDIRHDRS += [ FDirName $(<) ] ;
261 SUBDIRDEFINES += $(<) ;
265 rule SubIncludeMany {
266 # SubIncludeMany TOP d1 ... ;
268 # Include a subdirectory's Jamfile.
270 # We use SubDir to get there, in case the included Jamfile
271 # either doesn't have its own SubDir (naughty) or is a subtree
273 #Echo "including " $(<) " : " $(>) ;
275 if ! $($(<[1])) { Exit "SubIncludeMany" $(<[1]) "without prior SubDir" $(<[1]) ; }
277 include $(JAMFILE:D=$(SUBDIR)) ;
281 rule SubIncludeOnce {
282 # SubIncludeOnce varname : TOP d1 ... ;
284 # Include a subdirectory's Jamfile.
286 local _vn = $(<[1]) ;
288 #Echo "processing $(_vn)" ;
291 SubIncludeMany $(>) ;
293 # Echo "skiped $(_vn) -- $($(_vn))" ;
300 # SubInclude TOP d1 ... ;
302 # Include a subdirectory's Jamfile.
303 if ! $($(<[1])) { Exit "SubInclude" $(<[1]) "without prior SubDir" $(<[1]) ; }
304 local _sbiguard = _K8JAM_SUB_GUARD_$(<:J=_) ;
305 SubIncludeOnce $(_sbiguard) : $(<) ;
310 # SubRules TOP d1 ... : Other-TOP ;
312 # Read another tree's Jamrules, by giving it's path according
313 # to this tree and it's own name.
314 if ! $($(<[1])) { Exit "SubRules" $(<[1]) "without prior SubDir" $(<[1]) ; }
320 # /MakeLocate targets : directory
322 # Creates _dir_ and causes _target_ to be built into _dir_
324 # This is done by setting the target-specific variable LOCATE
325 # on _targets_, and arranges with @MkDir to create the target
329 # Note we grist the directory name with 'dir',
330 # so that directory path components and other
331 # targets don't conflict.
332 local srcname = $(<[1]:G=) ;
333 local srcdir = $(srcname:D) ;
334 local outdir = $(>[1]:G=dir) ;
337 odir = $(outdir)$(PATH_SEPARATOR)$(srcdir) ;
341 #Echo "MakeLocate:" "$(<)" "|" "$(>)" ;
342 #Echo "srcname:" "$(srcname)" ;
343 #Echo "srcdir :" "$(srcdir)" ;
344 #Echo "outdir :" "$(outdir)" ;
345 #Echo "odir :" "$(odir)" ;
347 LOCATE on $(<) = $(>) ;
348 Depends $(<) : $(odir) ;