xref: /haiku/build/jam/OverriddenJamRules (revision 746cac055adc6ac3308c7bc2d29040fb95689cc9)
1# Overridden to allow spaces in file names.
2actions Chmod1
3{
4	$(CHMOD) "$(MODE)" "$(1)"
5}
6
7# Overridden to allow spaces in file names.
8actions piecemeal together existing Clean
9{
10	$(RM) "$(>)"
11}
12
13#-------------------------------------------------------------------------------
14# Link rule/action are overwritten as they don't handle linking files who's name
15# contain spaces very well. Also adds resources and version to executable.
16#-------------------------------------------------------------------------------
17rule Link
18{
19	# Note: RESFILES must be set before invocation.
20
21	if [ on $(1) return $(PLATFORM) ] = host {
22		LINK on $(1) = $(HOST_LINK) ;
23	 	LINKFLAGS on $(1) = $(HOST_LINKFLAGS) [ on $(1) return $(LINKFLAGS) ] ;
24	} else {
25		LINK on $(1) = $(TARGET_LINK) ;
26	 	LINKFLAGS on $(1) = $(TARGET_LINKFLAGS)
27			[ on $(1) return $(LINKFLAGS) ] ;
28	}
29
30 	NEEDLIBS on $(1) = [ on $(1) return $(NEEDLIBS) ] ;
31 	LINKLIBS on $(1) = [ on $(1) return $(LINKLIBS) ] ;
32
33	MODE on $(<) = $(EXEMODE) ;
34	on $(1) XRes $(1) : $(RESFILES) ;
35	if ! [ on $(1) return $(DONT_USE_BEOS_RULES) ] {
36		SetType $(1) ;
37		MimeSet $(1) ;
38		SetVersion $(1) ;
39
40		# If the generic attribute emulation is enabled, make sure the tool to
41		# remove the attributes is built first.
42		if $(HOST_RM_ATTRS_TARGET) {
43			Depends $(1) : $(HOST_RM_ATTRS_TARGET) ;
44		}
45	}
46	Chmod $(<) ;
47}
48
49# When using "real" attributes (i.e. BeOS attributes or xattr/extattr) on the
50# host platform, unlinking the main target by gcc will also automatically get
51# rid of the attributes. When using the generic attribute emulation, which
52# uses separate files, we need to remove the target explicitely first, so that
53# the attributes won't be "leaked".
54if $(HOST_PLATFORM_BEOS_COMPATIBLE) || $(HAIKU_HOST_USE_XATTR) = 1 {
55	actions Link bind NEEDLIBS LINK_BEGIN_GLUE LINK_END_GLUE
56	{
57		$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(LINK_BEGIN_GLUE)" "$(2)" \
58			"$(NEEDLIBS)" $(LINKLIBS) "$(LINK_END_GLUE)" ;
59	}
60} else {
61	actions Link bind NEEDLIBS LINK_BEGIN_GLUE LINK_END_GLUE
62	{
63		$(RM) "$(1)"
64		$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(LINK_BEGIN_GLUE)" "$(2)" \
65			"$(NEEDLIBS)" $(LINKLIBS) "$(LINK_END_GLUE)" ;
66	}
67}
68
69rule Object
70{
71	# find out which headers and defines to use
72	local headers ;
73	local sysHeaders ;
74	local defines ;
75
76	on $(1) { # use on $(1) variable values
77		if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
78			return ;
79		}
80
81		# Save HDRS for -I$(HDRS) on compile.
82		# We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
83		# in the .c file's directory, but generated .c files (from
84		# yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
85		# different from $(SEARCH_SOURCE).
86
87		headers = $(HAIKU_CONFIG_HEADERS) $(SEARCH_SOURCE) $(SUBDIRHDRS)
88			$(HDRS) ;
89		sysHeaders = $(SUBDIRSYSHDRS) $(SYSHDRS) ;
90		defines = $(DEFINES) ;
91
92		if $(PLATFORM) = host {
93			sysHeaders += $(HOST_HDRS) ;
94			defines += $(HOST_DEFINES) ;
95
96			if $(USES_BE_API) {
97				sysHeaders += $(HOST_BE_API_HEADERS) ;
98			}
99
100		} else {
101			sysHeaders += $(TARGET_HDRS) ;
102			defines += $(TARGET_DEFINES) ;
103		}
104	}
105
106	# locate object and search for source
107
108	LocalClean clean : $(<) ;
109
110	MakeLocateDebug $(<) ;
111	SEARCH on $(>) = $(SEARCH_SOURCE) ;
112
113	HDRS on $(<) = $(headers) ;
114	SYSHDRS on $(<) = $(sysHeaders) ;
115
116	# handle #includes for source: Jam scans for headers with
117	# the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
118	# with the scanned file as the target and the found headers
119	# as the sources.  HDRSEARCH is the value of SEARCH used for
120	# the found header files.  Finally, if jam must deal with
121	# header files of the same name in different directories,
122	# they can be distinguished with HDRGRIST.
123
124	# $(SEARCH_SOURCE:E) is where cc first looks for #include
125	# "foo.h" files.  If the source file is in a distant directory,
126	# look there.  Else, look in "" (the current directory).
127
128	HDRRULE on $(>) = HdrRule ;
129	HDRSCAN on $(>) = $(HDRPATTERN) ;
130	HDRSEARCH on $(>) = $(headers) $(sysHeaders) $(STDHDRS) ;
131	HDRGRIST on $(>) = $(HDRGRIST) ;
132
133	# propagate target specific-defines
134
135	DEFINES on $(1) = $(defines) ;
136
137	# if source is not .c, generate .c with specific rule
138
139	switch $(>:S)
140	{
141	    case .asm : As $(<) : $(>) ;
142	    case .c :	Cc $(<) : $(>) ;
143	    case .C :	C++ $(<) : $(>) ;
144	    case .cc :	C++ $(<) : $(>) ;
145	    case .cpp : C++ $(<) : $(>) ;
146	    case .f :	Fortran $(<) : $(>) ;
147	    case .l :	if [ on $(2) return $(GENERATE_C++) ] {
148	    				InheritPlatform $(<:S=.cpp) : $(1) ;
149						C++ $(<) : $(<:S=.cpp) ;
150						Lex $(<:S=.cpp) : $(>) ;
151					} else {
152	    				InheritPlatform $(<:S=.c) : $(1) ;
153						Cc $(<) : $(<:S=.c) ;
154						Lex $(<:S=.c) : $(>) ;
155					}
156		case *.o :	return ;
157	    case .s :	As $(<) : $(>) ;
158	    case .S :	As $(<) : $(>) ;
159	    case .y :	if [ on $(2) return $(GENERATE_C++) ] {
160	    				InheritPlatform $(1:S=.cpp) $(1:S=.hpp) : $(1) ;
161						C++ $(1) : $(1:S=.cpp) ;
162						Yacc $(1:S=.cpp) $(1:S=.hpp) : $(2) ;
163					} else {
164	    				InheritPlatform $(1:S=.c) $(1:S=.h) : $(1) ;
165						Cc $(1) : $(1:S=.c) ;
166						Yacc $(1:S=.c) $(1:S=.h) : $(2) ;
167					}
168	    case * :	UserObject $(<) : $(>) ;
169	}
170}
171
172rule As
173{
174	local flags ;
175	local includesSeparator ;
176	local localIncludesOption ;
177	local systemIncludesOption ;
178	if [ on $(1) return $(PLATFORM) ] = host {
179		flags = [ on $(1) return $(HOST_ASFLAGS) $(ASFLAGS) ] ;
180
181		CC on $(1) = $(HOST_CC) ;
182
183		includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;
184		localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;
185		systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;
186
187	} else {
188		flags = [ on $(1) return $(TARGET_ASFLAGS) $(ASFLAGS) ] ;
189
190		CC on $(1) = $(TARGET_CC) ;
191
192		includesSeparator = $(TARGET_INCLUDES_SEPARATOR) ;
193		localIncludesOption = $(TARGET_LOCAL_INCLUDES_OPTION) ;
194		systemIncludesOption = $(TARGET_SYSTEM_INCLUDES_OPTION) ;
195	}
196
197	Depends $(<) : $(>) ;
198	ASFLAGS on $(<) += $(flags) $(SUBDIRASFLAGS) ;
199	ASHDRS on $(<) = [ on $(<) FIncludes $(HDRS) : $(localIncludesOption) ]
200		$(includesSeparator)
201		[ on $(<) FSysIncludes $(SYSHDRS) : $(systemIncludesOption) ] ;
202	ASDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
203}
204
205# TODO: The KERNEL_CCFLAGS were used here before. Check whether we need any
206# flags we don't have now.
207actions As
208{
209	$(CC) -c "$(2)" -O2 $(ASFLAGS) -D_ASSEMBLER $(ASDEFS) $(ASHDRS) -o "$(1)" ;
210}
211
212rule Lex
213{
214	Depends $(1) : $(2) ;
215	MakeLocateArch $(1) ;
216	LocalClean clean : $(1) ;
217}
218
219actions Lex
220{
221	$(LEX) $(LEXFLAGS) -o$(1) $(2)
222}
223
224rule Yacc
225{
226	local source = $(1[1]) ;
227	local header = $(1[2]) ;
228	local yaccSource = $(2) ;
229
230	MakeLocateArch $(source) $(header) ;
231
232	Depends $(source) $(header) : $(yaccSource) ;
233	Yacc1 $(source) $(header) : $(yaccSource) ;
234	LocalClean clean : $(source) $(header) ;
235
236	# make sure someone includes $(header) else it will be
237	# a deadly independent target
238
239	Includes $(source) : $(header) ;
240}
241
242actions Yacc1
243{
244	bison $(YACCFLAGS) -o $(1[1]) $(2)
245	[ -f $(1[1]).h ] && mv $(1[1]).h $(1[2]) || true
246}
247
248rule Cc
249{
250	Depends $(<) : $(>) ;
251
252	on $(1) {
253		local flags ;
254		local includesSeparator ;
255		local localIncludesOption ;
256		local systemIncludesOption ;
257
258		# optimization flags
259		if $(DEBUG) = 0 {
260			flags += $(OPTIM) ;
261		} else {
262			flags += -O0 ;
263		}
264
265		if $(PLATFORM) = host {
266			# warning flags
267			if $(WARNINGS) != 0 {
268				flags += $(HOST_WARNING_CCFLAGS) ;
269			}
270
271			# debug and other flags
272			flags += $(HOST_CCFLAGS) $(HOST_DEBUG_$(DEBUG)_CCFLAGS)
273				$(SUBDIRCCFLAGS) $(CCFLAGS) ;
274
275			if $(USES_BE_API) {
276				flags += $(HOST_BE_API_CCFLAGS) ;
277			}
278
279			CC on $(1) = $(HOST_CC) ;
280
281			includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;
282			localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;
283			systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;
284
285		} else {
286			# warning flags
287			if $(WARNINGS) != 0 {
288				flags += $(TARGET_WARNING_CCFLAGS) ;
289			}
290
291			# debug and other flags
292			flags += $(TARGET_CCFLAGS) $(TARGET_DEBUG_$(DEBUG)_CCFLAGS)
293				$(SUBDIRCCFLAGS) $(CCFLAGS) ;
294
295			CC on $(1) = $(TARGET_CC) ;
296
297			includesSeparator = $(TARGET_INCLUDES_SEPARATOR) ;
298			localIncludesOption = $(TARGET_LOCAL_INCLUDES_OPTION) ;
299			systemIncludesOption = $(TARGET_SYSTEM_INCLUDES_OPTION) ;
300		}
301
302		CCFLAGS on $(<) = $(flags) ;
303		CCHDRS on $(<) = [ FIncludes $(HDRS) : $(localIncludesOption) ]
304			$(includesSeparator)
305			[ FSysIncludes $(SYSHDRS) : $(systemIncludesOption) ] ;
306		CCDEFS on $(<) = [ FDefines $(DEFINES) ] ;
307	}
308}
309
310actions Cc
311{
312	$(CC) $(CCFLAGS) -c "$(2)" $(CCDEFS) $(CCHDRS) -o "$(1)" ;
313}
314
315rule C++
316{
317	Depends $(<) : $(>) ;
318
319	on $(1) {
320		local flags ;
321		local includesSeparator ;
322		local localIncludesOption ;
323		local systemIncludesOption ;
324
325		# optimization flags
326		if $(DEBUG) = 0 {
327			flags += $(OPTIM) ;
328		} else {
329			flags += -O0 ;
330		}
331
332		if $(PLATFORM) = host {
333			# warning flags
334			if $(WARNINGS) != 0 {
335				flags += $(HOST_WARNING_C++FLAGS) ;
336			}
337
338			# debug and other flags
339			flags += $(HOST_C++FLAGS) $(HOST_DEBUG_$(DEBUG)_C++FLAGS)
340				$(SUBDIRC++FLAGS) $(C++FLAGS) ;
341
342			if $(USES_BE_API) {
343				flags += $(HOST_BE_API_C++FLAGS) ;
344			}
345
346			C++ on $(1) = $(HOST_C++) ;
347
348			includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;
349			localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;
350			systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;
351
352		} else {
353			# warning flags
354			if $(WARNINGS) != 0 {
355				flags += $(TARGET_WARNING_C++FLAGS) ;
356			}
357
358			# debug and other flags
359			flags += $(TARGET_C++FLAGS) $(TARGET_DEBUG_$(DEBUG)_C++FLAGS)
360				$(SUBDIRC++FLAGS) $(C++FLAGS) ;
361
362			C++ on $(1) = $(TARGET_C++) ;
363
364			includesSeparator = $(TARGET_INCLUDES_SEPARATOR) ;
365			localIncludesOption = $(TARGET_LOCAL_INCLUDES_OPTION) ;
366			systemIncludesOption = $(TARGET_SYSTEM_INCLUDES_OPTION) ;
367		}
368
369		C++FLAGS on $(<) = $(flags) ;
370		CCHDRS on $(<) = [ FIncludes $(HDRS) : $(localIncludesOption) ]
371			$(includesSeparator)
372			[ FSysIncludes $(SYSHDRS) : $(systemIncludesOption) ] ;
373		CCDEFS on $(<) = [ FDefines $(DEFINES) ] ;
374	}
375}
376
377actions C++
378{
379	$(C++) -c "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
380}
381
382actions together Archive
383{
384	# Force recreation of the archive to avoid build errors caused by
385	# stale dependencies after renaming or deleting object files.
386	$(RM) $(<)
387	$(AR) $(<) $(>)
388}
389
390rule Library
391{
392	local lib = $(1) ;
393	local sources = [ FGristFiles $(2) ] ;
394	local objects = $(sources:S=$(SUFOBJ)) ;
395
396	InheritPlatform $(objects) : $(lib) ;
397	LibraryFromObjects $(lib) : $(objects) ;
398	Objects $(sources) ;
399}
400
401rule LibraryFromObjects
402{
403	local _i _l _s ;
404
405	# Add grist to file names
406	# bonefish: No, don't. The Library rule does that anyway, and when we
407	# have an object from another dir, we certainly don't want that.
408
409	_s = $(>) ;
410	_l = $(<:S=$(SUFLIB)) ;
411
412	on $(_l) {
413		# set the tools according to the platform
414		if $(PLATFORM) = host {
415			AR on $(_l) = $(HOST_AR) $(HOST_ARFLAGS) ;
416			RANLIB on $(_l) = $(HOST_RANLIB) ;
417		} else {
418			AR on $(_l) = $(TARGET_AR) $(TARGET_ARFLAGS) ;
419			RANLIB on $(_l) = $(TARGET_RANLIB) ;
420		}
421
422		# library depends on its member objects
423
424		if $(KEEPOBJS)
425		{
426			LocalDepends obj : $(_s) ;
427		}
428
429		LocalDepends lib : $(_l) ;
430
431		# Set LOCATE for the library and its contents.  The bound
432		# value shows up as $(NEEDLIBS) on the Link actions.
433		# For compatibility, we only do this if the library doesn't
434		# already have a path.
435
436		if ! $(_l:D)
437		{
438			# locate the library only, if it hasn't been located yet
439			local dir = $(LOCATE[1]) ;
440			if ! $(dir) {
441				MakeLocateDebug $(_l) ;
442				dir = [ on $(_l) return $(LOCATE[1]) ] ;
443					# Note: The "on ..." is necessary, since our environment
444					# isn't changed by MakeLocateDebug.
445			}
446			MakeLocate $(_l)($(_s:BS)) : $(dir) ;
447		}
448
449		if $(NOARSCAN)
450		{
451			# If we can't scan the library to timestamp its contents,
452			# we have to just make the library depend directly on the
453			# on-disk object files.
454
455			Depends $(_l) : $(_s) ;
456		}
457		else
458		{
459			# If we can scan the library, we make the library depend
460			# on its members and each member depend on the on-disk
461			# object file.
462
463			Depends $(_l) : $(_l)($(_s:BS)) ;
464
465			for _i in $(_s)
466			{
467			Depends $(_l)($(_i:BS)) : $(_i) ;
468			}
469		}
470
471		LocalClean clean : $(_l) ;
472
473		# bonefish: Not needed on the supported platforms. Maybe later...
474		# if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
475
476		Archive $(_l) : $(_s) ;
477
478		if $(RANLIB) { Ranlib $(_l) ; }
479
480		# If we can't scan the library, we have to leave the .o's around.
481
482		if ! ( $(KEEPOBJS) || $(NOARSCAN) || $(NOARUPDATE) ) {
483			RmTemps $(_l) : $(_s) ;
484		}
485	}
486}
487
488rule Main
489{
490	local target = $(1) ;
491	local sources = [ FGristFiles $(2) ] ;
492	local objects = $(sources:S=$(SUFOBJ)) ;
493
494	InheritPlatform $(objects) : $(target) ;
495	MainFromObjects $(target) : $(objects) ;
496	Objects $(sources) ;
497}
498
499rule MainFromObjects
500{
501	local _s _t ;
502
503	# Add grist to file names
504	# Add suffix to exe
505
506	_s = [ FGristFiles $(>) ] ;
507	_t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
508
509	# so 'jam foo' works when it's really foo.exe
510
511	if $(_t) != $(<)
512	{
513	    Depends $(<) : $(_t) ;
514	    NotFile $(<) ;
515	}
516
517	# make compiled sources a dependency of target
518
519	LocalDepends exe : $(_t) ;
520	Depends $(_t) : $(_s) ;
521	MakeLocateDebug $(_t) ;
522
523	LocalClean clean : $(_t) ;
524
525	Link $(_t) : $(_s) ;
526}
527
528# Override Jam 2.5rc3 MakeLocate and MkDir to deal more intelligently
529# with grist set on the supplied directory name.
530rule MakeLocate
531{
532	local dir = $(2[1]) ;
533
534	if $(dir)
535	{
536		if ! $(dir:G) {
537			dir = $(dir:G=dir) ;
538		}
539	    LOCATE on $(1) += $(dir:G=) ;	# don't relocate once located
540	    Depends $(1) : $(dir) ;
541	    MkDir $(dir) ;
542	}
543}
544
545rule MkDir
546{
547	local dir = $(<) ;
548	if ! $(dir:G) {
549		dir = $(dir:G=dir) ;
550	}
551
552	# make this and all super directories
553	while true {
554		# If dir exists, don't update it
555		# Do this even for $(DOT).
556		NoUpdate $(dir) ;
557
558		# Bail out when reaching the CWD (".") or a directory we've already
559		# made.
560		if $(dir:G=) = $(DOT) || $($(dir:G=)-mkdir) {
561			return ;
562		}
563
564		local s ;
565
566		# Cheesy gate to prevent multiple invocations on same dir
567		# MkDir1 has the actions
568		# Arrange for jam dirs
569
570		$(dir:G=)-mkdir = true ;
571		MkDir1 $(dir) ;
572		LocalDepends dirs : $(dir) ;
573
574		# Recursively make parent directories.
575		# $(dir:P) = $(dir)'s parent, & we recurse until root
576
577		s = $(dir:P) ;	# parent keeps grist
578
579		if $(s:G=) && $(s) != $(dir) {
580			Depends $(dir) : $(s) ;
581			dir = $(s) ;
582		} else if $(s) {
583			NotFile $(s) ;
584			break ;
585		}
586	}
587}
588
589rule ObjectCcFlags
590{
591	# supports inheriting the global variable value
592
593	local file ;
594	for file in [ FGristFiles $(1:S=$(SUFOBJ)) ] {
595		CCFLAGS on $(file) = [ on $(file) return $(CCFLAGS) ] $(2) ;
596	}
597}
598
599rule ObjectC++Flags
600{
601	# supports inheriting the global variable value
602
603	local file ;
604	for file in [ FGristFiles $(1:S=$(SUFOBJ)) ] {
605		C++FLAGS on $(file) = [ on $(file) return $(C++FLAGS) ] $(2) ;
606	}
607}
608
609rule ObjectDefines
610{
611	# supports inheriting the global variable value and multiple files
612
613	if $(2) {
614		local file ;
615		for file in [ FGristFiles $(1:S=$(SUFOBJ)) ] {
616			DEFINES on $(file) = [ on $(file) return $(DEFINES) ] $(2) ;
617			CCDEFS on $(file) = [ on $(file) FDefines $(DEFINES) ] ;
618		}
619	}
620}
621
622rule ObjectHdrs
623{
624	# ObjectHdrs <sources or objects> : <headers> : <gristed objects>
625	# Note: Parameter 3 <gristed objects> is an extension.
626
627	local objects = [ FGristFiles $(1:S=$(SUFOBJ)) ] $(3) ;
628	local headers = $(2) ;
629
630	local file ;
631	for file in $(objects) {
632		on $(file) {
633			local localHeaders = $(HDRS) $(headers) ;
634			SYSHDRS on $(file) = $(localHeaders) ;
635
636			# reformat ASHDRS and CCHDRS
637			local fileHeaders ;
638
639			if $(PLATFORM) = host {
640				fileHeaders =
641					[ FIncludes $(localHeaders) : $(HOST_LOCAL_INCLUDES_OPTION) ]
642					$(HOST_INCLUDES_SEPARATOR)
643					[ FSysIncludes $(SYSHDRS)
644						: $(HOST_SYSTEM_INCLUDES_OPTION) ] ;
645			} else {
646				fileHeaders =
647					[ FIncludes $(localHeaders) : $(TARGET_LOCAL_INCLUDES_OPTION) ]
648					$(TARGET_INCLUDES_SEPARATOR)
649					[ FSysIncludes $(SYSHDRS)
650						: $(TARGET_SYSTEM_INCLUDES_OPTION) ] ;
651			}
652
653			ASHDRS on $(file) = $(fileHeaders) ;
654			CCHDRS on $(file) = $(fileHeaders) ;
655		}
656	}
657}
658
659# Overridden to avoid calling SubDir for a directory twice (in SubInclude
660# and from the Jamfile in the directory).
661rule SubInclude
662{
663	# SubInclude TOP d1 ... ;
664	#
665	# Include a subdirectory's Jamfile.
666
667	if ! $($(<[1]))
668	{
669	    Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ;
670	}
671
672	# Set up the config variables for the subdirectory.
673	local config = [ ConfigObject $(1) ] ;
674
675	__configured = ;
676	if ! [ on $(config) return $(__configured) ] {
677		# No custom configuration defined for the subdir. We use the variable
678		# values inherited by the closest ancestor.
679		config = $(HAIKU_INHERITED_SUBDIR_CONFIG) ;
680	}
681
682	# store SUBDIR_TOKENS
683	local oldSubDirTokens = $(SUBDIR_TOKENS) ;
684
685	on $(config) {
686		include [ FDirName $($(1[1])) $(1[2-) $(JAMFILE) ] ;
687	}
688
689	# restore SUBDIR_TOKENS
690	SUBDIR_TOKENS = $(oldSubDirTokens) ;
691}
692