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