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