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