xref: /haiku/build/jam/MainBuildRules (revision f23596149e0d173463f70629581aa10cc305d32e)
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
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		InheritPlatform $(file) : $(1) ;
404		RESFILES on $(1) += $(file) ;
405	}
406}
407
408rule BuildPlatformObjects
409{
410	# Usage BuildPlatformObjects <sources> ;
411	# <sources> The sources.
412	#
413	local sources = [ FGristFiles $(1) ] ;
414	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
415
416	PLATFORM on $(objects) = host ;
417	SUPPORTED_PLATFORMS on $(objects) = host ;
418
419	Objects $(sources) ;
420}
421
422rule BuildPlatformMain
423{
424	# Usage BuildPlatformMain <target> : <sources> : <libraries> ;
425	# <target> The executable/library.
426	# <sources> The sources.
427	# <libraries> Libraries to link against.
428	#
429	local target = $(1) ;
430	local sources = $(2) ;
431	local libs = $(3) ;
432	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
433
434	PLATFORM on $(target) = host ;
435	SUPPORTED_PLATFORMS on $(target) = host ;
436	DONT_USE_BEOS_RULES on $(target) = true ;
437
438	local usesBeAPI = [ on $(target) return $(USES_BE_API) ] ;
439	if $(usesBeAPI) {
440		# propagate the flag to the objects
441		USES_BE_API on $(objects) = $(usesBeAPI) ;
442
443		# add the build libroot
444		if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
445			Depends $(target) : $(HOST_LIBROOT) ;
446			NEEDLIBS on $(target) += $(HOST_LIBROOT) ;
447		}
448	}
449
450	Main $(target) : $(sources) ;
451	LinkAgainst $(target) : $(libs) ;
452}
453
454rule BuildPlatformSharedLibrary
455{
456	# Usage BuildPlatformSharedLibrary <target> : <sources> : <libraries> ;
457	# <target> The library.
458	# <sources> The sources.
459	# <libraries> Libraries to link against.
460	#
461	local target = $(1) ;
462	local sources = $(2) ;
463	local libs = $(3) ;
464
465	BuildPlatformMain $(target) : $(sources) : $(libs) ;
466	LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
467		-shared -Xlinker -soname=\"$(target)\" ;
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