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