boiler now not includes dirs without headers in HDRS
[k8jam.git] / defaults / Jambase.subdir
blobfa604dc5fe5310c14eeca95431865644342912ad
1 rule FSubDirPath {
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)) ;
18 rule SubDir {
19   #
20   # SubDir TOP d1 d2 ... ;
21   #
22   # Support for a project tree spanning multiple directories.
23   #
24   # SubDir declares a Jamfile's location in a project tree, setting
25   # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source
26   # files can be found.
27   #
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.
31   #
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 ...
35   #
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.
39   #
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.
44   #
45   # SubDir's public variables:
46   #
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
57   #
58   local _top = $(<[1]) ;
59   local _tokens = $(<[2-]) ;
60   local _xpath = $(_tokens:J=$(PATH_SEPARATOR)) ;
62   #Echo "$(_tokens)" ;
63   #Echo "$(_xpath) ";
64   if $(_xpath) != "" { _xpath = "$(PATH_SEPARATOR)$(_xpath)" ; }
66   #local sdr ;
68   # First time through sets up relative root and includes Jamrules.
69   if ! $(_top) { Exit "SubDir syntax error" ; }
71   if ! $($(_top)-SET) {
72     $(_top)-SET = true ;
73     # First time we've seen this TOP.
74     # We'll initialize a number of internal variables:
75     #
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)
82     #
83     if $($(_top)) {
84       # TOP externally set.
85       # We'll ignore the relative (UP/DOWN) path that
86       # got us here, and instead remember the hard ROOT.
87       $(_top)-UP = ;
88       $(_top)-DOWN = ;
89       $(_top)-ROOT = $($(_top)) ;
90     } else {
91       # TOP not preset.
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.
100       #
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.
109       #
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) ] ;
145     }
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) ;
153     SUBDIR_DOWN = ;
154     SUBDIR_ROOT = $($(_top)-ROOT) ;
156     # Include $(TOPRULES) or $(TOP)/Jamrules.
157     # Include $(TOPRULES) if set.
158     # Otherwise include $(TOP)/Jamrules if present.
159     if $($(_top)RULES) {
160       include $($(_top)RULES) ;
161     } else {
162       NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;
163       include $(JAMRULES:R=$($(_top)):G=$(_top)) ;
164     }
165   }
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)" ;
187   } else {
188     LOCATE_TARGET = $(SUBDIR) ;
189     LOCATE_SOURCE = $(SUBDIR) ;
190   }
192   if $(ALL_LOCATE_BIN) {
193     LOCATE_BIN = $(ALL_LOCATE_BIN) ;
194   } else {
195     LOCATE_BIN = $(LOCATE_TARGET) ;
196   }
198   if $(ALL_LOCATE_LIB) {
199     LOCATE_LIB = $(ALL_LOCATE_LIB) ;
200   } else {
201     LOCATE_LIB = $(LOCATE_TARGET) ;
202   }
204   if $(ALL_LOCATE_LIBSO) {
205     LOCATE_LIBSO = $(ALL_LOCATE_LIBSO) ;
206   } else {
207     LOCATE_LIBSO = $(LOCATE_LIB) ;
208   }
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
219   # penalty.
220   #
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 += $(<) ;
240 rule SubDirCcFlags {
241   SUBDIRCCFLAGS += $(<) ;
245 rule SubDirC++Flags {
246   SUBDIRC++FLAGS += $(<) ;
250 rule SubDirObjCFlags {
251   SUBDIROBJCFLAGS += $(<) ;
255 rule SubDirHdrs {
256   SUBDIRHDRS += [ FDirName $(<) ] ;
260 rule SubIncludeMany {
261   # SubIncludeMany TOP d1 ... ;
262   #
263   # Include a subdirectory's Jamfile.
265   # We use SubDir to get there, in case the included Jamfile
266   # either doesn't have its own SubDir (naughty) or is a subtree
267   # with its own TOP.
268   #Echo "including " $(<) " : " $(>) ;
270   if ! $($(<[1])) { Exit "SubIncludeMany" $(<[1]) "without prior SubDir" $(<[1]) ; }
271   SubDir $(<) ;
272   include $(JAMFILE:D=$(SUBDIR)) ;
276 rule SubIncludeOnce {
277   # SubIncludeOnce varname : TOP d1 ... ;
278   #
279   # Include a subdirectory's Jamfile.
281   local _vn = $(<[1]) ;
282   if ! $($(_vn)) {
283     #Echo "processing $(_vn)" ;
284     #Echo "$(>)" ;
285     $(_vn) = tan ;
286     SubIncludeMany $(>) ;
287   #} else {
288   #  Echo "skiped $(_vn) -- $($(_vn))" ;
289   #  Echo "$(>)" ;
290   }
294 rule SubInclude {
295   # SubInclude TOP d1 ... ;
296   #
297   # Include a subdirectory's Jamfile.
298   if ! $($(<[1])) { Exit "SubInclude" $(<[1]) "without prior SubDir" $(<[1]) ; }
299   local _sbiguard = _K8JAM_SUB_GUARD_$(<:J=_) ;
300   SubIncludeOnce $(_sbiguard) : $(<) ;
304 rule SubRules {
305   # SubRules TOP d1 ... : Other-TOP ;
306   #
307   # Read another tree's Jamrules, by giving it's path according
308   # to this tree and it's own name.
309   if ! $($(<[1])) { Exit "SubRules" $(<[1]) "without prior SubDir" $(<[1]) ; }
310   SubDir $(<) ;
311   SubDir $(>) ;
315 # /MakeLocate  targets : directory
317 # Creates _dir_ and causes _target_ to be built into _dir_
319 # This is done by setting the target-specific variable LOCATE
320 # on _targets_, and arranges with @MkDir to create the target
321 # directory
323 rule MakeLocate {
324   # Note we grist the directory name with 'dir',
325   # so that directory path components and other
326   # targets don't conflict.
327   local srcname = $(<[1]:G=) ;
328   local srcdir = $(srcname:D) ;
329   local outdir = $(>[1]:G=dir) ;
330   local odir ;
331   if $(srcdir) {
332     odir = $(outdir)$(PATH_SEPARATOR)$(srcdir) ;
333   } else {
334     odir = $(outdir) ;
335   }
336   #Echo "MakeLocate:" "$(<)" "|" "$(>)" ;
337   #Echo "srcname:" "$(srcname)" ;
338   #Echo "srcdir :" "$(srcdir)" ;
339   #Echo "outdir :" "$(outdir)" ;
340   #Echo "odir   :" "$(odir)" ;
341   if $(>) {
342     LOCATE on $(<) = $(>) ;
343     Depends $(<) : $(odir) ;
344     MkDir $(odir) ;
345   }