xref: /haiku/build/jam/MainBuildRules (revision 5fae0bc1a2f74ccf56b7e3958149317d6af2cccc)
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	StaticLibraryFromObjects $(lib) : $(objects) $(otherObjects) ;
158	Objects $(2) ;
159}
160
161rule StaticLibraryFromObjects
162{
163	if ! [ IsPlatformSupportedForTarget $(1) ] {
164		return ;
165	}
166
167	LibraryFromObjects $(1) : $(2) ;
168}
169
170rule AssembleNasm
171{
172	if ! [ on $(1) return $(NASMFLAGS) ] {
173		NASMFLAGS on $(1) = -f elf32 ;
174	}
175
176	Depends $(1) : $(2) [ on $(2) return $(PLATFORM) ] ;
177}
178
179actions AssembleNasm
180{
181	if test $(ASFLAGS) ; then
182		$(HAIKU_NASM) -d $(ASFLAGS) $(NASMFLAGS) -o $(1) $(2);
183	else
184		$(HAIKU_NASM) $(NASMFLAGS) -o $(1) $(2);
185	fi
186}
187
188rule CompileDTS
189{
190	Depends $(<) : $(>) ;
191}
192
193actions CompileDTS
194{
195	dtc -O dtb -o $(1) $(2);
196}
197
198rule Ld
199{
200	# Ld <name> : <objs> : <linkerscript> : <flags> ;
201	#
202	local target = $(1) ;
203	local objects = $(2) ;
204	local linkerScript = $(3) ;
205	local linkerFlags = $(4) ;
206
207	if $(linkerScript) {
208		linkerFlags += --script=$(linkerScript) ;
209	}
210
211	on $(target) {
212		if $(PLATFORM) = host {
213			LINK on $(target) = $(HOST_LD) ;
214			LINKFLAGS on $(target) = $(HOST_LDFLAGS) $(LINKFLAGS) $(linkerFlags) ;
215		} else {
216			LINK on $(target) = $(TARGET_LD_$(TARGET_PACKAGING_ARCH)) ;
217			LINKFLAGS on $(target) = $(TARGET_LDFLAGS_$(TARGET_PACKAGING_ARCH))
218				$(LINKFLAGS) $(linkerFlags) ;
219		}
220
221		NEEDLIBS on $(target) = $(NEEDLIBS) ;
222		LINKLIBS on $(target) = $(LINKLIBS) ;
223	}
224
225	LocalClean clean : $(target) ;
226	LocalDepends all : $(target) ;
227	Depends $(target) : $(objects) ;
228
229	MakeLocateDebug $(target) ;
230
231	on $(1) XRes $(1) : $(RESFILES) ;
232	if ! [ on $(1) return $(DONT_USE_BEOS_RULES) ] {
233		SetType $(1) ;
234		MimeSet $(1) ;
235		SetVersion $(1) ;
236	}
237}
238
239actions Ld
240{
241	$(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" "$(NEEDLIBS)" $(LINKLIBS)
242}
243
244rule CreateAsmStructOffsetsHeader header : source
245{
246	# CreateAsmStructOffsetsHeader header : source
247	#
248	# Grist will be added to both header and source.
249
250	header = [ FGristFiles $(header) ] ;
251	source = [ FGristFiles $(source) ] ;
252
253	# find out which headers, defines, etc. to use
254	local headers ;
255	local sysHeaders ;
256	local defines ;
257	local flags ;
258	local includesSeparator ;
259	local localIncludesOption ;
260	local systemIncludesOption ;
261
262	on $(header) { # use on $(1) variable values
263		if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
264			return ;
265		}
266
267		# headers and defines
268		headers = $(HAIKU_CONFIG_HEADERS) $(SEARCH_SOURCE) $(SUBDIRHDRS)
269			$(HDRS) ;
270		sysHeaders = $(SUBDIRSYSHDRS) $(SYSHDRS) ;
271		defines = $(DEFINES) ;
272
273		if $(PLATFORM) = host {
274			sysHeaders += $(HOST_HDRS) ;
275			defines += $(HOST_DEFINES) ;
276
277			if $(USES_BE_API) {
278				sysHeaders += $(HOST_BE_API_HEADERS) ;
279			}
280
281		} else {
282			sysHeaders += [ FStandardHeaders $(TARGET_PACKAGING_ARCH) ]
283				$(TARGET_HDRS_$(TARGET_PACKAGING_ARCH)) ;
284			defines += $(TARGET_DEFINES_$(TARGET_PACKAGING_ARCH))
285				$(TARGET_DEFINES) ;
286		}
287
288		# optimization flags
289		if $(DEBUG) = 0 {
290			flags += $(OPTIM) ;
291		} else {
292			flags += -O0 ;
293		}
294
295		if $(PLATFORM) = host {
296			# warning flags
297			if $(WARNINGS) != 0 {
298				flags += $(HOST_WARNING_C++FLAGS) ;
299				if $(WARNINGS) = treatAsErrors {
300					flags += -Werror $(HOST_WERROR_FLAGS) ;
301				}
302			}
303
304			# debug and other flags
305			flags += $(HOST_C++FLAGS) $(HOST_DEBUG_$(DEBUG)_C++FLAGS)
306				$(SUBDIRC++FLAGS) $(C++FLAGS) ;
307
308			if $(USES_BE_API) {
309				flags += $(HOST_BE_API_C++FLAGS) ;
310			}
311
312			C++ on $(header) = $(HOST_C++) ;
313
314			includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;
315			localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;
316			systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;
317
318		} else {
319			# warning flags
320			if $(WARNINGS) != 0 {
321				flags += $(TARGET_WARNING_C++FLAGS_$(TARGET_PACKAGING_ARCH)) ;
322				if $(WARNINGS) = treatAsErrors {
323					flags += -Werror
324						$(TARGET_WERROR_FLAGS_$(TARGET_PACKAGING_ARCH)) ;
325				}
326			}
327
328			# debug and other flags
329			flags += $(TARGET_C++FLAGS_$(TARGET_PACKAGING_ARCH))
330				$(TARGET_DEBUG_$(DEBUG)_C++FLAGS_$(TARGET_PACKAGING_ARCH))
331				$(SUBDIRC++FLAGS) $(C++FLAGS) ;
332
333			C++ on $(header) = $(TARGET_C++_$(TARGET_PACKAGING_ARCH)) ;
334
335			includesSeparator
336				= $(TARGET_INCLUDES_SEPARATOR_$(TARGET_PACKAGING_ARCH)) ;
337			localIncludesOption
338				= $(TARGET_LOCAL_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;
339			systemIncludesOption
340				= $(TARGET_SYSTEM_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;
341		}
342	}
343
344	# Turn off "invalid use of offsetof()" macro warning. We use offsetof() also
345	# for non-PODs. Since we're using the same compiler for the whole kernel and
346	# don't do virtual inheritence, that works well enough.
347	flags += -Wno-invalid-offsetof ;
348		# TODO: Rather get rid of the respective offsetof() instances.
349
350	# locate object, search for source, and set on target variables
351
352	Depends $(header) : $(source) $(PLATFORM) ;
353	SEARCH on $(source) += $(SEARCH_SOURCE) ;
354	MakeLocateArch $(header) ;
355	LocalClean clean : $(header) ;
356
357	HDRRULE on $(source) = HdrRule ;
358	HDRSCAN on $(source) = $(HDRPATTERN) ;
359	HDRSEARCH on $(source) = $(headers) $(sysHeaders) $(STDHDRS) ;
360	HDRGRIST on $(source) = $(HDRGRIST) ;
361
362	C++FLAGS on $(header) = $(flags) ;
363	CCHDRS on $(header) = [ FIncludes $(headers) : $(localIncludesOption) ]
364		$(includesSeparator)
365		[ FSysIncludes $(sysHeaders) : $(systemIncludesOption) ] ;
366	CCDEFS on $(header) = [ FDefines $(defines) ] ;
367
368	CreateAsmStructOffsetsHeader1 $(header) : $(source) ;
369}
370
371actions CreateAsmStructOffsetsHeader1
372{
373 	$(C++) -S "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o - \
374		| grep "#define" | sed -e 's/[\$\#]\([0-9]\)/\1/' > "$(1)"
375}
376
377rule MergeObjectFromObjects
378{
379	# MergeObjectFromObjects <name> : <objects> : <other objects> ;
380	# Merges object files to an object file.
381	# <name>: Name of the object file to create. No grist will be added.
382	# <objects>: Object files to be merged. Grist will be added.
383	# <other objects>: Object files or static libraries to be merged. No grist
384	#                  will be added.
385	#
386	local objects = [ FGristFiles $(2) ] ;
387
388	on $(1) {
389		if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
390			return ;
391		}
392
393		if $(PLATFORM) = host {
394			LINK on $(1) = $(HOST_LD) ;
395			LINKFLAGS on $(target) = $(HOST_LDFLAGS) ;
396		} else {
397			LINK on $(1) = $(TARGET_LD_$(TARGET_PACKAGING_ARCH)) ;
398			LINKFLAGS on $(target)
399				= $(TARGET_LDFLAGS_$(TARGET_PACKAGING_ARCH)) ;
400		}
401	}
402
403	MakeLocateDebug $(1) ;
404	Depends $(1) : $(objects) ;
405	Depends $(1) : $(3) ;
406	LocalDepends obj : $(1) ;
407	MergeObjectFromObjects1 $(1) : $(objects) $(3) ;
408}
409
410actions MergeObjectFromObjects1
411{
412	$(LINK) $(LINKFLAGS) -r $(2) -o $(1) ;
413}
414
415rule MergeObject
416{
417	# MergeObject <name> : <sources> : <other objects> ;
418	# Compiles source files and merges the object files to an object file.
419	# <name>: Name of the object file to create. No grist will be added.
420	# <sources>: Sources to be compiled. Grist will be added.
421	# <other objects>: Object files or static libraries to be merged. No grist
422	#                  will be added.
423	#
424	local target = $(1) ;
425	local sources = [ FGristFiles $(2) ] ;
426	local otherObjects = $(3) ;
427	local objects = $(sources:S=$(SUFOBJ)) ;
428
429	if ! [ IsPlatformSupportedForTarget $(1) ] {
430		return ;
431	}
432
433	InheritPlatform $(objects) : $(target) ;
434	Objects $(sources) ;
435	MergeObjectFromObjects $(target) : $(objects) : $(otherObjects) ;
436}
437
438rule SharedLibraryFromObjects
439{
440	# SharedLibraryFromObjects <lib> : <objects> : <libraries> ;
441	#
442	local _lib = $(1) ;
443
444	if ! [ IsPlatformSupportedForTarget $(1) ] {
445		return ;
446	}
447
448	local soname = [ on $(_lib) return $(HAIKU_SONAME) ] ;
449	soname ?= $(_lib:BS) ;
450
451	MainFromObjects $(_lib) : $(2) ;
452	LINKFLAGS on $(_lib) = [ on $(_lib) return $(LINKFLAGS) ]
453		-shared -Xlinker -soname=\"$(soname)\" ;
454	LinkAgainst $(_lib) : $(3) ;
455
456	AddSharedObjectGlueCode $(_lib) : false ;
457}
458
459rule SharedLibrary
460{
461	# SharedLibrary <lib> : <sources> : <libraries> : <abiVersion> ;
462	local lib = $(1) ;
463	local sources = [ FGristFiles $(2) ] ;
464	local objects = $(sources:S=$(SUFOBJ)) ;
465	local libs = $(3) ;
466	local abiVersion = $(4) ;	# major ABI (soname) version for lib (if any)
467
468	if ! [ IsPlatformSupportedForTarget $(1) ] {
469		return ;
470	}
471
472	if $(abiVersion) {
473		HAIKU_SONAME on $(lib) = $(lib:BS).$(abiVersion) ;
474		HAIKU_LIB_ABI_VERSION on $(lib) = $(abiVersion) ;
475	}
476
477	InheritPlatform $(objects) : $(lib) ;
478	Objects $(sources) ;
479	SharedLibraryFromObjects $(lib) : $(objects) : $(libs) ;
480}
481
482rule LinkAgainst
483{
484	# LinkAgainst <name> : <libs> [ : <mapLibs> ] ;
485	# Valid elements for <libs> are e.g. "be" or "libtranslation.so" or
486	# "/boot/.../libfoo.so". If the basename starts with "lib" or the thingy
487	# has a dirname or grist, it is added to the NEEDLIBS variable (i.e. the
488	# file will be bound!), otherwise it is prefixed "-l" and added to
489	# LINKLIBS. If you want to specify a target that isn't a library and
490	# also has neither grist nor a dirname, you can prepend "<nogrist>" as
491	# grist; it will be stripped by this rule.
492	# <mapLibs> specifies whether the to translate library names (e.g. "be"
493	# to "libbe.so" in case of target platform "haiku"). Defaults to "true".
494	#
495	local target = $(1) ;
496	local libs = $(2) ;
497	local mapLibs = $(3:E=true) ;
498
499	on $(target) {
500		local i ;
501
502		# map libraries, if desired and target platform is Haiku
503		local map = $(TARGET_LIBRARY_NAME_MAP_$(TARGET_PACKAGING_ARCH)) ;
504		if $(PLATFORM) != host && $(mapLibs) = true && $(map) {
505			local mappedLibs ;
506
507			for i in $(libs) {
508				local mapped = $($(map)_$(i)) ;
509				mapped ?= $(i) ;
510				mappedLibs += $(mapped) ;
511			}
512
513			libs = $(mappedLibs) ;
514		}
515
516		local linkLibs ;
517		local needLibs ;
518
519		for i in $(libs)
520		{
521			local isfile = ;
522			if $(i:D) || $(i:G) {
523				isfile = true ;
524				if $(i:G) = <nogrist> {
525					i = $(i:G=) ;
526				}
527			} else {
528				switch $(i:B)
529				{
530					# XXX: _APP_ and _KERNEL_ should not be needed for ELF.
531					case _APP_ : isfile = true ;
532					case _KERNEL_ : isfile = true ;
533					case lib*	: isfile = true ;
534					case *	: isfile = ;
535				}
536				if ! $(isfile) && ( $(i:S) = .so || $(i:S) = .a ) {
537					isfile = true ;
538				}
539			}
540
541			if $(isfile) {
542				needLibs += $(i) ;
543			} else {
544				linkLibs += $(i) ;
545			}
546		}
547
548		NEEDLIBS on $(1) = $(NEEDLIBS) $(needLibs) ;
549		LINKLIBS on $(1) = $(LINKLIBS) -l$(linkLibs) ;
550
551		if $(needLibs) && ! $(NO_LIBRARY_DEPENDENCIES) {
552			Depends $(1) : $(needLibs) ;
553		}
554	}
555}
556
557rule AddResources
558{
559	# AddResources <name> : <resourcefiles> ;
560
561	# add grist to the resource files which don't have any yet
562	local resfiles ;
563	local file ;
564	for file in $(2) {
565		if ! $(file:G) {
566			file = [ FGristFiles $(file) ] ;
567		}
568		resfiles += $(file) ;
569	}
570
571	SEARCH on $(resfiles) += $(SEARCH_SOURCE) ;
572
573	for file in $(resfiles) {
574		if $(file:S) = .rdef {
575			local rdef = $(file) ;
576			file = $(rdef:S=.rsrc) ;
577			ResComp $(file) : $(rdef) ;
578		}
579		InheritPlatform $(file) : $(1) ;
580		RESFILES on $(1) += $(file) ;
581	}
582}
583
584rule SetVersionScript target : versionScript
585{
586	# SetVersionScript <target> : <versionScript>
587	#
588	# Sets the version script for <target>. Grist will be added to
589	# <versionScript> and SEARCH will be set on it.
590
591	versionScript = [ FGristFiles $(versionScript) ] ;
592
593	SEARCH on $(versionScript) += $(SEARCH_SOURCE) ;
594
595	VERSION_SCRIPT on $(target) = $(versionScript) ;
596	Depends $(target) : $(versionScript) ;
597}
598
599rule BuildPlatformObjects
600{
601	# Usage BuildPlatformObjects <sources> ;
602	# <sources> The sources.
603	#
604	local sources = [ FGristFiles $(1) ] ;
605	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
606
607	PLATFORM on $(objects) = host ;
608	SUPPORTED_PLATFORMS on $(objects) = host ;
609
610	Objects $(sources) ;
611}
612
613actions CygwinExtensionFix
614{
615	if test -f $(1).exe ; then
616		rm -f $(1)
617		mv $(1).exe $(1)
618	fi
619}
620
621rule BuildPlatformMain
622{
623	# Usage BuildPlatformMain <target> : <sources> : <libraries> ;
624	# <target> The executable/library.
625	# <sources> The sources.
626	# <libraries> Libraries to link against.
627	#
628	local target = $(1) ;
629	local sources = $(2) ;
630	local libs = $(3) ;
631	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
632
633	PLATFORM on $(target) = host ;
634	SUPPORTED_PLATFORMS on $(target) = host ;
635	DONT_USE_BEOS_RULES on $(target) = true ;
636
637	local usesBeAPI = [ on $(target) return $(USES_BE_API) ] ;
638	if $(usesBeAPI) {
639		# propagate the flag to the objects
640		USES_BE_API on $(objects) = $(usesBeAPI) ;
641
642		# add the build libroot
643		if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
644			local libroot = [ on $(target) return $(HOST_LIBROOT) ] ;
645			Depends $(target) : $(libroot) ;
646			NEEDLIBS on $(target) += $(libroot) ;
647		}
648	}
649
650	Main $(target) : $(sources) ;
651	LinkAgainst $(target) : $(libs) ;
652	if $(HOST_PLATFORM) = cygwin {
653		# Cygwin gcc adds the ".exe" extension. We cannot force
654		# jam to use SUFEXE as haiku target executables are not
655		# supposed to have this extension, thus finding
656		# dependencies will fail for these.
657		# The hack is to remove the extension after a successful
658		# build of the Target.
659		CygwinExtensionFix $(target) ;
660	}
661}
662
663rule BuildPlatformSharedLibrary
664{
665	# Usage BuildPlatformSharedLibrary <target> : <sources> : <libraries> ;
666	# <target> The library.
667	# <sources> The sources.
668	# <libraries> Libraries to link against.
669	#
670	local target = $(1) ;
671	local sources = $(2) ;
672	local libs = $(3) ;
673
674	BuildPlatformMain $(target) : $(sources) : $(libs) ;
675
676	if $(HOST_PLATFORM) = darwin {
677		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
678			-dynamic -dynamiclib -Xlinker -flat_namespace ;
679	} else if $(HOST_PLATFORM) = cygwin {
680		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
681			-shared -Xlinker --allow-multiple-definition ;
682	} else {
683		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
684			-shared -Xlinker -soname=\"$(target:G=)\" ;
685	}
686
687    local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
688	CCFLAGS on $(objects) += $(HOST_PIC_CCFLAGS) ;
689	C++FLAGS on $(objects) += $(HOST_PIC_C++FLAGS) ;
690}
691
692rule BuildPlatformMergeObject
693{
694	# BuildPlatformMergeObject <name> : <sources> : <other objects> ;
695	# Compiles source files and merges the object files to an object file.
696	# <name>: Name of the object file to create. No grist will be added.
697	# <sources>: Sources to be compiled. Grist will be added.
698	# <other objects>: Object files or static libraries to be merged. No grist
699	#                  will be added.
700	#
701	local target = $(1) ;
702	local sources = $(2) ;
703	local otherObjects = $(3) ;
704	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
705
706	PLATFORM on $(target) = host ;
707	SUPPORTED_PLATFORMS on $(target) = host ;
708
709	local usesBeAPI = [ on $(target[1]) return $(USES_BE_API) ] ;
710	if $(usesBeAPI) {
711		# propagate the flag to the objects
712		USES_BE_API on $(objects) = $(usesBeAPI) ;
713	}
714
715	MergeObject $(target) : $(sources) : $(otherObjects) ;
716}
717
718rule BuildPlatformMergeObjectPIC target : sources : otherObjects
719{
720	# BuildPlatformMergeObjectPIC <name> : <sources> : <other objects> ;
721	# Compiles source files and merges the object files to an object file.
722	# Same as BuildPlatformMergeObject rule but adds position-independent
723	# flags to the compiler (if any).
724	# <name>: Name of the object file to create. No grist will be added.
725	# <sources>: Sources to be compiled. Grist will be added.
726	# <other objects>: Object files or static libraries to be merged. No grist
727	#                  will be added.
728	#
729	ObjectCcFlags $(sources) : $(HOST_PIC_CCFLAGS) ;
730	ObjectC++Flags $(sources) : $(HOST_PIC_C++FLAGS) ;
731
732	BuildPlatformMergeObject $(target) : $(sources) : $(otherObjects) ;
733}
734
735rule BuildPlatformStaticLibrary lib : sources : otherObjects
736{
737	# BuildPlatformStaticLibrary <lib> : <sources> ;
738	# Creates a static library from sources.
739	# <lib>: The static library to be built.
740	# <sources>: List of source files.
741	# <otherObjects>: List of additional object files.
742	#
743
744	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
745
746	PLATFORM on $(lib) = host ;
747	SUPPORTED_PLATFORMS on $(lib) = host ;
748
749	local usesBeAPI = [ on $(lib) return $(USES_BE_API) ] ;
750	if $(usesBeAPI) {
751		# propagate the flag to the objects
752		USES_BE_API on $(objects) = $(usesBeAPI) ;
753	}
754
755	StaticLibrary $(lib) : $(sources) : $(otherObjects) ;
756}
757
758rule BuildPlatformStaticLibraryPIC target : sources : otherObjects
759{
760	# Like BuildPlatformStaticLibrary, but producing position independent code.
761
762	ObjectCcFlags $(sources) : $(HOST_PIC_CCFLAGS) ;
763	ObjectC++Flags $(sources) : $(HOST_PIC_C++FLAGS) ;
764
765	BuildPlatformStaticLibrary $(target) : $(sources) : $(otherObjects) ;
766}
767
768rule BootstrapStage0PlatformObjects sources : separateFromStandardSiblings
769{
770	# BootstrapStage0PlatformObjects <sources> : <separateFromStandardSiblings>
771	# Builds objects from the given sources for stage0 of the bootstrap process.
772	# <sources> The sources from which objects should be created.
773	# <separateFromStandardSiblings> Pass 'true' if the same objects are built
774	# in a different context, too, so that a separate grist and target location
775	# is required. This defaults to ''.
776	local source ;
777	for source in $(sources) {
778		local objectGrist ;
779		if $(separateFromStandardSiblings) = true {
780			objectGrist = "bootstrap!$(SOURCE_GRIST)" ;
781		} else {
782			objectGrist = $(SOURCE_GRIST) ;
783		}
784		local object = $(source:S=$(SUFOBJ):G=$(objectGrist)) ;
785		PLATFORM on $(object) = bootstrap_stage0 ;
786		SUPPORTED_PLATFORMS on $(object) = bootstrap_stage0 ;
787		if $(separateFromStandardSiblings) = true {
788			MakeLocate $(object) : [
789				FDirName $(TARGET_DEBUG_$(DEBUG)_LOCATE_TARGET) bootstrap
790			] ;
791		}
792		Object $(object) : $(source) ;
793	}
794}
795