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