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