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