xref: /haiku/build/jam/MainBuildRules (revision d9cebac2b77547b7064f22497514eecd2d047160)
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	on $(1) XRes $(1) : $(RESFILES) ;
203	if ! [ on $(1) return $(DONT_USE_BEOS_RULES) ] {
204		SetType $(1) ;
205		MimeSet $(1) ;
206		SetVersion $(1) ;
207	}
208}
209
210actions Ld
211{
212	$(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" "$(NEEDLIBS)" $(LINKLIBS)
213}
214
215
216rule MergeObjectFromObjects
217{
218	# MergeObjectFromObjects <name> : <objects> : <other objects> ;
219	# Merges object files to an object file.
220	# <name>: Name of the object file to create. No grist will be added.
221	# <objects>: Object files to be merged. Grist will be added.
222	# <other objects>: Object files or static libraries to be merged. No grist
223	#                  will be added.
224	#
225	local objects = [ FGristFiles $(2) ] ;
226
227	on $(1) {
228		if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
229			return ;
230		}
231
232		if $(PLATFORM) = host {
233			LINK on $(1) = $(HOST_LD) ;
234			LINKFLAGS on $(target) = $(HOST_LDFLAGS) ;
235		} else {
236			LINK on $(1) = $(TARGET_LD) ;
237			LINKFLAGS on $(target) = $(TARGET_LDFLAGS) ;
238		}
239	}
240
241	MakeLocateDebug $(1) ;
242	Depends $(1) : $(objects) ;
243	Depends $(1) : $(3) ;
244	LocalDepends obj : $(1) ;
245	MergeObjectFromObjects1 $(1) : $(objects) $(3) ;
246}
247
248actions MergeObjectFromObjects1
249{
250	$(LINK) $(LINKFLAGS) -r $(2) -o $(1) ;
251}
252
253rule MergeObject
254{
255	# MergeObject <name> : <sources> : <other objects> ;
256	# Compiles source files and merges the object files to an object file.
257	# <name>: Name of the object file to create. No grist will be added.
258	# <sources>: Sources to be compiled. Grist will be added.
259	# <other objects>: Object files or static libraries to be merged. No grist
260	#                  will be added.
261	#
262	local target = $(1) ;
263	local sources = [ FGristFiles $(2) ] ;
264	local otherObjects = $(3) ;
265	local objects = $(sources:S=$(SUFOBJ)) ;
266
267	if ! [ IsPlatformSupportedForTarget $(1) ] {
268		return ;
269	}
270
271	InheritPlatform $(objects) : $(target) ;
272	Objects $(sources) ;
273	MergeObjectFromObjects $(target) : $(objects) : $(otherObjects) ;
274}
275
276rule SharedLibraryFromObjects
277{
278	# SharedLibraryFromObjects <lib> : <objects> : <libraries> ;
279	#
280	local _lib = $(1) ;
281
282	if ! [ IsPlatformSupportedForTarget $(1) ] {
283		return ;
284	}
285
286	MainFromObjects $(_lib) : $(2) ;
287	LINKFLAGS on $(_lib) = [ on $(_lib) return $(LINKFLAGS) ]
288						   -nostart -Xlinker -soname=\"$(_lib:G=)\" ;
289	LinkAgainst $(_lib) : $(3) ;
290
291	AddSharedObjectGlueCode $(_lib) : false ;
292}
293
294rule SharedLibrary
295{
296	# SharedLibrary <lib> : <sources> : <libraries> ;
297	local lib = $(1) ;
298	local sources = [ FGristFiles $(2) ] ;
299	local objects = $(sources:S=$(SUFOBJ)) ;
300	local libs = $(3) ;
301
302	if ! [ IsPlatformSupportedForTarget $(1) ] {
303		return ;
304	}
305
306	InheritPlatform $(objects) : $(lib) ;
307	Objects $(sources) ;
308	SharedLibraryFromObjects $(lib) : $(objects) : $(libs) ;
309}
310
311rule LinkAgainst
312{
313	# LinkAgainst <name> : <libs> [ : <mapLibs> ] ;
314	# Valid elements for <libs> are e.g. "be" or "libtranslation.so" or
315	# "/boot/.../libfoo.so". If the basename starts with "lib" or the thingy
316	# has a dirname or grist, it is added to the NEEDLIBS variable (i.e. the
317	# file will be bound!), otherwise it is prefixed "-l" and added to
318	# LINKLIBS. If you want to specify a target that isn't a library and
319	# also has neither grist nor a dirname, you can prepend "<nogrist>" as
320	# grist; it will be stripped by this rule.
321	# <mapLibs> specifies whether the to translate library names (e.g. "be"
322	# to "libbe.so" in case of target platform "haiku"). Defaults to "true".
323	#
324	local target = $(1) ;
325	local libs = $(2) ;
326	local mapLibs = $(3:E=true) ;
327
328	on $(target) {
329		# map libraries, if desired and target platform is Haiku
330		if $(PLATFORM) != host && $(mapLibs) = true
331				&& $(TARGET_LIBRARY_NAME_MAP) {
332			local mappedLibs ;
333
334			for i in $(libs) {
335				local mapped = $($(TARGET_LIBRARY_NAME_MAP)_$(i)) ;
336				mapped ?= $(i) ;
337				mappedLibs += $(mapped) ;
338			}
339
340			libs = $(mappedLibs) ;
341		}
342
343		local linkLibs ;
344		local needLibs ;
345
346		for i in $(libs)
347		{
348			local isfile = ;
349			if $(i:D) || $(i:G) {
350				isfile = true ;
351				if $(i:G) = <nogrist> {
352					i = $(i:G=) ;
353				}
354			} else {
355				switch $(i:B)
356				{
357					# XXX: _APP_ and _KERNEL_ should not be needed for ELF.
358					case _APP_ : isfile = true ;
359					case _KERNEL_ : isfile = true ;
360					case lib*	: isfile = true ;
361					case *	: isfile = ;
362				}
363				if ! $(isfile) && ( $(i:S) = .so || $(i:S) = .a ) {
364					isfile = true ;
365				}
366			}
367
368			if $(isfile) {
369				needLibs += $(i) ;
370			} else {
371				linkLibs += $(i) ;
372			}
373		}
374
375		NEEDLIBS on $(1) = $(NEEDLIBS) $(needLibs) ;
376		LINKLIBS on $(1) = $(LINKLIBS) -l$(linkLibs) ;
377
378		if $(needLibs) && ! $(NO_LIBRARY_DEPENDENCIES) {
379			Depends $(1) : $(needLibs) ;
380		}
381	}
382}
383
384rule AddResources
385{
386	# AddResources <name> : <resourcefiles> ;
387
388	# add grist to the resource files which don't have any yet
389	local resfiles ;
390	local file ;
391	for file in $(2) {
392		if ! $(file:G) {
393			file = [ FGristFiles $(file) ] ;
394		}
395		resfiles += $(file) ;
396	}
397
398	SEARCH on $(resfiles) += $(SEARCH_SOURCE) ;
399
400	for file in $(resfiles) {
401		if $(file:S) = .rdef {
402			local rdef = $(file) ;
403			file = $(rdef:S=.rsrc) ;
404			ResComp $(file) : $(rdef) ;
405		}
406		InheritPlatform $(file) : $(1) ;
407		RESFILES on $(1) += $(file) ;
408	}
409}
410
411rule BuildPlatformObjects
412{
413	# Usage BuildPlatformObjects <sources> ;
414	# <sources> The sources.
415	#
416	local sources = [ FGristFiles $(1) ] ;
417	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
418
419	PLATFORM on $(objects) = host ;
420	SUPPORTED_PLATFORMS on $(objects) = host ;
421
422	Objects $(sources) ;
423}
424
425rule BuildPlatformMain
426{
427	# Usage BuildPlatformMain <target> : <sources> : <libraries> ;
428	# <target> The executable/library.
429	# <sources> The sources.
430	# <libraries> Libraries to link against.
431	#
432	local target = $(1) ;
433	local sources = $(2) ;
434	local libs = $(3) ;
435	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
436
437	PLATFORM on $(target) = host ;
438	SUPPORTED_PLATFORMS on $(target) = host ;
439	DONT_USE_BEOS_RULES on $(target) = true ;
440
441	local usesBeAPI = [ on $(target) return $(USES_BE_API) ] ;
442	if $(usesBeAPI) {
443		# propagate the flag to the objects
444		USES_BE_API on $(objects) = $(usesBeAPI) ;
445
446		# add the build libroot
447		if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
448			Depends $(target) : $(HOST_LIBROOT) ;
449			NEEDLIBS on $(target) += $(HOST_LIBROOT) ;
450		}
451	}
452
453	Main $(target) : $(sources) ;
454	LinkAgainst $(target) : $(libs) ;
455}
456
457rule BuildPlatformSharedLibrary
458{
459	# Usage BuildPlatformSharedLibrary <target> : <sources> : <libraries> ;
460	# <target> The library.
461	# <sources> The sources.
462	# <libraries> Libraries to link against.
463	#
464	local target = $(1) ;
465	local sources = $(2) ;
466	local libs = $(3) ;
467
468	BuildPlatformMain $(target) : $(sources) : $(libs) ;
469
470	if $(HOST_PLATFORM) = darwin {
471		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
472			-dynamic -dynamiclib -Xlinker -flat_namespace ;
473	} else {
474		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
475			-shared -Xlinker -soname=\"$(target:G=)\" ;
476	}
477
478    local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
479	CCFLAGS on $(objects) += $(HOST_PIC_CCFLAGS) ;
480	C++FLAGS on $(objects) += $(HOST_PIC_C++FLAGS) ;
481}
482
483rule BuildPlatformMergeObject
484{
485	# BuildPlatformMergeObject <name> : <sources> : <other objects> ;
486	# Compiles source files and merges the object files to an object file.
487	# <name>: Name of the object file to create. No grist will be added.
488	# <sources>: Sources to be compiled. Grist will be added.
489	# <other objects>: Object files or static libraries to be merged. No grist
490	#                  will be added.
491	#
492	local target = $(1) ;
493	local sources = $(2) ;
494	local otherObjects = $(3) ;
495	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
496
497	PLATFORM on $(target) = host ;
498	SUPPORTED_PLATFORMS on $(target) = host ;
499
500	local usesBeAPI = [ on $(target[1]) return $(USES_BE_API) ] ;
501	if $(usesBeAPI) {
502		# propagate the flag to the objects
503		USES_BE_API on $(objects) = $(usesBeAPI) ;
504	}
505
506	MergeObject $(target) : $(sources) : $(otherObjects) ;
507}
508
509rule BuildPlatformMergeObjectPIC target : sources : otherObjects
510{
511	# BuildPlatformMergeObjectPIC <name> : <sources> : <other objects> ;
512	# Compiles source files and merges the object files to an object file.
513	# Same as BuildPlatformMergeObject rule but adds position-independent
514	# flags to the compiler (if any).
515	# <name>: Name of the object file to create. No grist will be added.
516	# <sources>: Sources to be compiled. Grist will be added.
517	# <other objects>: Object files or static libraries to be merged. No grist
518	#                  will be added.
519	#
520	ObjectCcFlags $(sources) : $(HOST_PIC_CCFLAGS) ;
521	ObjectC++Flags $(sources) : $(HOST_PIC_C++FLAGS) ;
522
523	BuildPlatformMergeObject $(target) : $(sources) : $(otherObjects) ;
524}
525
526rule BuildPlatformStaticLibrary
527{
528	# BuildPlatformStaticLibrary <lib> : <sources> ;
529	# Creates a static library from sources.
530	# <lib>: The library.
531	# <sources>: List of source files.
532
533	local lib = $(1) ;
534	local sources = $(2) ;
535	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
536
537	PLATFORM on $(lib) = host ;
538	SUPPORTED_PLATFORMS on $(lib) = host ;
539
540	local usesBeAPI = [ on $(lib) return $(USES_BE_API) ] ;
541	if $(usesBeAPI) {
542		# propagate the flag to the objects
543		USES_BE_API on $(objects) = $(usesBeAPI) ;
544	}
545
546	StaticLibrary $(lib) : $(sources) ;
547}
548
549