xref: /haiku/build/jam/MainBuildRules (revision 020cbad9d40235a2c50a81a42d69912a5ff8fbc4)
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
215rule CreateAsmStructOffsetsHeader header : source
216{
217	# CreateAsmStructOffsetsHeader header : source
218	#
219	# Grist will be added to both header and source.
220
221	header = [ FGristFiles $(header) ] ;
222	source = [ FGristFiles $(source) ] ;
223
224	# find out which headers, defines, etc. to use
225	local headers ;
226	local sysHeaders ;
227	local defines ;
228	local flags ;
229	local includesSeparator ;
230	local localIncludesOption ;
231	local systemIncludesOption ;
232
233	on $(header) { # use on $(1) variable values
234		if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
235			return ;
236		}
237
238		# headers and defines
239		headers = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
240		sysHeaders = $(SUBDIRSYSHDRS) $(SYSHDRS) ;
241		defines = $(DEFINES) ;
242
243		if $(PLATFORM) = host {
244			sysHeaders += $(HOST_HDRS) ;
245			defines += $(HOST_DEFINES) ;
246
247			if $(USES_BE_API) {
248				sysHeaders += $(HOST_BE_API_HEADERS) ;
249			}
250
251		} else {
252			sysHeaders += $(TARGET_HDRS) ;
253			defines += $(TARGET_DEFINES) ;
254		}
255
256		# optimization flags
257		if $(DEBUG) = 0 {
258			flags += $(OPTIM) ;
259		} else {
260			flags += -O0 ;
261		}
262
263		if $(PLATFORM) = host {
264			# warning flags
265			if $(WARNINGS) != 0 {
266				flags += $(HOST_WARNING_C++FLAGS) ;
267			}
268
269			# debug and other flags
270			flags += $(HOST_C++FLAGS) $(HOST_DEBUG_$(DEBUG)_C++FLAGS)
271				$(SUBDIRC++FLAGS) $(C++FLAGS) ;
272
273			if $(USES_BE_API) {
274				flags += $(HOST_BE_API_C++FLAGS) ;
275			}
276
277			C++ on $(header) = $(HOST_C++) ;
278
279			includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;
280			localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;
281			systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;
282
283		} else {
284			# warning flags
285			if $(WARNINGS) != 0 {
286				flags += $(TARGET_WARNING_C++FLAGS) ;
287			}
288
289			# debug and other flags
290			flags += $(TARGET_C++FLAGS) $(TARGET_DEBUG_$(DEBUG)_C++FLAGS)
291				$(SUBDIRC++FLAGS) $(C++FLAGS) ;
292
293			C++ on $(header) = $(TARGET_C++) ;
294
295			includesSeparator = $(TARGET_INCLUDES_SEPARATOR) ;
296			localIncludesOption = $(TARGET_LOCAL_INCLUDES_OPTION) ;
297			systemIncludesOption = $(TARGET_SYSTEM_INCLUDES_OPTION) ;
298		}
299	}
300
301	# locate object, search for source, and set on target variables
302
303	Depends $(header) : $(source) ;
304	SEARCH on $(source) += $(SEARCH_SOURCE) ;
305	MakeLocateArch $(header) ;
306	LocalClean clean : $(header) ;
307
308	HDRRULE on $(source) = HdrRule ;
309	HDRSCAN on $(source) = $(HDRPATTERN) ;
310	HDRSEARCH on $(source) = $(headers) $(sysHeaders) $(STDHDRS) ;
311	HDRGRIST on $(source) = $(HDRGRIST) ;
312
313	C++FLAGS on $(header) = $(flags) ;
314	CCHDRS on $(header) = [ FIncludes $(headers) : $(localIncludesOption) ]
315		$(includesSeparator)
316		[ FSysIncludes $(sysHeaders) : $(systemIncludesOption) ] ;
317	CCDEFS on $(header) = [ FDefines $(defines) ] ;
318
319	CreateAsmStructOffsetsHeader1 $(header) : $(source) ;
320}
321
322actions CreateAsmStructOffsetsHeader1
323{
324 	$(C++) -S "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o - \
325		| grep "#define" | sed -e 's/\$//' > "$(1)"
326}
327
328rule MergeObjectFromObjects
329{
330	# MergeObjectFromObjects <name> : <objects> : <other objects> ;
331	# Merges object files to an object file.
332	# <name>: Name of the object file to create. No grist will be added.
333	# <objects>: Object files to be merged. Grist will be added.
334	# <other objects>: Object files or static libraries to be merged. No grist
335	#                  will be added.
336	#
337	local objects = [ FGristFiles $(2) ] ;
338
339	on $(1) {
340		if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
341			return ;
342		}
343
344		if $(PLATFORM) = host {
345			LINK on $(1) = $(HOST_LD) ;
346			LINKFLAGS on $(target) = $(HOST_LDFLAGS) ;
347		} else {
348			LINK on $(1) = $(TARGET_LD) ;
349			LINKFLAGS on $(target) = $(TARGET_LDFLAGS) ;
350		}
351	}
352
353	MakeLocateDebug $(1) ;
354	Depends $(1) : $(objects) ;
355	Depends $(1) : $(3) ;
356	LocalDepends obj : $(1) ;
357	MergeObjectFromObjects1 $(1) : $(objects) $(3) ;
358}
359
360actions MergeObjectFromObjects1
361{
362	$(LINK) $(LINKFLAGS) -r $(2) -o $(1) ;
363}
364
365rule MergeObject
366{
367	# MergeObject <name> : <sources> : <other objects> ;
368	# Compiles source files and merges the object files to an object file.
369	# <name>: Name of the object file to create. No grist will be added.
370	# <sources>: Sources to be compiled. Grist will be added.
371	# <other objects>: Object files or static libraries to be merged. No grist
372	#                  will be added.
373	#
374	local target = $(1) ;
375	local sources = [ FGristFiles $(2) ] ;
376	local otherObjects = $(3) ;
377	local objects = $(sources:S=$(SUFOBJ)) ;
378
379	if ! [ IsPlatformSupportedForTarget $(1) ] {
380		return ;
381	}
382
383	InheritPlatform $(objects) : $(target) ;
384	Objects $(sources) ;
385	MergeObjectFromObjects $(target) : $(objects) : $(otherObjects) ;
386}
387
388rule SharedLibraryFromObjects
389{
390	# SharedLibraryFromObjects <lib> : <objects> : <libraries> ;
391	#
392	local _lib = $(1) ;
393
394	if ! [ IsPlatformSupportedForTarget $(1) ] {
395		return ;
396	}
397
398	MainFromObjects $(_lib) : $(2) ;
399	LINKFLAGS on $(_lib) = [ on $(_lib) return $(LINKFLAGS) ]
400						   -nostart -Xlinker -soname=\"$(_lib:G=)\" ;
401	LinkAgainst $(_lib) : $(3) ;
402
403	AddSharedObjectGlueCode $(_lib) : false ;
404}
405
406rule SharedLibrary
407{
408	# SharedLibrary <lib> : <sources> : <libraries> ;
409	local lib = $(1) ;
410	local sources = [ FGristFiles $(2) ] ;
411	local objects = $(sources:S=$(SUFOBJ)) ;
412	local libs = $(3) ;
413
414	if ! [ IsPlatformSupportedForTarget $(1) ] {
415		return ;
416	}
417
418	InheritPlatform $(objects) : $(lib) ;
419	Objects $(sources) ;
420	SharedLibraryFromObjects $(lib) : $(objects) : $(libs) ;
421}
422
423rule LinkAgainst
424{
425	# LinkAgainst <name> : <libs> [ : <mapLibs> ] ;
426	# Valid elements for <libs> are e.g. "be" or "libtranslation.so" or
427	# "/boot/.../libfoo.so". If the basename starts with "lib" or the thingy
428	# has a dirname or grist, it is added to the NEEDLIBS variable (i.e. the
429	# file will be bound!), otherwise it is prefixed "-l" and added to
430	# LINKLIBS. If you want to specify a target that isn't a library and
431	# also has neither grist nor a dirname, you can prepend "<nogrist>" as
432	# grist; it will be stripped by this rule.
433	# <mapLibs> specifies whether the to translate library names (e.g. "be"
434	# to "libbe.so" in case of target platform "haiku"). Defaults to "true".
435	#
436	local target = $(1) ;
437	local libs = $(2) ;
438	local mapLibs = $(3:E=true) ;
439
440	on $(target) {
441		# map libraries, if desired and target platform is Haiku
442		if $(PLATFORM) != host && $(mapLibs) = true
443				&& $(TARGET_LIBRARY_NAME_MAP) {
444			local mappedLibs ;
445
446			for i in $(libs) {
447				local mapped = $($(TARGET_LIBRARY_NAME_MAP)_$(i)) ;
448				mapped ?= $(i) ;
449				mappedLibs += $(mapped) ;
450			}
451
452			libs = $(mappedLibs) ;
453		}
454
455		local linkLibs ;
456		local needLibs ;
457
458		for i in $(libs)
459		{
460			local isfile = ;
461			if $(i:D) || $(i:G) {
462				isfile = true ;
463				if $(i:G) = <nogrist> {
464					i = $(i:G=) ;
465				}
466			} else {
467				switch $(i:B)
468				{
469					# XXX: _APP_ and _KERNEL_ should not be needed for ELF.
470					case _APP_ : isfile = true ;
471					case _KERNEL_ : isfile = true ;
472					case lib*	: isfile = true ;
473					case *	: isfile = ;
474				}
475				if ! $(isfile) && ( $(i:S) = .so || $(i:S) = .a ) {
476					isfile = true ;
477				}
478			}
479
480			if $(isfile) {
481				needLibs += $(i) ;
482			} else {
483				linkLibs += $(i) ;
484			}
485		}
486
487		NEEDLIBS on $(1) = $(NEEDLIBS) $(needLibs) ;
488		LINKLIBS on $(1) = $(LINKLIBS) -l$(linkLibs) ;
489
490		if $(needLibs) && ! $(NO_LIBRARY_DEPENDENCIES) {
491			Depends $(1) : $(needLibs) ;
492		}
493	}
494}
495
496rule AddResources
497{
498	# AddResources <name> : <resourcefiles> ;
499
500	# add grist to the resource files which don't have any yet
501	local resfiles ;
502	local file ;
503	for file in $(2) {
504		if ! $(file:G) {
505			file = [ FGristFiles $(file) ] ;
506		}
507		resfiles += $(file) ;
508	}
509
510	SEARCH on $(resfiles) += $(SEARCH_SOURCE) ;
511
512	for file in $(resfiles) {
513		if $(file:S) = .rdef {
514			local rdef = $(file) ;
515			file = $(rdef:S=.rsrc) ;
516			ResComp $(file) : $(rdef) ;
517		}
518		InheritPlatform $(file) : $(1) ;
519		RESFILES on $(1) += $(file) ;
520	}
521}
522
523rule BuildPlatformObjects
524{
525	# Usage BuildPlatformObjects <sources> ;
526	# <sources> The sources.
527	#
528	local sources = [ FGristFiles $(1) ] ;
529	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
530
531	PLATFORM on $(objects) = host ;
532	SUPPORTED_PLATFORMS on $(objects) = host ;
533
534	Objects $(sources) ;
535}
536
537rule BuildPlatformMain
538{
539	# Usage BuildPlatformMain <target> : <sources> : <libraries> ;
540	# <target> The executable/library.
541	# <sources> The sources.
542	# <libraries> Libraries to link against.
543	#
544	local target = $(1) ;
545	local sources = $(2) ;
546	local libs = $(3) ;
547	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
548
549	PLATFORM on $(target) = host ;
550	SUPPORTED_PLATFORMS on $(target) = host ;
551	DONT_USE_BEOS_RULES on $(target) = true ;
552
553	local usesBeAPI = [ on $(target) return $(USES_BE_API) ] ;
554	if $(usesBeAPI) {
555		# propagate the flag to the objects
556		USES_BE_API on $(objects) = $(usesBeAPI) ;
557
558		# add the build libroot
559		if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
560			Depends $(target) : $(HOST_LIBROOT) ;
561			NEEDLIBS on $(target) += $(HOST_LIBROOT) ;
562		}
563	}
564
565	Main $(target) : $(sources) ;
566	LinkAgainst $(target) : $(libs) ;
567}
568
569rule BuildPlatformSharedLibrary
570{
571	# Usage BuildPlatformSharedLibrary <target> : <sources> : <libraries> ;
572	# <target> The library.
573	# <sources> The sources.
574	# <libraries> Libraries to link against.
575	#
576	local target = $(1) ;
577	local sources = $(2) ;
578	local libs = $(3) ;
579
580	BuildPlatformMain $(target) : $(sources) : $(libs) ;
581
582	if $(HOST_PLATFORM) = darwin {
583		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
584			-dynamic -dynamiclib -Xlinker -flat_namespace ;
585	} else {
586		LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ]
587			-shared -Xlinker -soname=\"$(target:G=)\" ;
588	}
589
590    local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
591	CCFLAGS on $(objects) += $(HOST_PIC_CCFLAGS) ;
592	C++FLAGS on $(objects) += $(HOST_PIC_C++FLAGS) ;
593}
594
595rule BuildPlatformMergeObject
596{
597	# BuildPlatformMergeObject <name> : <sources> : <other objects> ;
598	# Compiles source files and merges the object files to an object file.
599	# <name>: Name of the object file to create. No grist will be added.
600	# <sources>: Sources to be compiled. Grist will be added.
601	# <other objects>: Object files or static libraries to be merged. No grist
602	#                  will be added.
603	#
604	local target = $(1) ;
605	local sources = $(2) ;
606	local otherObjects = $(3) ;
607	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
608
609	PLATFORM on $(target) = host ;
610	SUPPORTED_PLATFORMS on $(target) = host ;
611
612	local usesBeAPI = [ on $(target[1]) return $(USES_BE_API) ] ;
613	if $(usesBeAPI) {
614		# propagate the flag to the objects
615		USES_BE_API on $(objects) = $(usesBeAPI) ;
616	}
617
618	MergeObject $(target) : $(sources) : $(otherObjects) ;
619}
620
621rule BuildPlatformMergeObjectPIC target : sources : otherObjects
622{
623	# BuildPlatformMergeObjectPIC <name> : <sources> : <other objects> ;
624	# Compiles source files and merges the object files to an object file.
625	# Same as BuildPlatformMergeObject rule but adds position-independent
626	# flags to the compiler (if any).
627	# <name>: Name of the object file to create. No grist will be added.
628	# <sources>: Sources to be compiled. Grist will be added.
629	# <other objects>: Object files or static libraries to be merged. No grist
630	#                  will be added.
631	#
632	ObjectCcFlags $(sources) : $(HOST_PIC_CCFLAGS) ;
633	ObjectC++Flags $(sources) : $(HOST_PIC_C++FLAGS) ;
634
635	BuildPlatformMergeObject $(target) : $(sources) : $(otherObjects) ;
636}
637
638rule BuildPlatformStaticLibrary
639{
640	# BuildPlatformStaticLibrary <lib> : <sources> ;
641	# Creates a static library from sources.
642	# <lib>: The library.
643	# <sources>: List of source files.
644
645	local lib = $(1) ;
646	local sources = $(2) ;
647	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
648
649	PLATFORM on $(lib) = host ;
650	SUPPORTED_PLATFORMS on $(lib) = host ;
651
652	local usesBeAPI = [ on $(lib) return $(USES_BE_API) ] ;
653	if $(usesBeAPI) {
654		# propagate the flag to the objects
655		USES_BE_API on $(objects) = $(usesBeAPI) ;
656	}
657
658	StaticLibrary $(lib) : $(sources) ;
659}
660
661