xref: /haiku/build/jam/MainBuildRules (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
1rule AddSharedObjectGlueCode
2{
3	# AddSharedObjectGlueCode <target> : <isExecutable> ;
4
5	# we link with -nostdlib and add the required libs manually, when building
6	# for Haiku
7	local platform ;
8	on $(1) {
9		platform = $(PLATFORM) ;
10		if $(platform) = haiku {
11			local stdLibs = [ MultiArchDefaultGristFiles libroot.so ]
12				[ TargetLibgcc ] ;
13			local type = EXECUTABLE ;
14			if $(2) != true {
15				type = LIBRARY ;
16
17				# special case for libroot: don't link it against itself
18				if $(DONT_LINK_AGAINST_LIBROOT) {
19					stdLibs = ;
20				}
21			}
22
23			local beginGlue
24				= $(HAIKU_$(type)_BEGIN_GLUE_CODE_$(TARGET_PACKAGING_ARCH)) ;
25			local endGlue
26				= $(HAIKU_$(type)_END_GLUE_CODE_$(TARGET_PACKAGING_ARCH)) ;
27
28			LINK_BEGIN_GLUE on $(1) = $(beginGlue) ;
29			LINK_END_GLUE on $(1) = $(endGlue) ;
30
31			NEEDLIBS on $(1) = [ on $(1) return $(NEEDLIBS) ] $(stdLibs) ;
32			Depends $(1) : $(stdLibs) $(beginGlue) $(endGlue) ;
33			LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ] -nostdlib
34				-Xlinker --no-undefined ;
35		}
36	}
37
38	# link against the compatibility libraries needed for the target
39	if $(platform) != host && $(TARGET_HAIKU_COMPATIBILITY_LIBS) {
40		LinkAgainst $(1) : $(TARGET_HAIKU_COMPATIBILITY_LIBS) ;
41	}
42}
43
44rule Executable
45{
46	# Executable <name> : <sources> : <libraries> : <res> ;
47	#
48	if ! [ IsPlatformSupportedForTarget $(1) ] {
49		return ;
50	}
51
52	AddResources $(1) : $(4) ;
53	Main $(1) : $(2) ;
54	LinkAgainst $(1) : $(3) ;
55	LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
56		-Xlinker -soname=_APP_ ;
57
58	# we link with -nostdlib and add the required libs manually, when building
59	# for Haiku
60	AddSharedObjectGlueCode $(1) : true ;
61}
62
63rule Application
64{
65	# Application <name> : <sources> : <libraries> : <res> ;
66	Executable $(1) : $(2) : $(3) : $(4) ;
67}
68
69rule BinCommand
70{
71	# BinCommand <name> : <sources> : <libraries> : <res> ;
72	Executable $(1) : $(2) : $(3) : $(4) ;
73}
74
75rule StdBinCommands
76{
77	# StdBinCommands <sources> : <libs> : <res> ;
78	local libs = $(2) ;
79	local ress = $(3) ;
80	local source ;
81	for source in $(1)
82	{
83		local target = $(source:S=) ;
84
85		BinCommand $(target) : $(source) : $(libs) : $(ress) ;
86	}
87}
88
89rule Preference
90{
91	# Preference <name> : <sources> : <libraries> : <res> ;
92	Executable $(1) : $(2) : $(3) : $(4) ;
93}
94
95rule Server
96{
97	# Server <name> : <sources> : <libraries> : <res> ;
98
99	Executable $(1) : $(2) : $(3) : $(4) ;
100}
101
102rule Addon target : sources : libraries : isExecutable
103{
104	# Addon <target> : <sources> : <is executable> : <libraries> ;
105	# <target>: The add-on.
106	# <sources>: Source files.
107	# <libraries>: Libraries to be linked against.
108	# <isExecutable>: true, if the target shall be executable as well.
109
110	if ! [ IsPlatformSupportedForTarget $(target) ] {
111		return ;
112	}
113
114	Main $(target) : $(sources) ;
115
116	local linkFlags = -Xlinker -soname=\"$(target:G=)\" ;
117	if $(isExecutable) != true {
118		linkFlags = -shared $(linkFlags) ;
119	}
120	LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ] $(linkFlags) ;
121	LinkAgainst $(target) : $(libraries) ;
122
123	AddSharedObjectGlueCode $(target) : $(isExecutable) ;
124}
125
126rule Translator target : sources : libraries : isExecutable
127{
128	# Translator <target> : <sources> : <libraries> : <isExecutable> ;
129	Addon $(target) : $(sources) : $(libraries) : $(isExecutable) ;
130}
131
132rule ScreenSaver target : sources : libraries
133{
134	# ScreenSaver <target> : <sources> : <libraries> ;
135	Addon $(target) : $(sources) : $(libraries) : false ;
136}
137
138rule StaticLibrary
139{
140	# StaticLibrary <lib> : <sources> : <otherObjects> ;
141	# Creates a static library from sources.
142	# <lib>: The static library to be built.
143	# <sources>: List of source files.
144	# <otherObjects>: List of additional object files.
145	#
146	local lib = $(1) ;
147	local sources = [ FGristFiles $(2) ] ;
148	local otherObjects = $(3) ;
149	local objects = $(sources:S=$(SUFOBJ)) ;
150
151	if ! [ IsPlatformSupportedForTarget $(1) ] {
152		return ;
153	}
154
155	InheritPlatform $(objects) : $(lib) ;
156
157	if $(TARGET_CC_IS_LEGACY_GCC_$(TARGET_PACKAGING_ARCH)) = 0
158			&& [ on $(lib) return $(NO_HIDDEN_VISIBILITY) ] != 1 {
159		CCFLAGS on $(objects) += -fvisibility=hidden ;
160		C++FLAGS on $(objects) += -fvisibility=hidden ;
161	}
162
163	StaticLibraryFromObjects $(lib) : $(objects) $(otherObjects) ;
164	Objects $(2) ;
165}
166
167rule StaticLibraryFromObjects
168{
169	if ! [ IsPlatformSupportedForTarget $(1) ] {
170		return ;
171	}
172
173	LibraryFromObjects $(1) : $(2) ;
174}
175
176rule AssembleNasm
177{
178	if ! [ on $(1) return $(NASMFLAGS) ] {
179		NASMFLAGS on $(1) = -f elf32 ;
180	}
181
182	Depends $(1) : $(2) [ on $(2) return $(PLATFORM) ] ;
183}
184
185actions AssembleNasm
186{
187	if test $(ASFLAGS) ; then
188		$(HAIKU_NASM) -d $(ASFLAGS) $(NASMFLAGS) -I$(2:D)/ -o $(1) $(2) ;
189	else
190		$(HAIKU_NASM) $(NASMFLAGS) -I$(2:D)/ -o $(1) $(2) ;
191	fi
192}
193
194rule CompileDTS target : source
195{
196	CCDEFS on $(target) = [ FDefines $(TARGET_DEFINES_$(TARGET_PACKAGING_ARCH))
197		$(TARGET_DEFINES) ] ;
198	CC on $(target) = $(TARGET_CC_$(TARGET_PACKAGING_ARCH)) ;
199
200	MakeLocate $(target) : $(HAIKU_OUTPUT_DIR) ;
201	Depends $(target) : $(source) ;
202	CompileDTS1 $(target) : $(source) ;
203}
204
205actions CompileDTS1
206{
207	$(CC) -E $(CCDEFS) -P -xassembler-with-cpp \
208		-I$(HAIKU_TOP)/src/data/dts/arch/$(TARGET_ARCH) \
209		-I$(HAIKU_TOP)/src/data/dts $(2) \
210	| dtc -O dtb -o $(1) \
211		-i $(HAIKU_TOP)/src/data/dts/arch/$(TARGET_ARCH) \
212		-i $(HAIKU_TOP)/src/data/dts ;
213}
214
215rule Ld
216{
217	# Ld <name> : <objs> : <linkerscript> : <flags> ;
218	#
219	local target = $(1) ;
220	local objects = $(2) ;
221	local linkerScript = $(3) ;
222	local linkerFlags = $(4) ;
223
224	if $(linkerScript) {
225		linkerFlags += --script=$(linkerScript) ;
226	}
227
228	on $(target) {
229		if $(PLATFORM) = host {
230			LINK on $(target) = $(HOST_LD) ;
231			LINKFLAGS on $(target) = $(HOST_LDFLAGS) $(LINKFLAGS) $(linkerFlags) ;
232		} else {
233			LINK on $(target) = $(TARGET_LD_$(TARGET_PACKAGING_ARCH)) ;
234			LINKFLAGS on $(target) = $(TARGET_LDFLAGS_$(TARGET_PACKAGING_ARCH))
235				$(LINKFLAGS) $(linkerFlags) ;
236		}
237
238		NEEDLIBS on $(target) = $(NEEDLIBS) ;
239		LINKLIBS on $(target) = $(LINKLIBS) ;
240	}
241
242	LocalClean clean : $(target) ;
243	LocalDepends all : $(target) ;
244	Depends $(target) : $(objects) ;
245
246	MakeLocateDebug $(target) ;
247
248	on $(1) XRes $(1) : $(RESFILES) ;
249	if ! [ on $(1) return $(DONT_USE_BEOS_RULES) ] {
250		SetType $(1) ;
251		MimeSet $(1) ;
252		SetVersion $(1) ;
253	}
254}
255
256actions Ld
257{
258	$(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" "$(NEEDLIBS)" $(LINKLIBS)
259}
260
261rule CreateAsmStructOffsetsHeader header : source : architecture
262{
263	# CreateAsmStructOffsetsHeader header : source : architecture
264	#
265	# Grist will be added to both header and source.
266
267	header = [ FGristFiles $(header) ] ;
268	source = [ FGristFiles $(source) ] ;
269
270	TARGET_PACKAGING_ARCH on $(header) = $(architecture) ;
271
272	# find out which headers, defines, etc. to use
273	local headers ;
274	local sysHeaders ;
275	local defines ;
276	local flags ;
277	local includesSeparator ;
278	local localIncludesOption ;
279	local systemIncludesOption ;
280
281	on $(header) { # use on $(1) variable values
282		if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
283			Echo $(PLATFORM) is not in SUPPORTED_PLATFORMS, cannot make struct-offsets header! ;
284			return ;
285		}
286
287		# headers and defines
288		headers = $(HAIKU_CONFIG_HEADERS) $(SEARCH_SOURCE) $(SUBDIRHDRS)
289			$(HDRS) ;
290		sysHeaders = $(SUBDIRSYSHDRS) $(SYSHDRS) ;
291		defines = $(DEFINES) ;
292
293		if $(PLATFORM) = host {
294			sysHeaders += $(HOST_HDRS) ;
295			defines += $(HOST_DEFINES) ;
296
297			if $(USES_BE_API) {
298				sysHeaders += $(HOST_BE_API_HEADERS) ;
299			}
300		} else {
301			sysHeaders += [ FStandardHeaders $(TARGET_PACKAGING_ARCH) ]
302				$(TARGET_HDRS_$(TARGET_PACKAGING_ARCH)) ;
303			defines += $(TARGET_DEFINES_$(TARGET_PACKAGING_ARCH))
304				$(TARGET_DEFINES) ;
305		}
306
307		# optimization flags
308		if $(DEBUG) = 0 {
309			flags += $(OPTIM) ;
310		} else {
311			flags += -O0 ;
312		}
313
314		if $(PLATFORM) = host {
315			# warning flags
316			if $(WARNINGS) != 0 {
317				flags += $(HOST_WARNING_C++FLAGS) ;
318				if $(WARNINGS) = treatAsErrors {
319					flags += -Werror $(HOST_WERROR_FLAGS) ;
320				}
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 $(header) = $(HOST_C++) ;
332
333			includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;
334			localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;
335			systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;
336		} else {
337			# warning flags
338			if $(WARNINGS) != 0 {
339				flags += $(TARGET_WARNING_C++FLAGS_$(TARGET_PACKAGING_ARCH)) ;
340				if $(WARNINGS) = treatAsErrors {
341					flags += -Werror
342						$(TARGET_WERROR_FLAGS_$(TARGET_PACKAGING_ARCH)) ;
343				}
344			}
345
346			# debug and other flags
347			flags += $(TARGET_C++FLAGS_$(TARGET_PACKAGING_ARCH))
348				$(TARGET_DEBUG_$(DEBUG)_C++FLAGS_$(TARGET_PACKAGING_ARCH))
349				$(SUBDIRC++FLAGS) $(C++FLAGS) ;
350
351			C++ on $(header) = $(TARGET_C++_$(TARGET_PACKAGING_ARCH)) ;
352
353			includesSeparator
354				= $(TARGET_INCLUDES_SEPARATOR_$(TARGET_PACKAGING_ARCH)) ;
355			localIncludesOption
356				= $(TARGET_LOCAL_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;
357			systemIncludesOption
358				= $(TARGET_SYSTEM_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;
359		}
360	}
361
362	# Turn off "invalid use of offsetof()" macro warning. We use offsetof() also
363	# for non-PODs. Since we're using the same compiler for the whole kernel and
364	# don't do virtual inheritence, that works well enough.
365	flags += -Wno-invalid-offsetof ;
366		# TODO: Rather get rid of the respective offsetof() instances.
367
368	# locate object, search for source, and set on target variables
369
370	Depends $(header) : $(source) $(PLATFORM) ;
371	SEARCH on $(source) += $(SEARCH_SOURCE) ;
372	MakeLocate $(header) : [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR_$(architecture))
373		system kernel ] ;
374	LocalClean clean : $(header) ;
375
376	HDRRULE on $(source) = HdrRule ;
377	HDRSCAN on $(source) = $(HDRPATTERN) ;
378	HDRSEARCH on $(source) = $(headers) $(sysHeaders) $(STDHDRS) ;
379	HDRGRIST on $(source) = $(HDRGRIST) ;
380
381	C++FLAGS on $(header) = $(flags) ;
382	CCHDRS on $(header) = [ FIncludes $(headers) : $(localIncludesOption) ]
383		$(includesSeparator)
384		[ FSysIncludes $(sysHeaders) : $(systemIncludesOption) ] ;
385	CCDEFS on $(header) = [ FDefines $(defines) ] ;
386
387	CreateAsmStructOffsetsHeader1 $(header) : $(source) ;
388}
389
390actions CreateAsmStructOffsetsHeader1
391{
392 	$(C++) -S "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o - \
393		| $(SED) 's/@define/#define/g' | grep "#define" \
394		| $(SED) -e 's/[\$\#]\([0-9]\)/\1/' > "$(1)"
395	grep -q "#define" "$(1)"
396}
397
398rule MergeObjectFromObjects
399{
400	# MergeObjectFromObjects <name> : <objects> : <other objects> ;
401	# Merges object files to an object file.
402	# <name>: Name of the object file to create. No grist will be added.
403	# <objects>: Object files to be merged. Grist will be added.
404	# <other objects>: Object files or static libraries to be merged. No grist
405	#                  will be added.
406	#
407	local objects = [ FGristFiles $(2) ] ;
408
409	on $(1) {
410		if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
411			return ;
412		}
413
414		if $(PLATFORM) = host {
415			LINK on $(1) = $(HOST_LD) ;
416			LINKFLAGS on $(target) = $(HOST_LDFLAGS) ;
417		} else {
418			LINK on $(1) = $(TARGET_LD_$(TARGET_PACKAGING_ARCH)) ;
419			LINKFLAGS on $(target)
420				= $(TARGET_LDFLAGS_$(TARGET_PACKAGING_ARCH)) ;
421		}
422	}
423
424	MakeLocateDebug $(1) ;
425	Depends $(1) : $(objects) ;
426	Depends $(1) : $(3) ;
427	LocalDepends obj : $(1) ;
428	MergeObjectFromObjects1 $(1) : $(objects) $(3) ;
429}
430
431actions MergeObjectFromObjects1
432{
433	$(LINK) $(LINKFLAGS) -r $(2) -o $(1)
434}
435
436rule MergeObject
437{
438	# MergeObject <name> : <sources> : <other objects> ;
439	# Compiles source files and merges the object files to an object file.
440	# <name>: Name of the object file to create. No grist will be added.
441	# <sources>: Sources to be compiled. Grist will be added.
442	# <other objects>: Object files or static libraries to be merged. No grist
443	#                  will be added.
444	#
445	local target = $(1) ;
446	local sources = [ FGristFiles $(2) ] ;
447	local otherObjects = $(3) ;
448	local objects = $(sources:S=$(SUFOBJ)) ;
449
450	if ! [ IsPlatformSupportedForTarget $(1) ] {
451		return ;
452	}
453
454	InheritPlatform $(objects) : $(target) ;
455	Objects $(sources) ;
456	MergeObjectFromObjects $(target) : $(objects) : $(otherObjects) ;
457}
458
459rule SharedLibraryFromObjects
460{
461	# SharedLibraryFromObjects <lib> : <objects> : <libraries> ;
462	#
463	local _lib = $(1) ;
464
465	if ! [ IsPlatformSupportedForTarget $(1) ] {
466		return ;
467	}
468
469	local soname = [ on $(_lib) return $(HAIKU_SONAME) ] ;
470	soname ?= $(_lib:BS) ;
471
472	MainFromObjects $(_lib) : $(2) ;
473	LINKFLAGS on $(_lib) = [ on $(_lib) return $(LINKFLAGS) ]
474		-shared -Xlinker -soname=\"$(soname)\" ;
475	LinkAgainst $(_lib) : $(3) ;
476
477	AddSharedObjectGlueCode $(_lib) : false ;
478}
479
480rule SharedLibrary
481{
482	# SharedLibrary <lib> : <sources> : <libraries> : <abiVersion> ;
483	local lib = $(1) ;
484	local sources = [ FGristFiles $(2) ] ;
485	local objects = $(sources:S=$(SUFOBJ)) ;
486	local libs = $(3) ;
487	local abiVersion = $(4) ;	# major ABI (soname) version for lib (if any)
488
489	if ! [ IsPlatformSupportedForTarget $(1) ] {
490		return ;
491	}
492
493	if $(abiVersion) {
494		HAIKU_SONAME on $(lib) = $(lib:BS).$(abiVersion) ;
495		HAIKU_LIB_ABI_VERSION on $(lib) = $(abiVersion) ;
496	}
497
498	InheritPlatform $(objects) : $(lib) ;
499	Objects $(sources) ;
500	SharedLibraryFromObjects $(lib) : $(objects) : $(libs) ;
501}
502
503rule LinkAgainst
504{
505	# LinkAgainst <name> : <libs> [ : <mapLibs> ] ;
506	# Valid elements for <libs> are e.g. "be" or "libtranslation.so" or
507	# "/boot/.../libfoo.so". If the basename starts with "lib" or the thingy
508	# has a dirname or grist, it is added to the NEEDLIBS variable (i.e. the
509	# file will be bound!), otherwise it is prefixed "-l" and added to
510	# LINKLIBS. If you want to specify a target that isn't a library and
511	# also has neither grist nor a dirname, you can prepend "<nogrist>" as
512	# grist; it will be stripped by this rule.
513	# <mapLibs> specifies whether the to translate library names (e.g. "be"
514	# to "libbe.so" in case of target platform "haiku"). Defaults to "true".
515	#
516	local target = $(1) ;
517	local libs = $(2) ;
518	local mapLibs = $(3:E=true) ;
519
520	local linkLibs ;
521	local needLibs ;
522
523	on $(target) {
524		local i ;
525
526		# map libraries, if desired and target platform is Haiku
527		local map = $(TARGET_LIBRARY_NAME_MAP_$(TARGET_PACKAGING_ARCH)) ;
528		if $(PLATFORM) != host && $(mapLibs) = true && $(map) {
529			local mappedLibs ;
530
531			for i in $(libs) {
532				local mapped = $($(map)_$(i)) ;
533				mapped ?= $(i) ;
534				mappedLibs += $(mapped) ;
535			}
536
537			libs = $(mappedLibs) ;
538		}
539
540		for i in $(libs) {
541			local isfile = ;
542			if $(i:D) || $(i:G) {
543				isfile = true ;
544				if $(i:G) = <nogrist> {
545					i = $(i:G=) ;
546				}
547			} else {
548				switch $(i:B)
549				{
550					# XXX: _APP_ and _KERNEL_ should not be needed for ELF.
551					case _APP_ : isfile = true ;
552					case _KERNEL_ : isfile = true ;
553					case lib*	: isfile = true ;
554					case *	: isfile = ;
555				}
556				if ! $(isfile) && ( $(i:S) = .so || $(i:S) = .a ) {
557					isfile = true ;
558				}
559			}
560
561			if $(isfile) {
562				needLibs += $(i) ;
563			} else {
564				linkLibs += $(i) ;
565			}
566		}
567	}
568
569	# Copy in the library dependencies from any static libraries first.
570	# (We have to do the [ on ... ] outside the on { } block. )
571	for i in $(needLibs) {
572		if $(i:S) = .a  {
573			needLibs += [ on $(i) return $(NEEDLIBS) ] ;
574			linkLibs += [ on $(i) return $(LINKLIBS) ] ;
575		}
576	}
577
578	on $(target) {
579		NEEDLIBS on $(1) = $(NEEDLIBS) $(needLibs) ;
580		LINKLIBS on $(1) = $(LINKLIBS) -l$(linkLibs) ;
581
582		if $(needLibs) && ! $(NO_LIBRARY_DEPENDENCIES) {
583			Depends $(1) : $(needLibs) ;
584		}
585	}
586}
587
588rule AddResources
589{
590	# AddResources <name> : <resourcefiles> ;
591
592	# add grist to the resource files which don't have any yet
593	local resfiles ;
594	local file ;
595	for file in $(2) {
596		if ! $(file:G) {
597			file = [ FGristFiles $(file) ] ;
598		}
599		resfiles += $(file) ;
600	}
601
602	SEARCH on $(resfiles) += $(SEARCH_SOURCE) ;
603
604	for file in $(resfiles) {
605		if $(file:S) = .rdef {
606			local rdef = $(file) ;
607			file = $(rdef:S=.rsrc) ;
608			ResComp $(file) : $(rdef) ;
609		}
610		InheritPlatform $(file) : $(1) ;
611		RESFILES on $(1) += $(file) ;
612	}
613}
614
615rule SetVersionScript target : versionScript
616{
617	# SetVersionScript <target> : <versionScript>
618	#
619	# Sets the version script for <target>. Grist will be added to
620	# <versionScript> and SEARCH will be set on it.
621
622	versionScript = [ FGristFiles $(versionScript) ] ;
623
624	SEARCH on $(versionScript) += $(SEARCH_SOURCE) ;
625
626	VERSION_SCRIPT on $(target) = $(versionScript) ;
627	Depends $(target) : $(versionScript) ;
628}
629
630rule BuildPlatformObjects
631{
632	# Usage BuildPlatformObjects <sources> ;
633	# <sources> The sources.
634	#
635	local sources = [ FGristFiles $(1) ] ;
636	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
637
638	PLATFORM on $(objects) = host ;
639	SUPPORTED_PLATFORMS on $(objects) = host ;
640
641	Objects $(sources) ;
642}
643
644rule BuildPlatformMain
645{
646	# Usage BuildPlatformMain <target> : <sources> : <libraries> ;
647	# <target> The executable/library.
648	# <sources> The sources.
649	# <libraries> Libraries to link against.
650	#
651	local target = $(1) ;
652	local sources = $(2) ;
653	local libs = $(3) ;
654	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
655
656	PLATFORM on $(target) = host ;
657	SUPPORTED_PLATFORMS on $(target) = host ;
658	DONT_USE_BEOS_RULES on $(target) = true ;
659
660	local usesBeAPI = [ on $(target) return $(USES_BE_API) ] ;
661	if $(usesBeAPI) {
662		# propagate the flag to the objects
663		USES_BE_API on $(objects) = $(usesBeAPI) ;
664
665		# add the build libroot
666		local libroot = [ on $(target) return $(HOST_LIBROOT) ] ;
667		Depends $(target) : $(libroot) ;
668		NEEDLIBS on $(target) += $(libroot) ;
669	}
670
671	Main $(target) : $(sources) ;
672	LinkAgainst $(target) : $(libs) ;
673}
674
675rule BuildPlatformSharedLibrary
676{
677	# Usage BuildPlatformSharedLibrary <target> : <sources> : <libraries> ;
678	# <target> The library.
679	# <sources> The sources.
680	# <libraries> Libraries to link against.
681	#
682	local target = $(1) ;
683	local sources = $(2) ;
684	local libs = $(3) ;
685
686	BuildPlatformMain $(target) : $(sources) : $(libs) ;
687
688	if $(HOST_PLATFORM) = darwin {
689		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
690			-dynamic -dynamiclib -Xlinker -flat_namespace ;
691	} else {
692		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
693			-shared -Xlinker -soname=\"$(target:G=)\" ;
694	}
695
696	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
697	CCFLAGS on $(objects) += $(HOST_PIC_CCFLAGS) ;
698	C++FLAGS on $(objects) += $(HOST_PIC_C++FLAGS) ;
699}
700
701rule BuildPlatformMergeObject
702{
703	# BuildPlatformMergeObject <name> : <sources> : <other objects> ;
704	# Compiles source files and merges the object files to an object file.
705	# <name>: Name of the object file to create. No grist will be added.
706	# <sources>: Sources to be compiled. Grist will be added.
707	# <other objects>: Object files or static libraries to be merged. No grist
708	#                  will be added.
709	#
710	local target = $(1) ;
711	local sources = $(2) ;
712	local otherObjects = $(3) ;
713	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
714
715	PLATFORM on $(target) = host ;
716	SUPPORTED_PLATFORMS on $(target) = host ;
717
718	local usesBeAPI = [ on $(target[1]) return $(USES_BE_API) ] ;
719	if $(usesBeAPI) {
720		# propagate the flag to the objects
721		USES_BE_API on $(objects) = $(usesBeAPI) ;
722	}
723
724	MergeObject $(target) : $(sources) : $(otherObjects) ;
725}
726
727rule BuildPlatformMergeObjectPIC target : sources : otherObjects
728{
729	# BuildPlatformMergeObjectPIC <name> : <sources> : <other objects> ;
730	# Compiles source files and merges the object files to an object file.
731	# Same as BuildPlatformMergeObject rule but adds position-independent
732	# flags to the compiler (if any).
733	# <name>: Name of the object file to create. No grist will be added.
734	# <sources>: Sources to be compiled. Grist will be added.
735	# <other objects>: Object files or static libraries to be merged. No grist
736	#                  will be added.
737	#
738	ObjectCcFlags $(sources) : $(HOST_PIC_CCFLAGS) ;
739	ObjectC++Flags $(sources) : $(HOST_PIC_C++FLAGS) ;
740
741	BuildPlatformMergeObject $(target) : $(sources) : $(otherObjects) ;
742}
743
744rule BuildPlatformStaticLibrary lib : sources : otherObjects
745{
746	# BuildPlatformStaticLibrary <lib> : <sources> ;
747	# Creates a static library from sources.
748	# <lib>: The static library to be built.
749	# <sources>: List of source files.
750	# <otherObjects>: List of additional object files.
751	#
752
753	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
754
755	PLATFORM on $(lib) = host ;
756	SUPPORTED_PLATFORMS on $(lib) = host ;
757
758	local usesBeAPI = [ on $(lib) return $(USES_BE_API) ] ;
759	if $(usesBeAPI) {
760		# propagate the flag to the objects
761		USES_BE_API on $(objects) = $(usesBeAPI) ;
762	}
763
764	StaticLibrary $(lib) : $(sources) : $(otherObjects) ;
765}
766
767rule BuildPlatformStaticLibraryPIC target : sources : otherObjects
768{
769	# Like BuildPlatformStaticLibrary, but producing position independent code.
770
771	ObjectCcFlags $(sources) : $(HOST_PIC_CCFLAGS) ;
772	ObjectC++Flags $(sources) : $(HOST_PIC_C++FLAGS) ;
773
774	BuildPlatformStaticLibrary $(target) : $(sources) : $(otherObjects) ;
775}
776
777rule BootstrapStage0PlatformObjects sources : separateFromStandardSiblings
778{
779	# BootstrapStage0PlatformObjects <sources> : <separateFromStandardSiblings>
780	# Builds objects from the given sources for stage0 of the bootstrap process.
781	# <sources> The sources from which objects should be created.
782	# <separateFromStandardSiblings> Pass 'true' if the same objects are built
783	# in a different context, too, so that a separate grist and target location
784	# is required. This defaults to ''.
785	local source ;
786	for source in $(sources) {
787		local objectGrist ;
788		if $(separateFromStandardSiblings) = true {
789			objectGrist = "bootstrap!$(SOURCE_GRIST)" ;
790		} else {
791			objectGrist = $(SOURCE_GRIST) ;
792		}
793		local object = $(source:S=$(SUFOBJ):G=$(objectGrist)) ;
794		PLATFORM on $(object) = bootstrap_stage0 ;
795		SUPPORTED_PLATFORMS on $(object) = bootstrap_stage0 ;
796		if $(separateFromStandardSiblings) = true {
797			MakeLocate $(object) : [
798				FDirName $(TARGET_DEBUG_$(DEBUG)_LOCATE_TARGET) bootstrap
799			] ;
800		}
801		Object $(object) : $(source) ;
802	}
803}
804