xref: /haiku/build/jam/MainBuildRules (revision 1e36cfc2721ef13a187c6f7354dc9cbc485e89d3)
1
2rule AddSharedObjectGlueCode
3{
4	# AddSharedObjectGlueCode <target> : <isExecutable> ;
5
6	# we link with -nostdlib and add the required libs manually, when building
7	# for Haiku
8	local platform ;
9	on $(1) {
10		platform = $(PLATFORM) ;
11		if $(platform) = haiku {
12			local stdLibs = libroot.so ;
13			local beginGlue ;
14			local endGlue ;
15			if $(2) = true {
16				beginGlue += $(HAIKU_EXECUTABLE_BEGIN_GLUE_CODE) ;
17				endGlue += $(HAIKU_EXECUTABLE_END_GLUE_CODE) ;
18			} else {
19				beginGlue += $(HAIKU_LIBRARY_BEGIN_GLUE_CODE) ;
20				endGlue += $(HAIKU_LIBRARY_END_GLUE_CODE) ;
21
22				# special case for libroot: don't link it against itself
23				if $(DONT_LINK_AGAINST_LIBROOT) {
24					stdLibs = ;
25				}
26			}
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		}
35	}
36
37	# link against the compatibility libraries needed for the target
38	if $(platform) != host && $(TARGET_HAIKU_COMPATIBILITY_LIBS) {
39		LinkAgainst $(1) : $(TARGET_HAIKU_COMPATIBILITY_LIBS) ;
40	}
41}
42
43rule Executable
44{
45	# Executable <name> : <sources> : <libraries> : <res> ;
46	#
47	if ! [ IsPlatformSupportedForTarget $(1) ] {
48		return ;
49	}
50
51	AddResources $(1) : $(4) ;
52	Main $(1) : $(2) ;
53	LinkAgainst $(1) : $(3) ;
54	LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
55		-Xlinker -soname=_APP_ ;
56
57	# we link with -nostdlib and add the required libs manually, when building
58	# for Haiku
59	AddSharedObjectGlueCode $(1) : true ;
60}
61
62rule Application
63{
64	# Application <name> : <sources> : <libraries> : <res> ;
65	Executable $(1) : $(2) : $(3) : $(4) ;
66}
67
68rule BinCommand
69{
70	# BinCommand <name> : <sources> : <libraries> : <res> ;
71	Executable $(1) : $(2) : $(3) : $(4) ;
72}
73
74rule StdBinCommands
75{
76	# StdBinCommands <sources> : <libs> : <res> ;
77	local libs = $(2) ;
78	local ress = $(3) ;
79	local source ;
80	for source in $(1)
81	{
82		local target = $(source:S=) ;
83
84		BinCommand $(target) : $(source) : $(libs) : $(ress) ;
85	}
86}
87
88rule Preference
89{
90	# Preference <name> : <sources> : <libraries> : <res> ;
91	Executable $(1) : $(2) : $(3) : $(4) ;
92}
93
94rule Server
95{
96	# Server <name> : <sources> : <libraries> : <res> ;
97
98	Executable $(1) : $(2) : $(3) : $(4) ;
99}
100
101rule Addon target : sources : libraries : isExecutable
102{
103	# Addon <target> : <sources> : <is executable> : <libraries> ;
104	# <target>: The add-on.
105	# <sources>: Source files.
106	# <libraries>: Libraries to be linked against.
107	# <isExecutable>: true, if the target shall be executable as well.
108
109	if ! [ IsPlatformSupportedForTarget $(target) ] {
110		return ;
111	}
112
113	Main $(target) : $(sources) ;
114
115	local linkFlags = -Xlinker -soname=\"$(target:G=)\" ;
116	if $(isExecutable) != true {
117		linkFlags = -nostart $(linkFlags) ;
118	}
119	LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ] $(linkFlags) ;
120	LinkAgainst $(target) : $(libraries) ;
121
122	AddSharedObjectGlueCode $(target) : $(isExecutable) ;
123}
124
125rule Translator target : sources : libraries : isExecutable
126{
127	# Translator <target> : <sources> : <libraries> : <isExecutable> ;
128	Addon $(target) : $(sources) : $(libraries) : $(isExecutable) ;
129}
130
131rule ScreenSaver target : sources : libraries
132{
133	# ScreenSaver <target> : <sources> : <libraries> ;
134	Addon $(target) : $(sources) : $(libraries) : false ;
135}
136
137rule StaticLibrary
138{
139	# StaticLibrary <lib> : <sources> : <otherObjects> ;
140	# Creates a static library from sources.
141	# <lib>: The static library to be built.
142	# <sources>: List of source files.
143	# <otherObjects>: List of additional object files.
144	#
145	local lib = $(1) ;
146	local sources = [ FGristFiles $(2) ] ;
147	local otherObjects = $(3) ;
148	local objects = $(sources:S=$(SUFOBJ)) ;
149
150	if ! [ IsPlatformSupportedForTarget $(1) ] {
151		return ;
152	}
153
154	InheritPlatform $(objects) : $(lib) ;
155
156	StaticLibraryFromObjects $(lib) : $(objects) $(otherObjects) ;
157	Objects $(2) ;
158}
159
160rule StaticLibraryFromObjects
161{
162	if ! [ IsPlatformSupportedForTarget $(1) ] {
163		return ;
164	}
165
166	LibraryFromObjects $(1) : $(2) ;
167}
168
169rule Ld
170{
171	# Ld <name> : <objs> : <linkerscript> : <flags> ;
172	#
173	local target = $(1) ;
174	local objects = $(2) ;
175	local linkerScript = $(3) ;
176	local linkerFlags = $(4) ;
177
178	if $(linkerScript) {
179		linkerFlags += --script=$(linkerScript) ;
180	}
181
182	on $(target) {
183		if $(PLATFORM) = host {
184			LINK on $(target) = $(HOST_LD) ;
185			LINKFLAGS on $(target) = $(HOST_LDFLAGS) $(LINKFLAGS) $(linkerFlags) ;
186		} else {
187			LINK on $(target) = $(TARGET_LD) ;
188			LINKFLAGS on $(target) = $(TARGET_LDFLAGS) $(LINKFLAGS)
189				$(linkerFlags) ;
190		}
191
192		NEEDLIBS on $(target) = $(NEEDLIBS) ;
193		LINKLIBS on $(target) = $(LINKLIBS) ;
194	}
195
196	LocalClean clean : $(target) ;
197	LocalDepends all : $(target) ;
198	Depends $(target) : $(objects) ;
199
200	MakeLocateDebug $(target) ;
201}
202
203actions Ld
204{
205	$(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" "$(NEEDLIBS)" $(LINKLIBS)
206}
207
208
209rule MergeObjectFromObjects
210{
211	# MergeObjectFromObjects <name> : <objects> : <other objects> ;
212	# Merges object files to an object file.
213	# <name>: Name of the object file to create. No grist will be added.
214	# <objects>: Object files to be merged. Grist will be added.
215	# <other objects>: Object files or static libraries to be merged. No grist
216	#                  will be added.
217	#
218	local objects = [ FGristFiles $(2) ] ;
219
220	on $(1) {
221		if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
222			return ;
223		}
224
225		if $(PLATFORM) = host {
226			LINK on $(1) = $(HOST_LD) ;
227		} else {
228			LINK on $(1) = $(TARGET_LD) ;
229		}
230	}
231
232	MakeLocateDebug $(1) ;
233	Depends $(1) : $(objects) ;
234	Depends $(1) : $(3) ;
235	LocalDepends obj : $(1) ;
236	MergeObjectFromObjects1 $(1) : $(objects) $(3) ;
237}
238
239actions MergeObjectFromObjects1
240{
241	$(LINK) -r $(2) -o $(1) ;
242}
243
244rule MergeObject
245{
246	# MergeObject <name> : <sources> : <other objects> ;
247	# Compiles source files and merges the object files to an object file.
248	# <name>: Name of the object file to create. No grist will be added.
249	# <sources>: Sources to be compiled. Grist will be added.
250	# <other objects>: Object files or static libraries to be merged. No grist
251	#                  will be added.
252	#
253	local target = $(1) ;
254	local sources = [ FGristFiles $(2) ] ;
255	local otherObjects = $(3) ;
256	local objects = $(sources:S=$(SUFOBJ)) ;
257
258	if ! [ IsPlatformSupportedForTarget $(1) ] {
259		return ;
260	}
261
262	InheritPlatform $(objects) : $(target) ;
263	Objects $(sources) ;
264	MergeObjectFromObjects $(target) : $(objects) : $(otherObjects) ;
265}
266
267rule SharedLibraryFromObjects
268{
269	# SharedLibraryFromObjects <lib> : <objects> : <libraries> ;
270	#
271	local _lib = $(1) ;
272
273	if ! [ IsPlatformSupportedForTarget $(1) ] {
274		return ;
275	}
276
277	MainFromObjects $(_lib) : $(2) ;
278	LINKFLAGS on $(_lib) = [ on $(_lib) return $(LINKFLAGS) ]
279						   -nostart -Xlinker -soname=\"$(_lib:G=)\" ;
280	LinkAgainst $(_lib) : $(3) ;
281
282	AddSharedObjectGlueCode $(_lib) : false ;
283}
284
285rule SharedLibrary
286{
287	# SharedLibrary <lib> : <sources> : <libraries> ;
288	local lib = $(1) ;
289	local sources = [ FGristFiles $(2) ] ;
290	local objects = $(sources:S=$(SUFOBJ)) ;
291	local libs = $(3) ;
292
293	if ! [ IsPlatformSupportedForTarget $(1) ] {
294		return ;
295	}
296
297	InheritPlatform $(objects) : $(lib) ;
298	Objects $(sources) ;
299	SharedLibraryFromObjects $(lib) : $(objects) : $(libs) ;
300}
301
302rule LinkAgainst
303{
304	# LinkAgainst <name> : <libs> [ : <mapLibs> ] ;
305	# Valid elements for <libs> are e.g. "be" or "libtranslation.so" or
306	# "/boot/.../libfoo.so". If the basename starts with "lib" or the thingy
307	# has a dirname or grist, it is added to the NEEDLIBS variable (i.e. the
308	# file will be bound!), otherwise it is prefixed "-l" and added to
309	# LINKLIBS. If you want to specify a target that isn't a library and
310	# also has neither grist nor a dirname, you can prepend "<nogrist>" as
311	# grist; it will be stripped by this rule.
312	# <mapLibs> specifies whether the to translate library names (e.g. "be"
313	# to "libbe.so" in case of target platform "haiku"). Defaults to "true".
314	#
315	local target = $(1) ;
316	local libs = $(2) ;
317	local mapLibs = $(3:E=true) ;
318
319	on $(target) {
320		# map libraries, if desired and target platform is Haiku
321		if $(PLATFORM) != host && $(mapLibs) = true
322				&& $(TARGET_LIBRARY_NAME_MAP) {
323			local mappedLibs ;
324
325			for i in $(libs) {
326				local mapped = $($(TARGET_LIBRARY_NAME_MAP)_$(i)) ;
327				mapped ?= $(i) ;
328				mappedLibs += $(mapped) ;
329			}
330
331			libs = $(mappedLibs) ;
332		}
333
334		local linkLibs ;
335		local needLibs ;
336
337		for i in $(libs)
338		{
339			local isfile = ;
340			if $(i:D) || $(i:G) {
341				isfile = true ;
342				if $(i:G) = <nogrist> {
343					i = $(i:G=) ;
344				}
345			} else {
346				switch $(i:B)
347				{
348					# XXX: _APP_ and _KERNEL_ should not be needed for ELF.
349					case _APP_ : isfile = true ;
350					case _KERNEL_ : isfile = true ;
351					case lib*	: isfile = true ;
352					case *	: isfile = ;
353				}
354				if ! $(isfile) && ( $(i:S) = .so || $(i:S) = .a ) {
355					isfile = true ;
356				}
357			}
358
359			if $(isfile) {
360				needLibs += $(i) ;
361			} else {
362				linkLibs += $(i) ;
363			}
364		}
365
366		NEEDLIBS on $(1) = $(NEEDLIBS) $(needLibs) ;
367		LINKLIBS on $(1) = $(LINKLIBS) -l$(linkLibs) ;
368
369		if $(needLibs) && ! $(NO_LIBRARY_DEPENDENCIES) {
370			Depends $(1) : $(needLibs) ;
371		}
372	}
373}
374
375rule AddResources
376{
377	# AddResources <name> : <resourcefiles> ;
378
379	# add grist to the resource files which don't have any yet
380	local resfiles ;
381	local file ;
382	for file in $(2) {
383		if ! $(file:G) {
384			file = [ FGristFiles $(file) ] ;
385		}
386		resfiles += $(file) ;
387	}
388
389	SEARCH on $(resfiles) += $(SEARCH_SOURCE) ;
390
391	for file in $(resfiles) {
392		if $(file:S) = .rdef {
393			local rdef = $(file) ;
394			file = $(rdef:S=.rsrc) ;
395			ResComp $(file) : $(rdef) ;
396		}
397		InheritPlatform $(file) : $(1) ;
398		RESFILES on $(1) += $(file) ;
399	}
400}
401
402rule BuildPlatformObjects
403{
404	# Usage BuildPlatformObjects <sources> ;
405	# <sources> The sources.
406	#
407	local sources = [ FGristFiles $(1) ] ;
408	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
409
410	PLATFORM on $(objects) = host ;
411	SUPPORTED_PLATFORMS on $(objects) = host ;
412
413	Objects $(sources) ;
414}
415
416rule BuildPlatformMain
417{
418	# Usage BuildPlatformMain <target> : <sources> : <libraries> ;
419	# <target> The executable/library.
420	# <sources> The sources.
421	# <libraries> Libraries to link against.
422	#
423	local target = $(1) ;
424	local sources = $(2) ;
425	local libs = $(3) ;
426	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
427
428	PLATFORM on $(target) = host ;
429	SUPPORTED_PLATFORMS on $(target) = host ;
430	DONT_USE_BEOS_RULES on $(target) = true ;
431
432	local usesBeAPI = [ on $(target) return $(USES_BE_API) ] ;
433	if $(usesBeAPI) {
434		# propagate the flag to the objects
435		USES_BE_API on $(objects) = $(usesBeAPI) ;
436
437		# add the build libroot
438		if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
439			Depends $(target) : $(HOST_LIBROOT) ;
440			NEEDLIBS on $(target) += $(HOST_LIBROOT) ;
441		}
442	}
443
444	Main $(target) : $(sources) ;
445	LinkAgainst $(target) : $(libs) ;
446}
447
448rule BuildPlatformSharedLibrary
449{
450	# Usage BuildPlatformSharedLibrary <target> : <sources> : <libraries> ;
451	# <target> The library.
452	# <sources> The sources.
453	# <libraries> Libraries to link against.
454	#
455	local target = $(1) ;
456	local sources = $(2) ;
457	local libs = $(3) ;
458
459	BuildPlatformMain $(target) : $(sources) : $(libs) ;
460
461	if $(HOST_PLATFORM) = darwin {
462		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
463			-dynamic -dynamiclib -Xlinker -flat_namespace ;
464	} else {
465		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
466			-shared -Xlinker -soname=\"$(target:G=)\" ;
467	}
468}
469
470rule BuildPlatformMergeObject
471{
472	# BuildPlatformMergeObject <name> : <sources> : <other objects> ;
473	# Compiles source files and merges the object files to an object file.
474	# <name>: Name of the object file to create. No grist will be added.
475	# <sources>: Sources to be compiled. Grist will be added.
476	# <other objects>: Object files or static libraries to be merged. No grist
477	#                  will be added.
478	#
479	local target = $(1) ;
480	local sources = $(2) ;
481	local otherObjects = $(3) ;
482	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
483
484	PLATFORM on $(target) = host ;
485	SUPPORTED_PLATFORMS on $(target) = host ;
486
487	local usesBeAPI = [ on $(target[1]) return $(USES_BE_API) ] ;
488	if $(usesBeAPI) {
489		# propagate the flag to the objects
490		USES_BE_API on $(objects) = $(usesBeAPI) ;
491	}
492
493	MergeObject $(target) : $(sources) : $(otherObjects) ;
494}
495
496rule BuildPlatformStaticLibrary
497{
498	# BuildPlatformStaticLibrary <lib> : <sources> ;
499	# Creates a static library from sources.
500	# <lib>: The library.
501	# <sources>: List of source files.
502
503	local lib = $(1) ;
504	local sources = $(2) ;
505	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
506
507	PLATFORM on $(lib) = host ;
508	SUPPORTED_PLATFORMS on $(lib) = host ;
509
510	local usesBeAPI = [ on $(lib) return $(USES_BE_API) ] ;
511	if $(usesBeAPI) {
512		# propagate the flag to the objects
513		USES_BE_API on $(objects) = $(usesBeAPI) ;
514	}
515
516	StaticLibrary $(lib) : $(sources) ;
517}
518
519