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