xref: /haiku/Jamrules (revision 600203b105de6bd6bb9d6064aabb673b728cdf00)
1# Vanilla Jam compatibility
2if ! $(INVOCATION_SUBDIR_SET) {
3
4	rule FIsPrefix
5	{
6		# FIsPrefix <a> : <b> ;
7		# Returns true, if list <a> is a prefix (a proper one or equal) of
8		# list <b>, an empty list otherwise.
9		local a = $(1) ;
10		local b = $(2) ;
11		while $(a) && $(a[1]) = $(b[1]) {
12			a = $(a[2-]) ;
13			b = $(b[2-]) ;
14		}
15
16		if $(a) {
17			return ;
18		} else {
19			return true ;
20		}
21	}
22
23	rule LocalClean { Clean $(1) : $(2) ; }
24
25	rule LocalDepends { Depends $(1) : $(2) ; }
26
27} # vanilla Jam compatibility
28
29# The directory for build system specific files
30OBOS_BUILD_DIR = [ FDirName $(OBOS_TOP) build ] ;
31
32# Cache files for header scanning and jamfile caching
33HCACHEFILE = header_cache ;
34JCACHEFILE = jamfile_cache ;
35LOCATE on $(HCACHEFILE) $(JCACHEFILE) = $(OBOS_BUILD_DIR) ;
36
37# Include BuildConfig
38{
39	local buildConfig = [ GLOB $(OBOS_BUILD_DIR) : BuildConfig ] ;
40	if ! $(buildConfig)
41	{
42		ECHO "No BuildConfig found in $(OBOS_BUILD_DIR)!" ;
43		EXIT "Run ./configure in the source tree's root directory first!" ;
44	}
45	LOCATE on BuildConfig = $(OBOS_BUILD_DIR) ;
46	include BuildConfig ;
47}
48
49# analyze GCC version
50if ! $(GCC_RAW_VERSION) {
51	ECHO "Variable GCC_RAW_VERSION not set. Please run ./configure or" ;
52	EXIT "specify it manually." ;
53}
54GCC_VERSION = ;
55{
56	# split the raw version string at `.' and `-' characters
57	local version = $(GCC_RAW_VERSION) ;
58	while $(version) {
59		local split = [ Match "([^.-]*)[.-](.*)" : $(version) ] ;
60		if $(split) {
61			GCC_VERSION += $(split[1]) ;
62			version = $(split[2]) ;
63		} else {
64			GCC_VERSION += $(version) ;
65			version = ;
66		}
67	}
68}
69
70# Save the platform default headers.
71PLATFORM_DEFAULT_HEADERS = $(HDRS) ;
72
73# We do not include any local BeOS system headers by default
74CCFLAGS += -nostdinc ;
75C++FLAGS += -nostdinc ;
76
77# Determine if we're building on PPC or x86
78# Determine mimetype of executable
79# Cross compiling can come later
80
81TARGET_CPU ?= $(OSPLAT:L) ;
82OBOS_VERSION ?= R1 ;
83
84switch $(TARGET_CPU) {
85	case ppc :
86	{
87		if $(METROWERKS) {
88			# at least parts of OpenBeOS still can be compiled with
89			# the Metrowerks compiler on BeOS/PPC
90			OBOS_TARGET_TYPE ?= "application/x-be-executable" ;
91		} else {
92			OBOS_TARGET_TYPE ?= "application/x-vnd.Be-elfexecutable" ;
93		}
94		DEFINES += __POWERPC__ ;
95		OBOS_BOOT_PLATFORM = openfirmware ;
96	}
97	case x86 :
98	{
99		# nothing special to do here...
100		DEFINES += __INTEL__ ;
101		OBOS_BOOT_PLATFORM = bios_ia32 ;
102	}
103	case * :
104		Exit "Currently unsupported build platform:" $(TARGET_CPU) ;
105}
106
107# set target specific variables
108{
109	#Echo "Building for" $(TARGET_CPU) ;
110
111	OBOS_TARGET ?= $(TARGET_CPU).$(OBOS_VERSION) ;
112	OBOS_TARGET_TYPE ?= "application/x-vnd.Be-elfexecutable" ;
113	OBOS_ARCH ?= $(TARGET_CPU) ;
114	OBOS_TARGET_DEFINE ?= "ARCH_"$(TARGET_CPU) ;
115}
116
117# Disable warnings only if WARNINGS is set to 0
118# Should be enabled by default later
119#
120WARNINGS ?= 1 ;
121if $(WARNINGS) = 1 {
122	# For an explanation of the different warning options, see:
123	# http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_2.html
124	# to get even more warnings, add:
125	# -Wwrite-strings  	(doesn't work well with some Be headers)
126	# -Wundef			(dito)
127	# -Wconversion		(gets you many warnings about implicit conversions)
128	# -W				(gets you even more warnigs)
129	CCFLAGS += -Wall -Wno-multichar -Wmissing-prototypes ;
130	CCFLAGS += -Wpointer-arith -Wcast-align -Wsign-compare ;
131	C++FLAGS += -Wall -Wno-multichar -Wmissing-prototypes -Wno-ctor-dtor-privacy -Woverloaded-virtual ;
132	C++FLAGS += -Wpointer-arith -Wcast-align -Wsign-compare ;
133} else {
134	CCFLAGS += -Wno-multichar ;
135	C++FLAGS += -Wno-multichar ;
136}
137
138# standard kernel C/C++ flags
139KERNEL_CCFLAGS ?= -Wall -Wno-multichar -Wmissing-prototypes -finline -nostdinc ;
140KERNEL_CCFLAGS += -fno-builtin -D$(OBOS_TARGET_DEFINE) ;
141KERNEL_CCFLAGS += -DBOCHS_DEBUG_HACK=$(BOCHS_DEBUG_HACK) -D_KERNEL_MODE ;
142KERNEL_C++FLAGS ?= -Wall -Wno-multichar -Wmissing-prototypes -finline -nostdinc ;
143KERNEL_C++FLAGS += -fno-builtin -fno-exceptions -fno-rtti -D$(OBOS_TARGET_DEFINE) ;
144KERNEL_C++FLAGS += -DBOCHS_DEBUG_HACK=$(BOCHS_DEBUG_HACK) -D_KERNEL_MODE ;
145if $(GCC_VERSION[1]) >= 3 {
146	KERNEL_C++FLAGS += -fno-use-cxa-atexit ;
147}
148
149# We might later want to introduce debug levels or handle the whole issue
150# differently. For now there's only on or off.
151#
152DEBUG ?= 0 ;
153if $(DEBUG) != 0 {
154	OPTIM ?= -O0 ;
155	CCFLAGS += -g [ FDefines DEBUG=$(DEBUG) ] ;
156	C++FLAGS += -g [ FDefines DEBUG=$(DEBUG) ] ;
157	KERNEL_CCFLAGS += -g [ FDefines DEBUG=$(DEBUG) ] ;
158	KERNEL_C++FLAGS += -g [ FDefines DEBUG=$(DEBUG) ] ;
159	LINKFLAGS += -g ;
160} else {
161	OPTIM ?= -O2 ;
162}
163#
164# To disable for the tests OPTIM and DEBUG are overridden, set the environment
165# variable NO_TEST_DEBUG.
166
167# Instructs the Library rule to not make its object files temporary.
168# This is needed as some objects are used in a static library and for an
169# executable.
170KEEPOBJS = true ;
171
172# under BeOS use copyattr instead of cp
173if $(OS) = BEOS
174{
175	CP = copyattr --data ;
176}
177
178# If no OBOS_OBJECT_TARGET is not defined yet, use our default directory and
179# include our "OBOS_TARGET" as subdirectory in there (to prevent different
180# builds mixing objects from different targets).
181if ! $(OBOS_OBJECT_TARGET) {
182	OBOS_OBJECT_TARGET ?= [ FDirName $(OBOS_TOP) objects $(OBOS_TARGET) ] ;
183}
184
185# If no OBOS_DISTRO_TARGET is not defined yet, use our default directory and
186# include our "OBOS_TARGET" as subdirectory in there (to prevent different
187# builds mixing executables from different targets).
188if ! $(OBOS_DISTRO_TARGET) {
189	OBOS_DISTRO_TARGET ?= [ FDirName $(OBOS_TOP) distro $(OBOS_TARGET) ] ;
190}
191
192# Set our version number if not already set and mark it as a developer build
193if ! $(OBOS_BUILD_VERSION) {
194	OBOS_BUILD_VERSION ?= "1 0 0 a 1" ;
195	OBOS_BUILD_DESCRIPTION ?= "Developer Build" ;
196}
197
198# If OBOS_BUILD_VERSION is set, but OBOS_BUILD_DESCRIPTION isn't, mark it as
199# an unknown build.
200if ! $(OBOS_BUILD_DESCRIPTION) {
201	OBOS_BUILD_DESCRIPTION ?= "Unknown Build" ;
202}
203
204# Relative subdirs for distro dir
205OBOS_ADDON_DIR  ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system add-ons ] ;
206OBOS_APPS_DIR   ?= [ FDirName $(OBOS_DISTRO_TARGET) beos apps ] ;
207OBOS_BIN_DIR    ?= [ FDirName $(OBOS_DISTRO_TARGET) beos bin ] ;
208OBOS_ETC_DIR    ?= [ FDirName $(OBOS_DISTRO_TARGET) beos etc ] ;
209OBOS_FONTS_DIR  ?= [ FDirName $(OBOS_ETC_DIR) fonts ] ;
210OBOS_KERNEL_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system ] ;
211OBOS_PREFS_DIR  ?= [ FDirName $(OBOS_DISTRO_TARGET) beos preferences ] ;
212OBOS_SERVER_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system servers ] ;
213OBOS_SHLIB_DIR  ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system lib ] ;
214OBOS_STLIB_DIR  ?= [ FDirName $(OBOS_DISTRO_TARGET) develop lib
215							  $(OBOS_ARCH) ] ;
216OBOS_TEST_DIR   ?= [ FDirName $(OBOS_TOP) tests ] ;
217
218OBOS_PACKAGE_DIR ?= [ FDirName $(OBOS_TOP) packages $(OBOS_TARGET) ] ;
219OBOS_PACKAGE_OBJECT_DIR ?= [ FDirName $(OBOS_OBJECT_TARGET) packages ] ;
220
221OBOS_KERNEL_CONFIG = config.$(OBOS_ARCH).ini ;
222OBOS_KERNEL = kernel.$(OBOS_ARCH) ;
223OBOS_FLOPPY = floppy.$(OBOS_ARCH) ;
224
225rule SetupIncludes
226{
227	# XXX add "opengl" later
228	local os_includes = add-ons add-ons/file_system add-ons/graphics add-ons/input_server add-ons/screen_saver add-ons/tracker app device drivers game interface kernel media mail midi midi2 net storage support translation ;
229
230	# Overwrite any exiting content when changing HDRS. This rule may be invoked multiple times.
231
232	# Use headers directory, to allow to do things like include <posix/string.h>
233	HDRS = [ FDirName $(OBOS_TOP) headers ] ;
234
235	# Use posix headers directory
236	HDRS += [ FDirName $(OBOS_TOP) headers posix ] ;
237
238	# Use public OS header directories
239	HDRS += [ PublicHeaders $(os_includes) ] ;
240
241	# Used as a fallback, the R5 header directories (we should remove this as soon as possible)
242	HDRS += /boot/develop/headers/posix /boot/develop/headers/cpp ;
243
244	# The platform dependent headers.
245	HDRS += $(PLATFORM_HEADERS) ;
246}
247
248rule SetupR5Includes
249{
250	# Unsets HDRS, so that the OBOS headers do not `shadow' the system headers.
251	HDRS = ;
252}
253
254rule SetupDefaultIncludes
255{
256	# Resets HDRS to the default headers for the build platform.
257	HDRS = $(PLATFORM_DEFAULT_HEADERS) ;
258}
259
260#-------------------------------------------------------------------------------
261# Things Jam needs in order to work :)
262#-------------------------------------------------------------------------------
263
264# TODO: back-ported from jam 2.5: remove when not longer needed
265rule MakeLocate
266{
267	if $(>)
268	{
269	    LOCATE on $(<) = $(>) ;
270	    Depends $(<) : $(>[1]:G=dir) ;
271	    MkDir $(>[1]:G=dir) ;
272	}
273}
274
275rule Object
276{
277	# This is basically the original Jambase 2.4 Object rule stripped by
278	# comments. Only the final switch statement has been changed to allow
279	# intermediate C++ files for Yacc and Lex.
280
281	LocalClean clean : $(<) ;
282
283	MakeLocate $(<) : $(LOCATE_TARGET) ;
284	SEARCH on $(>) = $(SEARCH_SOURCE) ;
285
286	HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
287
288	HDRRULE on $(>) = HdrRule ;
289	HDRSCAN on $(>) = $(HDRPATTERN) ;
290	HDRSEARCH on $(>) =
291		$(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;
292
293	HDRGRIST on $(>) = $(HDRGRIST) ;
294
295	DEFINES on $(<) += $(DEFINES) ;
296
297	# if source is not .c, generate .c with specific rule
298
299	switch $(>:S)
300	{
301	    case .asm : As $(<) : $(>) ;
302	    case .c :	Cc $(<) : $(>) ;
303	    case .C :	C++ $(<) : $(>) ;
304	    case .cc :	C++ $(<) : $(>) ;
305	    case .cpp : C++ $(<) : $(>) ;
306	    case .f :	Fortran $(<) : $(>) ;
307	    case .l :	if [ on $(2) return $(GENERATE_C++) ] {
308						C++ $(<) : $(<:S=.cpp) ;
309						LexC++ $(<:S=.cpp) : $(>) ;
310					} else {
311						Cc $(<) : $(<:S=.c) ;
312						Lex $(<:S=.c) : $(>) ;
313					}
314	    case .s :	As $(<) : $(>) ;
315	    case .y :	if [ on $(2) return $(GENERATE_C++) ] {
316						C++ $(<) : $(<:S=.cpp) ;
317						Bison $(<:S=.cpp) : $(>) ;
318					} else {
319						Cc $(<) : $(<:S=$(YACCGEN)) ;
320						Yacc $(<:S=$(YACCGEN)) : $(>) ;
321					}
322	    case * :	UserObject $(<) : $(>) ;
323	}
324}
325
326rule UserObject
327{
328	switch $(2)
329	{
330	case *.S    : assemble $(1) : $(2) ;
331	case *.o    : return ;
332	case *      : ECHO "unknown suffix on" $(2) ;
333	}
334}
335
336# Override the default to give "prettier" command lines.
337actions Cc
338{
339	$(CC) -c "$(2)" $(CCFLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
340}
341
342actions C++
343{
344	$(C++) -c "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
345}
346
347
348#-------------------------------------------------------------------------------
349# General High-level OBOS target rules
350#-------------------------------------------------------------------------------
351
352rule App
353{
354	# App <name> : <sources> : <libraries> ;
355	SetupIncludes ;
356	SetupObjectsDir ;
357	Main $(1) : $(2) ;
358	MakeLocate $(1) : $(OBOS_APPS_DIR) ;
359	LinkSharedOSLibs $(1) : $(3) ;
360	LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
361						-Xlinker -soname=_APP_ ;
362}
363
364rule BinCommand
365{
366	# BinCommand <name> : <sources> : <libraries> : <res> ;
367	SetupIncludes ;
368	SetupObjectsDir ;
369	AddResources $(1) : $(4) ;
370	Main $(1) : $(2) ;
371	MakeLocate $(1) : $(OBOS_BIN_DIR) ;
372	LinkSharedOSLibs $(1) : $(3) ;
373	LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
374						-Xlinker -soname=_APP_ ;
375}
376
377rule StdBinCommands
378{
379	# StdBinCommands <sources> : <libs> : <res> ;
380	SetupIncludes ;
381	SetupObjectsDir ;
382	local libs = $(2) ;
383	local ress = $(3) ;
384	local source ;
385	for source in $(1)
386	{
387		local target = $(source:S=) ;
388		target = [ FGristFiles $(target) ] ;
389
390		BinCommand $(target) : $(source) : $(libs) : $(ress) ;
391	}
392}
393
394rule Preference
395{
396	# Preference <name> : <sources> : <libraries> ;
397	SetupIncludes ;
398	SetupObjectsDir ;
399	Main $(1) : $(2) ;
400	MakeLocate $(1) : $(OBOS_PREFS_DIR) ;
401	LinkSharedOSLibs $(1) : $(3) ;
402	LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
403						-Xlinker -soname=_APP_ ;
404}
405
406rule Server
407{
408	# Server <name> : <sources> : <libraries> ;
409
410	SetupIncludes ;
411	SetupObjectsDir ;
412	Main $(1) : $(2) ;
413	MakeLocate $(1) : $(OBOS_SERVER_DIR) ;
414	LinkSharedOSLibs $(1) : $(3) ;
415	LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
416						-Xlinker -soname=_APP_ ;
417}
418
419# test pseudo targets
420NOTFILE obostests ;
421NOTFILE r5tests ;
422
423rule CommonTestLib
424{
425	# CommonTestLib <target> : <sources> : <obos libraries>
426	#	: <r5 libraries> : <test libraries> : <public headers>;
427	# Builds a unit test for both OBOS and R5 modules.
428	# <target> The name of the target.
429	# <sources> The list of sources.
430	# <obos libraries> A list of link libraries for the OBOS tests (as passed
431	# to LinkSharedOSLibs).
432	# <r5 libraries> A list of link libraries for the R5 tests (as passed
433	# to LinkSharedOSLibs).
434	# <test libraries> A list of link libraries for both OBOS tests and R5 tests
435	# that have a common name (i.e. specify libx.so and the OBOS tests will link
436	# to libx.so and the R5 tests will link to libx_r5.so).
437	# <public headers> A list of public header dirs (as passed to
438	# UsePublicHeaders).
439
440	TestLib $(1) : $(2) : [ FDirName $(OBOS_TEST_DIR) unittester lib ] : $(3) $(5) : $(6) ;
441	R5TestLib $(1) : $(2) : [ FDirName $(OBOS_TEST_DIR) unittester_r5 lib ] : $(4) [ R5SharedLibraryNames $(5) ] ;
442}
443
444rule TestLib
445{
446	# TestLib <target> : <sources> : <dest> : <libraries> : <public headers>
447	# Builds a unit test library for an OBOS module.
448	# <target> The name of the target.
449	# <sources> The list of sources.
450	# <dest> The directory for the target (as passed to FDirName).
451	# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
452	# <public headers> A list of public header dirs (as passed to
453	# UsePublicHeaders).
454
455	local target = $(1) ;
456	local sources = $(2) ;
457	local dest = $(3) ;
458	local libraries = $(4) ;
459	local headerDirs = $(5) ;
460	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
461
462	# Our Main replacement.
463	MainFromObjects $(target) : $(objects) ;
464	TestObjects $(sources) : $(headerDirs) ;
465
466	MakeLocate $(target) : $(dest) ;
467	Depends $(target) : libcppunit.so ;
468	Depends obostests : $(target) ;
469	LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ;
470	LINKFLAGS on $(target) = $(LINKFLAGS) -nostart -Xlinker -soname=\"$(target)\" ;
471}
472
473rule R5TestLib
474{
475	# R5TestLib <target> : <sources> : <dest> : <libraries>
476	# Builds a unit test for an R5 module. "_r5" is appended to the object
477	# and the target name.
478	# <target> The name of the target.
479	# <sources> The list of sources.
480	# <dest> The directory for the target (as passed to FDirName).
481	# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
482
483	local target = $(1:B)_r5$(1:S) ;
484	local sources = $(2) ;
485	local dest = $(3) ;
486	local libraries = $(4) ;
487	local objects = [ R5ObjectNames $(sources) ] ;
488
489	# Our Main replacement.
490	MainFromObjects $(target) : $(objects) ;
491	TestObjects $(sources) : : true ;
492
493	MakeLocate $(target) : $(dest) ;
494	Depends $(target) : libcppunit.so ;
495	Depends r5tests : $(target) ;
496	LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ;
497	LINKFLAGS on $(target) = $(LINKFLAGS) -nostart -Xlinker -soname=\"$(target)\" ;
498}
499
500rule CommonUnitTest
501{
502	# CommonUnitTest <target> : <sources> : <dest> : <obos libraries>
503	#	: <r5 libraries> : <public headers>;
504	# Builds a unit test for both OBOS and R5 modules.
505	# <target> The name of the target.
506	# <sources> The list of sources.
507	# <dest> The directory for the target (as passed to FDirName).
508	# <obos libraries> A list of link libraries for the OBOS tests (as passed
509	# to LinkSharedOSLibs).
510	# <r5 libraries> A list of link libraries for the R5 tests (as passed
511	# to LinkSharedOSLibs).
512	# <public headers> A list of public header dirs (as passed to
513	# UsePublicHeaders).
514
515	UnitTest $(1) : $(2) : $(3) : $(4) : $(6) ;
516	R5UnitTest $(1) : $(2) : $(3) : $(5) ;
517}
518
519rule UnitTest
520{
521	# UnitTest <target> : <sources> : <dest> : <libraries> : <public headers>
522	# Builds a unit test for an OBOS module.
523	# <target> The name of the target.
524	# <sources> The list of sources.
525	# <dest> The directory for the target (as passed to FDirName).
526	# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
527	# <public headers> A list of public header dirs (as passed to
528	# UsePublicHeaders).
529
530	local target = $(1) ;
531	local sources = $(2) ;
532	local dest = $(3) ;
533	local libraries = $(4) ;
534	local headerDirs = $(5) ;
535	local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
536
537	# Our Main replacement.
538	MainFromObjects $(target) : $(objects) ;
539	TestObjects $(sources) : $(headerDirs) ;
540
541	MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(dest) ] ;
542	Depends $(target) : libcppunit.so ;
543	Depends obostests : $(target) ;
544	LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ;
545}
546
547rule R5UnitTest
548{
549	# R5UnitTest <target> : <sources> : <dest> : <libraries>
550	# Builds a unit test for an R5 module. "_r5" is appended to the object
551	# and the target name.
552	# <target> The name of the target.
553	# <sources> The list of sources.
554	# <dest> The directory for the target (as passed to FDirName).
555	# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
556
557	local target = $(1)_r5 ;
558	local sources = $(2) ;
559	local dest = $(3) ;
560	local libraries = $(4) ;
561	local objects = [ R5ObjectNames $(sources) ] ;
562
563	# Our Main replacement.
564	MainFromObjects $(target) : $(objects) ;
565	TestObjects $(sources) : : true ;
566
567	MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(dest) ] ;
568	Depends $(target) : libcppunit.so ;
569	Depends r5tests : $(target) ;
570	LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ;
571}
572
573rule R5ObjectNames
574{
575	# R5ObjectNames <sources> ;
576	# Returns a list of gristed object names given a list of source file names.
577	# Moreover each object names gets "_r5" inserted before the object suffix.
578	local objects = $(1:S=)_r5 ;
579	return [ FGristFiles $(objects:S=$(SUFOBJ)) ] ;
580}
581
582rule R5Objects
583{
584	# R5Objects <sources>
585	# Similar to Objects, but appends "_r5" to the object file names and
586	# removes `-nostdinc' from the CC and C++ flags to enable system headers.
587	# <sources> The source files.
588
589	# Remove `-nostdinc' from CCFLAGS and C++FLAGS.
590	local oldCCFLAGS = $(CCFLAGS) ;
591	local oldC++FLAGS = $(C++FLAGS) ;
592	CCFLAGS = [ Filter $(CCFLAGS) : -nostdinc ] ;
593	C++FLAGS = [ Filter $(C++FLAGS) : -nostdinc ] ;
594
595	local sources = $(1) ;
596	local source ;
597	for source in [ FGristFiles $(sources) ]
598	{
599		local object = [ R5ObjectNames $(source) ] ;
600		Object $(object) : $(source) ;
601		LocalDepends obj : $(object) ;
602	}
603
604	# Reset CCFLAGS and C++FLAGS to original values.
605	CCFLAGS = $(oldCCFLAGS) ;
606	C++FLAGS = $(oldC++FLAGS) ;
607}
608
609rule TestObjects
610{
611	# TestLib <sources> : <public headers> : <r5>
612	# Compiles objects for tests.
613	# <sources> The list of sources.
614	# <public headers> A list of public header dirs (as passed to
615	# UsePublicHeaders).
616	# <r5> If set, "_r5" is appended to the object file names and
617	# <public headers> is ignored. Furthermore the pre-processor macro
618	# TEST_R5 is defined, TEST_OBOS otherwise.
619
620	local sources = $(1) ;
621	local headerDirs = $(2) ;
622	local r5 = $(3) ;
623	local objects ;
624
625	# Turn optimization off.
626	if ! $(NO_TEST_DEBUG) {
627		local optim = $(OPTIM) ;
628		OPTIM = ;
629	}
630
631	SetupObjectsDir ;
632
633	# compile
634	if $(r5) {
635		SetupR5Includes ;
636		objects = [ R5ObjectNames $(sources) ] ;
637		R5Objects $(sources) ;
638	} else {
639		SetupIncludes ;
640		objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
641		Objects $(sources) ;
642	}
643
644	# set headers/defines
645	UseCppUnitObjectHeaders $(sources) : $(objects) ;
646	if $(r5) {
647		ObjectsDefines $(objects) : TEST_R5 ;
648	} else {
649		UsePublicObjectHeaders $(sources) : $(headerDirs) : $(objects) ;
650		ObjectsDefines $(objects) : TEST_OBOS ;
651	}
652
653	if ! $(NO_TEST_DEBUG) {
654		# Turn debugging on. That is usually desired for test code.
655		ObjectCcFlags $(objects) : "-g" ;
656		ObjectC++Flags $(objects) : "-g" ;
657
658		# Turn optimization on again.
659		OPTIM = $(optim) ;
660	}
661}
662
663rule R5SharedLibraryNames
664{
665	# R5SharedLibraryNames <sources> ;
666	# Returns a list of shared library names given a list of file names. NO
667	# GRISTING IS PERFORMED :-) However, each library names gets "_r5" inserted
668	# before the shared lib suffix.
669	return $(1:S=)_r5.so ;
670}
671
672rule SimpleTest
673{
674	# UnitTest <target> : <sources> : <libraries>
675	# Builds a unit test for an OBOS module.
676	# <target> The name of the target.
677	# <sources> The list of sources.
678	# <dest> The directory for the target (as passed to FDirName).
679	# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
680	# <public headers> A list of public header dirs (as passed to
681	# UsePublicHeaders).
682
683	local target = $(1) ;
684	local sources = $(2) ;
685	local libraries = $(3) ;
686	local relPath = [ FRelPath src tests : $(SUBDIR_TOKENS) ] ;
687
688	# Turn optimization off.
689	if ! $(NO_TEST_DEBUG) {
690		local optim = $(OPTIM) ;
691		OPTIM = ;
692	}
693
694	SetupIncludes ;
695	SetupObjectsDir ;
696	MakeLocateObjects $(sources) ;
697	Main $(target) : $(sources) ;
698	MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(relPath) ] ;
699	Depends obostests : $(target) ;
700	LinkSharedOSLibs $(target) : $(libraries) ;
701	ObjectsDefines $(sources) : TEST_OBOS ;
702	if ! $(NO_TEST_DEBUG) {
703		# Turn debugging on. That is usually desired for test code.
704		ObjectCcFlags $(sources) : "-g" ;
705		ObjectC++Flags $(sources) : "-g" ;
706
707		# Turn optimization on again.
708		OPTIM = $(optim) ;
709	}
710}
711
712rule Addon
713{
714	# Addon <name> : <relpath> : <sources> : <is executable> : <libraries> ;
715	# <name>: Name of the add-on.
716	# <relpath>: Path where the add-on shall live relative to the add-on dir.
717	# <sources>: Source files.
718	# <is executable>: true, if the target shall be executable as well.
719	# <libraries>: Libraries to be linked against.
720
721	local isExecutable = $(4) ;
722
723	SetupIncludes ;
724	SetupObjectsDir ;
725	Main $(1) : $(3) ;
726
727	# Create output dir path for addon
728	local targetdir;
729	targetdir = [ FDirName $(OBOS_ADDON_DIR) $(2) ] ;
730
731	MakeLocate $(1) : $(targetdir) ;
732
733	local linkFlags = -Xlinker -soname=\"$(1)\" ;
734	if $(isExecutable) != true {
735		linkFlags = -nostart $(linkFlags) ;
736	}
737	LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ] $(linkFlags) ;
738	LinkSharedOSLibs $(1) : $(5) ;
739}
740
741rule R5KernelAddon
742{
743	# R5KernelAddon <name> : <relpath> : <sources> : <static-libraries> ;
744
745	local sources = $(3) ;
746
747	Addon $(1) : $(2) : $(3) ;
748	ObjectCcFlags $(sources) : -D_KERNEL_MODE=1 -no-fpic ;
749	ObjectC++Flags $(sources) : -D_KERNEL_MODE=1 -no-fpic
750								-fno-exceptions -fno-rtti ;
751	LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ] -nostdlib ;
752	LinkSharedOSLibs $(1) : $(4) /boot/develop/lib/x86/_KERNEL_ ;
753}
754
755rule Translator
756{
757	# Translator <name> : <sources> : <libraries> ;
758	SetupIncludes ;
759	SetupObjectsDir ;
760	Main $(1) : $(2) ;
761	LinkSharedOSLibs $(1) : $(3) ;
762
763	# Create output dir path for translator
764	local targetdir;
765	targetdir = [ FDirName $(OBOS_ADDON_DIR) Translators ] ;
766	MakeLocate $(1) : $(targetdir) ;
767}
768
769rule MakeLocateObjects
770{
771	# MakeLocateObjects <sources_or_objects> ;
772
773	local _objs = [ FGristFiles $(1:S=$(SUFOBJ)) ] ;
774
775	for o in $(_objs)
776	{
777		local dir = $(o:D) ;
778		if $(dir) {
779			MakeLocate $(o) : [ FDirName $(LOCATE_TARGET) $(dir) ] ;
780		} else {
781			MakeLocate $(o) : $(LOCATE_TARGET) ;
782		}
783	}
784}
785
786rule StaticLibrary
787{
788	# StaticLibrary <name> : <sources> [ : <target dir> ] ;
789	# Creates a static library from sources.
790	# <name>: Basename of the library, without leading "lib" and trailing ".a".
791	#         Grist is allowed -- it will be re-prepended after constructing
792	#         the complete library name.
793	# <source>: List of source files.
794	# <target dir>: Directory into which the library shall be placed. Defaults
795	#               to the objects directory for this subdir. If
796	#               STATIC_LIBRARY_DIR is supplied (the literal string)
797	#               the standard directory for static libs is used, otherwise
798	#               the parameter is interpreted as directory path.
799	#
800	local lib = lib$(1:B)$(SUFLIB) ;
801	lib = $(lib:G=$(1:G)) ;
802	SetupIncludes ;
803	SetupObjectsDir ;
804	MakeLocateObjects $(2) ;
805	Library $(lib) : $(2) ;
806	local targetDir = $(3) ;
807	if $(targetDir) {
808		if $(targetDir) = STATIC_LIBRARY_DIR {
809			targetDir = $(OBOS_STLIB_DIR) ;
810		}
811		MakeLocate $(lib) : $(targetDir) ;
812	} else {
813		# nothing to do, since the Library rule already located the library
814		# in $(LOCATE_TARGET)
815	}
816
817	# If KEEPOBJS is set, Library doesn't make the library depend on
818	# `lib'.
819	if $(KEEPOBJS) {
820		LocalDepends lib : $(lib) ;
821	}
822}
823
824rule R5KernelStaticLibrary
825{
826	# R5KernelStaticLibrary <name> : <sources> ;
827
828	local lib = lib$(1)$(SUFLIB) ;
829	local sources = $(2) ;
830
831	SetupIncludes ;
832	SetupObjectsDir ;
833	MakeLocateObjects $(sources) ;
834	Library $(lib) : $(sources) ;
835	ObjectCcFlags $(sources) : -D_KERNEL_MODE=1 -no-fpic ;
836	ObjectC++Flags $(sources) : -D_KERNEL_MODE=1 -no-fpic
837								-fno-exceptions -fno-rtti ;
838}
839
840rule MergeObjectFromObjects
841{
842	# MergeObjectFromObjects <name> : <objects> : <other objects> ;
843	# Merges object files to an object file.
844	# <name>: Name of the object file to create. No grist will be added.
845	# <objects>: Object files to be merged. Grist will be added.
846	# <other objects>: Object files or static libraries to be merged. No grist
847	#                  will be added.
848	#
849	local objects = [ FGristFiles $(2) ] ;
850	MakeLocate $(1) : $(LOCATE_TARGET) ;
851	Depends $(1) : $(objects) ;
852	Depends $(1) : $(3) ;
853	LINK on $(1) = ld ;
854	MergeObjectFromObjects1 $(1) : $(objects) $(3) ;
855}
856
857actions MergeObjectFromObjects1
858{
859	$(LINK) -r $(2) -o $(1) ;
860}
861
862rule MergeObject
863{
864	# MergeObject <name> : <sources> : <other objects> ;
865	# Compiles source files and merges the object files to an object file.
866	# <name>: Name of the object file to create. No grist will be added.
867	# <sources>: Sources to be compiled. Grist will be added.
868	# <other objects>: Object files or static libraries to be merged. No grist
869	#                  will be added.
870	#
871	SetupIncludes ;
872	SetupObjectsDir ;
873	MakeLocateObjects $(2) ;
874	Objects $(2) ;
875	MergeObjectFromObjects $(1) : $(2:S=$(SUFOBJ)) : $(3) ;
876}
877
878rule SharedLibraryFromObjects
879{
880	# SharedLibraryFromObjects <name> : <objects> : <libraries> ;
881	local _lib = lib$(1:B).so ;
882	_lib = $(_lib:G=$(1:G)) ;
883	MainFromObjects $(_lib) : $(2) ;
884	MakeLocate $(_lib) : $(OBOS_SHLIB_DIR) ;
885	LINKFLAGS on $(_lib) = [ on $(_lib) return $(LINKFLAGS) ]
886						   -nostart -Xlinker -soname=\"$(_lib)\" ;
887	LinkSharedOSLibs $(_lib) : $(3) ;
888}
889
890rule SharedLibrary
891{
892	# SharedLibrary <name> : <sources> : <libraries> ;
893	SetupIncludes ;
894	SetupObjectsDir ;
895	MakeLocateObjects $(2) ;
896	Objects $(2) ;
897	SharedLibraryFromObjects $(1) : $(2:S=$(SUFOBJ)) : $(3) ;
898}
899
900rule LinkSharedOSLibs
901{
902	# LinkSharedOSLibs <name> : <libs> ;
903	# Valid elements for <libs> are e.g. "be" or "libopenbeos.so" or
904	# "/boot/.../libfoo.so". If the basename starts with "lib" or the thingy
905	# has a dirname or grist, it is added to the NEEDLIBS variable (i.e. the
906	# file will be bound!), otherwise it is prefixed "-l" and added to
907	# LINKLIBS. If you want to specify a target that isn't a library and
908	# also has neither grist nor a dirname, you can prepend "<nogrist>" as
909	# grist; it will be stripped by this rule.
910
911	for i in $(>)
912	{
913		local isfile = ;
914		if $(i:D) || $(i:G) {
915			isfile = true ;
916			if $(i:G) = <nogrist> {
917				i = $(i:G=) ;
918			}
919		} else {
920			switch $(i:B)
921			{
922				# XXX: _APP_ and _KERNEL_ should not be needed for ELF.
923				case _APP_ : isfile = true ;
924				case _KERNEL_ : isfile = true ;
925				case lib*	: isfile = true ;
926				case *	: isfile = ;
927			}
928			if ! $(isfile) && ( $(i:S) = .so || $(i:S) = .a ) {
929				isfile = true ;
930			}
931		}
932		if $(isfile) {
933			NEEDLIBS on $(1) = [ on $(1) return $(NEEDLIBS) ] $(i) ;
934			Depends $(1) : $(i) ;
935		} else {
936			LINKLIBS on $(1) = [ on $(1) return $(LINKLIBS) ] -l$(i) ;
937		}
938	}
939}
940
941rule LinkStaticOSLibs
942{
943	# LinkStaticOSLibs <name> : <libs> ;
944
945	for i in $(>)
946	{
947		LINKLIBS on $(<) = $(LINKLIBS) -l $(i) ;
948	}
949}
950
951rule AddResources
952{
953	# AddResources <name> : <resourcefiles> ;
954
955	local resfiles = [ FGristFiles $(2) ] ;
956	SEARCH on $(resfiles) += $(SEARCH_SOURCE) ;
957
958	for file in $(resfiles) {
959		if $(file:S) = .rdef {
960			local rdef = $(file) ;
961			file = $(rdef:S=.rsrc) ;
962			ResComp $(file) : $(rdef) ;
963		}
964		RESFILES on $(1) += $(file) ;
965	}
966}
967
968rule ResComp
969{
970	# ResComp <resource file> : <rdef file> ;
971	#
972	# <resource file> and <rdef file> must be gristed.
973
974	SetupObjectsDir ;
975
976	SEARCH on $(2) += $(SEARCH_SOURCE) ;
977	MakeLocate $(1) : $(LOCATE_TARGET) ;
978	Depends $(1) : $(2) rc ;
979	LocalClean clean : $(1) ;
980	ResComp1 $(1) : rc $(2) ;
981}
982
983actions ResComp1
984{
985	$(2[1]) -o $(1) $(2[2-])
986}
987
988rule ObjectsDefines
989{
990	# Like ObjectDefines, but allows multiple files to be supplied
991	local file ;
992	for file in $(1) {
993		ObjectDefines $(file) : $(2) ;
994	}
995}
996
997rule SourceHdrs
998{
999	# SourceHdrs <sources> : <headers> [ : <gristed objects> ] ;
1000	#
1001	# Is a wrapper for ObjectHdrs, that passes <sources> and <headers> or,
1002	# if supplied <objects> and <headers>, and also adjusts HDRSEARCH (not
1003	# done by ObjectHdrs).
1004
1005	local sources = [ FGristFiles $(1) ] ;
1006	local headers = $(2) ;
1007	local objects = $(3) ;
1008
1009	local file ;
1010	if $(objects) {
1011		for file in $(objects) {
1012			ObjectHdrs $(file) : $(headers) ;
1013		}
1014	} else {
1015		for file in $(sources) {
1016			ObjectHdrs $(file) : $(headers) ;
1017		}
1018	}
1019
1020	# Also add the header search dirs to HDRSEARCH. Note, that these dirs
1021	# will be listed after the STDHDRS (if any), but that's better than not
1022	# being listed at all.
1023	HDRSEARCH on $(sources) += $(headers) ;
1024}
1025
1026rule PublicHeaders
1027{
1028	# PublicHeaders <group list>
1029	#
1030	# Returns the directory names for the public header dirs identified by
1031	# <group list>.
1032
1033	local list = $(1) ;
1034	local dirs = [ FDirName $(OBOS_TOP) headers os ] ;
1035
1036	for i in $(list) {
1037		dirs += [ FDirName $(OBOS_TOP) headers os $(i) ] ;
1038	}
1039	return $(dirs) ;
1040}
1041
1042rule PrivateHeaders
1043{
1044	# PrivateHeaders <group list>
1045	#
1046	# Returns the directory names for the private header dirs identified by
1047	# <group list>.
1048
1049	local list = $(1) ;
1050	local dirs ;
1051	for i in $(list) {
1052		dirs += [ FDirName $(OBOS_TOP) headers private $(i) ] ;
1053	}
1054	return $(dirs) ;
1055}
1056
1057rule LibraryHeaders
1058{
1059	# LibraryHeaders <group list>
1060	#
1061	# Returns the directory names for the library header dirs identified by
1062	# <group list>.
1063
1064	local list = $(1) ;
1065	local dirs ;
1066	for i in $(list) {
1067		dirs += [ FDirName $(OBOS_TOP) headers libs $(i) ] ;
1068	}
1069	return $(dirs) ;
1070}
1071
1072rule ArchHeaders
1073{
1074	# usage: ArchHeaders <arch> ;
1075	#
1076	# <arch> specifies the architecture (e.g. x86).
1077
1078	return [ FDirName $(OBOS_TOP) headers private kernel arch $(1) ] ;
1079}
1080
1081rule UsePublicHeaders
1082{
1083	# UsePublicHeaders <group list> ;
1084	#
1085	# Adds the public C header dirs given by <group list> to the header search
1086	# dirs of the subdirectory.
1087	# NOTE: This rule must be invoked *before* the rule that builds the
1088	# objects.
1089
1090	UseHeaders [ PublicHeaders $(1) ] ;
1091}
1092
1093rule UsePublicObjectHeaders
1094{
1095	# UsePublicObjectHeaders <sources> : <group list> [ : <objects> ] ;
1096	#
1097	# Adds the public C header dirs given by <group list> to the header search
1098	# dirs of either the object targets of <sources> or if supplied to
1099	# <objects>. Also adjusts HDRSEARCH of <sources>.
1100	# NOTE: This rule must be invoked *after* the rule that builds the objects.
1101
1102	SourceHdrs $(1) : [ PublicHeaders $(2) ] : $(3) ;
1103}
1104
1105rule UsePrivateHeaders
1106{
1107	# UsePrivateHeaders <group list> ;
1108	#
1109	# Adds the private C header dirs given by <group list> to the header search
1110	# dirs of the subdirectory.
1111	# NOTE: This rule must be invoked *before* the rule that builds the objects.
1112
1113	UseHeaders [ PrivateHeaders $(1) ] ;
1114}
1115
1116rule UsePrivateObjectHeaders
1117{
1118	# UsePrivateObjectHeaders <sources> : <group list> [ : <objects> ] ;
1119	#
1120	# Adds the private C header dirs given by <group list> to the header search
1121	# dirs of either the object targets of <sources> or if supplied to
1122	# <objects>. Also adjusts HDRSEARCH of <sources>.
1123	# NOTE: This rule must be invoked *after* the rule that builds the objects.
1124
1125	SourceHdrs $(1) : [ PrivateHeaders $(2) ] : $(3) ;
1126}
1127
1128rule UseHeaders
1129{
1130	# UseHeaders <headers> ;
1131	#
1132	# Adds the C header dirs <headers> to the header search
1133	# dirs of the subdirectory.
1134	# NOTE: This rule must be invoked *before* the rule that builds the objects.
1135
1136	local header ;
1137	for header in $(1) {
1138		SubDirHdrs $(header) ;
1139	}
1140}
1141
1142rule UseCppUnitHeaders
1143{
1144	SubDirHdrs [ FDirName $(OBOS_TOP) headers tools cppunit ] ;
1145}
1146
1147rule UseCppUnitObjectHeaders
1148{
1149	# UseCppUnitObjectHeaders <sources> [ : <objects> ] ;
1150	SourceHdrs $(1) : [ FDirName $(OBOS_TOP) headers tools cppunit ] : $(2) ;
1151}
1152
1153rule UseArchHeaders
1154{
1155	# usage: UseArchHeaders <arch> ;
1156	#
1157	# <arch> specifies the architecture (e.g. x86).
1158	# NOTE: This rule must be invoked *before* the rule that builds the objects.
1159
1160	local headers = [ ArchHeaders $(1) ] ;
1161	local opt = -D$(OBOS_TARGET_DEFINE) ;
1162
1163	SubDirCcFlags $(opt)  ;
1164	SubDirC++Flags $(opt)  ;
1165	HDRS += $(headers) ;
1166}
1167
1168rule UseArchObjectHeaders
1169{
1170	# usage: UseArchObjectHeaders <sources> : <arch> : [ <objects> ] ;
1171	#
1172	# <arch> specifies the architecture (e.g. x86).
1173	# <sources_or_objects> Source or object files.
1174	# NOTE: This rule must be invoked *after* the rule that builds the objects.
1175
1176	local sources = $(1) ;
1177	local headers = [ ArchHeaders $(2) ] ;
1178	local objects = $(3) ;
1179	local targets ;
1180	if $(objects) {
1181		targets = $(objects) ;
1182	} else {
1183		targets = $(sources) ;
1184	}
1185	local opt = -D$(OBOS_TARGET_DEFINE) ;
1186
1187	ObjectCcFlags $(targets) : $(opt)  ;
1188	ObjectC++Flags $(targets) : $(opt)  ;
1189	SourceHdrs $(sources) : $(headers) : $(objects) ;
1190}
1191
1192rule UsePosixHeaders
1193{
1194	# XXX changed to do nothing
1195}
1196
1197rule UsePosixObjectHeaders
1198{
1199	# UsePosixObjectHeaders <sources> [ : <objects> ] ;
1200	#
1201	# Adds the POSIX header dir to the header search
1202	# dirs of either the object targets of <sources> or if supplied to
1203	# <objects>. Also adjusts HDRSEARCH of <sources>.
1204	# NOTE: This rule must be invoked *after* the rule that builds the objects.
1205
1206	SourceHdrs $(1) : [ FDirName $(OBOS_TOP) headers posix ] : $(2) ;
1207}
1208
1209rule UseLibraryHeaders
1210{
1211	# UseLibraryHeaders <group list> ;
1212	#
1213	# Adds the library header dirs given by <group list> to the header search
1214	# dirs of the subdirectory.
1215	# NOTE: This rule must be invoked *before* the rule that builds the objects.
1216
1217	UseHeaders [ LibraryHeaders $(1) ] ;
1218}
1219
1220rule SplitPath
1221{
1222	# SplitPath <path> ;
1223	# Decomposes a path into its components.
1224	local path = $(1:G=) ;
1225	local components ;
1226	# $(path:D) for "/" is "/". Therefore the second condition.
1227	while $(path:D) && $(path:D) != $(path)
1228	{
1229		# Note: $(path:B) returns "." for "..", but $(path:D=) is fine.
1230		components = $(path:D=) $(components) ;
1231		path = $(path:D) ;
1232	}
1233	components = $(path) $(components) ;
1234	return $(components) ;
1235}
1236
1237rule PrependObjectHdrs
1238{
1239	# PrependObjectHdrs <objects_or_sources> : <dirs> ;
1240	# Prepends <dirs> to the list of header search dirs of the objects
1241	# specified by <objects_or_sources>. The HDRS variable will not be
1242	# changed, only CCHDRS.
1243	# Note: A subsequent ObjectHdrs invocation will therefore undo the
1244	# effect of this rule.
1245	# NOTE: This is a hack.
1246
1247	local objects = [ FGristFiles $(1:S=$(SUFOBJ)) ] ;
1248	local dirs = $(2) ;
1249	for object in $(objects) {
1250		# Don't change HDRS to avoid screwing up the header scanning.
1251		PREPENDED_HDRS on $(object)
1252			= $(dirs) [ on $(object) return $(PREPENDED_HDRS) ] ;
1253		CCHDRS on $(object)
1254			= [ FIncludes [ on $(object) return $(PREPENDED_HDRS) $(HDRS) ] ] ;
1255	}
1256}
1257
1258rule SymLink
1259{
1260	# SymLink <target> : <source> : <makeDefaultDependencies> ;
1261	# Links <target> to <source>.
1262	# <source> is the exact link contents. No binding is done.
1263	# <makeDefaultDependencies> If true, <target> will be made a dependency
1264	# of the `all' pseudo target, i.e. it will be made by default, and removed
1265	# on `jam clean'.
1266
1267	local target = $(1) ;
1268	local source = $(2) ;
1269	local makeDefaultDependencies = $(3) ;
1270	if ! $(makeDefaultDependencies) {
1271		makeDefaultDependencies = true ;
1272	}
1273	LINKCONTENTS on $(target) = $(source) ;
1274	SymLink1 $(target) ;
1275	if $(makeDefaultDependencies) = true {
1276		LocalDepends files : $(target) ;
1277		LocalClean clean : $(target) ;
1278	}
1279}
1280
1281actions SymLink1
1282{
1283	$(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)"
1284}
1285
1286rule RelSymLink
1287{
1288	# RelSymLink <link> : <link target> : <makeDefaultDependencies> ;
1289	# Creates a relative symbolic link from <link> to <link target>.
1290	# <link> and <link target> can be usual targets. They may have a grist
1291	# and don't need to have any dirname. Their LOCATE variables are used to
1292	# find their locations.
1293	# <makeDefaultDependencies> If true (which is the default), <link> will be
1294	# made a dependency of the `files' pseudo target, i.e. it will be made by
1295	# default, and removed on `jam clean'.
1296
1297	local target = $(1) ;
1298	local source = $(2) ;
1299	local makeDefaultDependencies = $(3) ;
1300	local targetDir = [ on $(target) FDirName $(LOCATE[1]) $(target:D) ] ;
1301	local sourceDir = [ on $(source) FDirName $(LOCATE[1]) $(source:D) ] ;
1302	local sourcePath = $(source:G=) ;
1303	sourcePath = $(sourcePath:D=$(sourceDir)) ;
1304	local targetDirComponents = [ SplitPath $(targetDir) ] ;
1305	local sourceComponents = [ SplitPath $(sourcePath) ] ;
1306
1307	SymLink $(target)
1308		: [ FRelPath $(targetDirComponents) : $(sourceComponents) ]
1309		: $(makeDefaultDependencies) ;
1310	NOUPDATE $(target) ;
1311	Depends $(target) : $(source) ;
1312}
1313
1314rule AbsSymLink
1315{
1316	# AbsSymLink <link> : <link target> : <link dir>
1317	#			: <makeDefaultDependencies> ;
1318	# Creates an absolute symbolic link from <link> to <link target>.
1319	# <link> and <link target> must be usual targets. If <link dir> is
1320	# given, then it is set as LOCATE directory on <link>.
1321	# <makeDefaultDependencies> If true (which is the default), <link> will be
1322	# made a dependency of the `files' pseudo target, i.e. it will be made by
1323	# default, and removed on `jam clean'.
1324
1325	local makeDefaultDependencies = $(4) ;
1326	if ! $(makeDefaultDependencies) {
1327		makeDefaultDependencies = true ;
1328	}
1329
1330	Depends $(1) : $(2) ;
1331	if $(3) {
1332		MakeLocate $(1) : $(3) ;
1333	}
1334	SEARCH on $(2) += $(SEARCH_SOURCE) ;
1335	if $(makeDefaultDependencies) = true {
1336		LocalDepends files : $(1) ;
1337		LocalClean clean : $(1) ;
1338	}
1339}
1340
1341actions AbsSymLink
1342{
1343	target="$(2)"
1344	case "$target" in
1345		/*) ;;
1346		*) target=`pwd`/"$target";;
1347	esac
1348	$(RM) "$(1)" && $(LN) -s "$target" "$(1)"
1349}
1350
1351rule OBOSInstall
1352{
1353	# Usage: OBOSInstall <[ install [ and uninstall ] pseudotarget ]>
1354	#					 : <directory> : <sources to install>
1355	#					 : [ <installgrist> ] : [ <install rule> ] ;
1356	local install = $(1[1]) ;
1357	install ?= install ;
1358	local uninstall = $(1[2]) ;
1359	uninstall ?= un$(install) ;
1360	local dir = $(2) ;
1361	local sources = $(3) ;
1362	local installgrist = $(4) ;
1363	installgrist ?= $(INSTALLGRIST) ;
1364	local installRule = $(5) ;
1365	installRule ?= Install ;
1366	local targets = $(sources:G=$(installgrist)) ;
1367
1368	NotFile $(install) ;
1369	NotFile $(uninstall) ;
1370	Depends $(install) : $(targets) ;
1371	Clean $(uninstall) : $(targets) ;
1372
1373	SEARCH on $(sources) += $(SEARCH_SOURCE) ;
1374	MakeLocate $(targets) : $(dir) ;
1375
1376	local source ;
1377	for source in $(sources) {
1378		local target = $(source:G=$(installgrist)) ;
1379
1380		Depends $(target) : $(source) ;
1381		$(installRule) $(target) : $(source) ;
1382
1383		if [ on $(target) return $(MODE) ] {
1384			Chmod $(target) ;
1385		}
1386
1387		if $(OWNER) && $(CHOWN) {
1388			Chown $(target) ;
1389			OWNER on $(target) = $(OWNER) ;
1390		}
1391
1392		if $(GROUP) && $(CHGRP) {
1393			Chgrp $(target) ;
1394			GROUP on $(target) = $(GROUP) ;
1395		}
1396	}
1397}
1398
1399rule InstallAbsSymLinkAdapter
1400{
1401	# InstallAbsSymLinkAdapter <link> : <link target>
1402	if ! [ on $(2) return $(TARGET) ] {
1403		TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
1404	}
1405	AbsSymLink $(1) : $(2) : : false ;
1406}
1407
1408rule OBOSInstallAbsSymLink
1409{
1410	# Usage: OBOSInstallAbsSymLink <[ install [ and uninstall ] pseudotarget ]>
1411	#							   : <directory> : <sources to install>
1412	#							   : [ <installgrist> ] ;
1413	OBOSInstall $(1) : $(2) : $(3) : $(4) : InstallAbsSymLinkAdapter ;
1414}
1415
1416rule InstallRelSymLinkAdapter
1417{
1418	# InstallRelSymLinkAdapter <link> : <link target>
1419	if ! [ on $(2) return $(TARGET) ] {
1420		TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
1421	}
1422	RelSymLink $(1) : $(2) : false ;
1423}
1424
1425rule OBOSInstallRelSymLink
1426{
1427	# Usage: OBOSInstallRelSymLink <[ install [ and uninstall ] pseudotarget ]>
1428	#							   : <directory> : <sources to install>
1429	#							   : [ <installgrist> ] ;
1430	OBOSInstall $(1) : $(2) : $(3) : $(4) : InstallRelSymLinkAdapter ;
1431}
1432
1433
1434#-------------------------------------------------------------------------------
1435# Low-level OBOS utility rules
1436#-------------------------------------------------------------------------------
1437rule SetupObjectsDir
1438{
1439	local rel_objectsdir;
1440
1441	# Copy subdir tokens except the first, as that will be "sources", and we
1442	# do not want to include that :)
1443	rel_objectsdir = [ FDirName $(SUBDIR_TOKENS[2-]) ] ;
1444	LOCATE_TARGET = [ FDirName $(OBOS_OBJECT_TARGET) $(rel_objectsdir) ] ;
1445	LOCATE_SOURCE = $(LOCATE_TARGET) ;
1446	SEARCH_SOURCE = [ Filter $(SEARCH_SOURCE) : $(LOCATE_TARGET) ]
1447					$(LOCATE_TARGET) ;
1448}
1449
1450#-------------------------------------------------------------------------------
1451# Link rule/action are overwritten as they don't handle linking files who's name
1452# contain spaces very well. Also adds resources and version to executable.
1453#-------------------------------------------------------------------------------
1454rule Link
1455{
1456	# Note: RESFILES must be set before invocation.
1457	MODE on $(<) = $(EXEMODE) ;
1458	on $(1) XRes $(1) : $(RESFILES) ;
1459	Chmod $(<) ;
1460	SetType $(1) ;
1461	MimeSet $(1) ;
1462	SetVersion $(1) ;
1463}
1464
1465actions Link bind NEEDLIBS
1466{
1467	$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(2)" "$(NEEDLIBS)" $(LINKLIBS) ;
1468}
1469
1470rule LexC++
1471{
1472	Depends $(1) : $(2) ;
1473	MakeLocate $(1) : $(LOCATE_SOURCE) ;
1474	LocalClean clean : $(1) ;
1475}
1476
1477actions LexC++
1478{
1479	$(LEX) -o$(1) $(2)
1480}
1481
1482rule Bison
1483{
1484	local _h ;
1485
1486	_h = $(1).h ;
1487
1488	MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;
1489
1490    Depends $(<) $(_h) : $(>) ;
1491    Bison1 $(<) $(_h) : $(>) ;
1492    LocalClean clean : $(<) $(_h) ;
1493
1494	# make sure someone includes $(_h) else it will be
1495	# a deadly independent target
1496
1497	Includes $(<) : $(_h) ;
1498}
1499
1500actions Bison1
1501{
1502	bison $(YACCFLAGS) -o $(1[1]) $(2)
1503}
1504
1505# BeOS specific rules
1506
1507rule XRes
1508{
1509	# XRes <target> : <resource files>
1510	if $(2)
1511	{
1512		Depends $(1) : $(2) ;
1513		XRes1 $(1) : $(2) ;
1514	}
1515}
1516
1517rule XRes1 { }
1518
1519rule SetVersion
1520{
1521	# SetVersion <target>
1522}
1523
1524rule SetType
1525{
1526	# SetType <target>
1527}
1528
1529rule MimeSet
1530{
1531	# SetType <target>
1532}
1533
1534
1535if $(OS) = BEOS
1536{
1537
1538actions XRes1
1539{
1540	xres -o "$(1)" "$(2)" ;
1541}
1542
1543actions SetVersion
1544{
1545	setversion "$(1)" -system $(OBOS_BUILD_VERSION) -short "$(OBOS_BUILD_DESCRIPTION)" ;
1546}
1547
1548actions SetType
1549{
1550	settype -t $(OBOS_TARGET_TYPE) "$(1)" ;
1551}
1552
1553actions MimeSet
1554{
1555	mimeset -f "$(1)" ;
1556}
1557
1558}	# if BEOS
1559
1560
1561rule assemble
1562{
1563	Depends $(<) : $(>) ;
1564	ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;
1565	ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
1566}
1567
1568actions assemble
1569{
1570	$(CC) -c "$(2)" -O2 $(ASFLAGS) -D_ASSEMBLER $(KERNEL_CCFLAGS) $(ASHDRS) -o "$(1)" ;
1571}
1572
1573# Overridden to allow spaces in file names.
1574actions Chmod1
1575{
1576	$(CHMOD) "$(MODE)" "$(1)"
1577}
1578
1579# Overridden to allow spaces in file names.
1580actions piecemeal together existing Clean
1581{
1582	$(RM) "$(>)"
1583}
1584
1585rule ObjectReference
1586{
1587	# ObjectReference <reference object> : <source object>
1588	# Makes <reference object> refer to the same file as <source object>.
1589	# The filenames must of course be identical.
1590	# <source object> must have already been LOCATEd.
1591
1592	local ref = $(1) ;
1593	local source = $(2) ;
1594	if $(ref) != $(source) {
1595		Depends $(ref) : $(source) ;
1596		LOCATE on $(ref) = [ on $(source) return $(LOCATE) ] ;
1597	}
1598}
1599
1600rule ObjectReferences
1601{
1602	# ObjectReferences <source objects>
1603	# Creates local references to <source objects>, i.e. identifiers with the
1604	# current grist referring to the same files. <source objects> must have
1605	# already been LOCATEd.
1606
1607	local source ;
1608	for source in $(1) {
1609		ObjectReference [ FGristFiles $(source) ] : $(source) ;
1610	}
1611}
1612
1613rule Filter
1614{
1615	# Filter <list> : <excludes> ;
1616	# Removes all occurrences of <excludes> in <list>.
1617
1618	local list = $(1) ;
1619	local excludes = $(2) ;
1620	local newList ;
1621	local item ;
1622	for item in $(list) {
1623		local skip ;
1624		local exclude ;
1625		for exclude in $(excludes) {
1626			if $(item) = $(exclude) {
1627				skip = true ;
1628			}
1629		}
1630		if ! $(skip) {
1631			newList += $(item) ;
1632		}
1633	}
1634	return $(newList) ;
1635}
1636
1637
1638## Kernel stuff!
1639
1640rule SetupKernel
1641{
1642	# Usage SetupKernel <sources_or_objects> : <extra_cc_flags>;
1643
1644	local _objs = [ FGristFiles $(1:S=$(SUFOBJ)) ] ;
1645
1646	#Setup Kernel header directories
1647	local public_kernel_includes = add-ons/file_system add-ons/graphics app device drivers kernel storage support ;
1648	local private_kernel_includes = kernel libroot kernel/boot/platform/$(OBOS_BOOT_PLATFORM) ;
1649	# Use posix headers directory
1650	HDRS = [ FDirName $(OBOS_TOP) headers posix ] ;
1651	# Use public OS header directories
1652	HDRS += [ PublicHeaders $(public_kernel_includes) ] ;
1653	# Use private directories
1654	HDRS += [ PrivateHeaders $(private_kernel_includes) ] ;
1655	# The platform dependent headers.
1656	HDRS += $(PLATFORM_HEADERS) ;
1657
1658	UseArchHeaders $(OBOS_ARCH) ;
1659
1660	SetupObjectsDir ;
1661
1662	CCFLAGS on $(_objs) = $(KERNEL_CCFLAGS) $(2) ;
1663	C++FLAGS on $(_objs) = $(KERNEL_C++FLAGS) $(2) ;
1664}
1665
1666rule KernelObjects
1667{
1668	SetupKernel $(1) : $(2) ;
1669
1670	Objects $(1) ;
1671}
1672
1673rule KernelLd
1674{
1675	# KernelLd <name> : <objs> : <linkerscript> : <args> : <gcc_off> : <config_section> ;
1676
1677	SetupKernel $(2) ;
1678	LINK on $(1) = ld ;
1679
1680	LINKFLAGS on $(1) = $(4) ;
1681	if $(3) { LINKFLAGS on $(1) += --script=$(3) ; }
1682
1683	# Remove any preset LINKLIBS
1684	LINKLIBS on $(1) =  ;
1685
1686	# Show that we depend on the libraries we need
1687	LocalClean clean : $(1) ;
1688	LocalDepends all : $(1) ;
1689	Depends $(1) : $(2) ;
1690
1691	if $(6) {
1692		for i in $(6) {
1693			KernelConfigSection $(i) : elf32 : $(1) ;
1694		}
1695	}
1696
1697	MakeLocate $(1) : $(LOCATE_TARGET) ;
1698
1699	# Add the platform specific static libs (libgcc.a).
1700	if ! $(5) {
1701		LINKLIBS on $(1) += $(PLATFORM_LINKLIBS) ;
1702	}
1703}
1704
1705actions KernelLd
1706{
1707	$(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" $(LINKLIBS) ;
1708}
1709
1710rule KernelAddon
1711{
1712	# KernelAddon <name> : <relpath> : <sources> : <static-libraries> ;
1713
1714	local sources = $(3) ;
1715
1716	SetupKernel $(3) ;
1717	Addon $(1) : $(2) : $(3) ;
1718	ObjectCcFlags $(sources) : -D_KERNEL_MODE=1 -no-fpic ;
1719	ObjectC++Flags $(sources) : -D_KERNEL_MODE=1 -no-fpic
1720								-fno-exceptions -fno-rtti ;
1721	LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ] -nostdlib ;
1722	LinkSharedOSLibs $(1) : $(4) $(OBOS_TOP)/objects/$(OBOS_ARCH).$(OBOS_VERSION)/kernel/kernel.so ;
1723		# ToDo this has to be changed!
1724}
1725
1726rule KernelMergeObject
1727{
1728	# KernelMergeObject <name> : <sources> : <extra CFLAGS> : <other objects> ;
1729	# Compiles source files and merges the object files to an object file.
1730	# <name>: Name of the object file to create. No grist will be added.
1731	# <sources>: Sources to be compiled. Grist will be added.
1732	# <extra CFLAGS>: Additional flags for compilation.
1733	# <other objects>: Object files or static libraries to be merged. No grist
1734	#                  will be added.
1735	#
1736
1737	SetupKernel $(2) : $(3) ;
1738
1739	MakeLocateObjects $(2) ;
1740	Objects $(2) ;
1741	MergeObjectFromObjects $(1) : $(2:S=$(SUFOBJ)) : $(4) ;
1742}
1743
1744rule KernelStaticLibrary
1745{
1746	# Usage KernelStaticLibrary <name> : <sources> : <extra cc flags>  ;
1747	# This is designed to take a set of sources and libraries and create
1748	# a file called lib<name>.a
1749
1750	SetupKernel $(2) : $(3) ;
1751
1752	MakeLocateObjects $(2) ;
1753	Library $(1) : $(2) ;
1754}
1755
1756rule KernelStaticLibraryObjects
1757{
1758	# Usage KernelStaticLibrary <name> : <sources> ;
1759	# This is designed to take a set of sources and libraries and create
1760	# a file called <name>
1761
1762	SetupKernel $(2) ;
1763
1764	# Show that we depend on the libraries we need
1765	LocalClean clean : $(1) ;
1766	LocalDepends all : $(1) ;
1767	Depends $(1) : $(2) ;
1768
1769	MakeLocate $(1) : $(LOCATE_TARGET) ;
1770}
1771
1772actions KernelStaticLibraryObjects
1773{
1774	ar -r "$(1)" "$(2)" ;
1775}
1776
1777rule BuildPlatformMain
1778{
1779	# Usage BuildPlatformMain <target> : <sources> ;
1780	SetupObjectsDir ;
1781	SetupDefaultIncludes ;
1782
1783	# Remove `-nostdinc' from CCFLAGS and C++FLAGS.
1784	local oldCCFLAGS = $(CCFLAGS) ;
1785	local oldC++FLAGS = $(C++FLAGS) ;
1786	CCFLAGS = [ Filter $(CCFLAGS) : -nostdinc ] ;
1787	C++FLAGS = [ Filter $(C++FLAGS) : -nostdinc ] ;
1788
1789	Main $(1) : $(2) ;
1790
1791	# Reset CCFLAGS and C++FLAGS to original values.
1792	CCFLAGS = $(oldCCFLAGS) ;
1793	C++FLAGS = $(oldC++FLAGS) ;
1794}
1795
1796rule BuildPlatformTest
1797{
1798	# Usage BuildPlatformTest <target> : <sources> ;
1799
1800	local target = $(1) ;
1801	local sources = $(2) ;
1802
1803	BuildPlatformMain $(target) : $(sources) ;
1804	local relPath ;
1805	if [ FIsPrefix src tests : $(SUBDIR_TOKENS) ] {
1806		relPath = $(SUBDIR_TOKENS[3-]) ;
1807	} else {
1808		relPath = $(SUBDIR_TOKENS[2-]) ;
1809	}
1810	MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(relPath) ] ;
1811}
1812
1813rule KernelConfigSection
1814{
1815	# KernelConfigSection <section> : <type> : <file>  ;
1816
1817	SECTION_NAMES on $(OBOS_KERNEL_CONFIG) += $(1) ;
1818	SECTION_TYPES on $(OBOS_KERNEL_CONFIG) += $(2) ;
1819	SECTION_FILES on $(OBOS_KERNEL_CONFIG) += $(3) ;
1820
1821	Depends $(OBOS_KERNEL_CONFIG) : $(3) ;
1822}
1823
1824rule WriteKernelConfig
1825{
1826	# usage: WriteKernelConfig <target> ;
1827
1828	LocalDepends files : $(1) ;
1829
1830	MakeLocate $(1) : $(OBOS_OBJECT_TARGET) ;
1831
1832	LocalClean clean : $(1) ;
1833}
1834
1835actions WriteKernelConfig bind SECTION_FILES
1836{
1837	target="$(1)"
1838	echo "# OpenBeOS Kernel Config File" > "$target"
1839	echo "# Automatically generated - do not edit!" >> "$target"
1840	count=0
1841	for section in "$(SECTION_NAMES)" ; do
1842		count=`expr $count + 1`
1843		eval section$count="$section"
1844	done
1845	i=1
1846	for type in "$(SECTION_TYPES)" ; do
1847		eval type$i="$type"
1848		i=`expr $i + 1`
1849	done
1850	i=1
1851	for file in "$(SECTION_FILES)" ; do
1852		eval file$i="$file"
1853		i=`expr $i + 1`
1854	done
1855	for i in `seq $count` ; do
1856		eval section="\$section$i"
1857		eval type="\$type$i"
1858		eval file="\$file$i"
1859		echo "" >> "$target"
1860		echo "["$section"]" >> "$target"
1861		echo "type="$type >> "$target"
1862		case "$file" in
1863			/*) ;;
1864			*) file=`pwd`/"$file";;
1865		esac
1866		echo "file="$file >> "$target"
1867	done
1868}
1869
1870rule BuildKernel
1871{
1872	# Usage BuildKernel <target> : <config_file> ;
1873	local kernel = $(1) ;
1874	local configFile = $(2) ;
1875	local bootmaker = bootmaker ;
1876
1877	LocalDepends all : $(kernel) ;
1878	Depends $(kernel) : $(configFile) $(bootmaker) ;
1879	LocalClean clean : $(kernel) ;
1880	MakeLocate $(kernel) : $(LOCATE_TARGET) ;
1881
1882	BOOT_MAKER on $(kernel) = $(bootmaker) ;
1883}
1884
1885actions BuildKernel bind BOOT_MAKER
1886{
1887	"$(BOOT_MAKER)" --strip-debug --strip-binary strip "$(2)" -o "$(1)" ;
1888	echo ""
1889	echo "Kernel linked!"
1890	echo ""
1891}
1892
1893rule KernelFloppyImage
1894{
1895	# Usage KernelFloppyImage <target> : <kernel> : <bootblock> ;
1896	local floppy = $(1) ;
1897	local kernel = $(2) ;
1898	local bootblock = $(3) ;
1899	local makeflop = makeflop ;
1900
1901	LocalDepends all : $(floppy) ;
1902	Depends $(floppy) : $(kernel) $(bootblock) $(makeflop) ;
1903	LocalClean clean : $(floppy) ;
1904	MakeLocate $(floppy) : $(OBOS_OBJECT_TARGET) ;
1905
1906	BOOT_BLOCK on $(floppy) = $(bootblock) ;
1907	MAKE_FLOP on $(floppy) = $(makeflop) ;
1908}
1909
1910# This may be a bit verbose, but I think it's useful to show what's
1911# going on, at least in this early stage of development.
1912actions KernelFloppyImage bind BOOT_BLOCK bind MAKE_FLOP
1913{
1914	"$(MAKE_FLOP)" "-p $(shell expr 18 \* 2 \* 512)" "$(BOOT_BLOCK)" "$(2)" "$(1)" ;
1915
1916	echo ""
1917	echo "*************************************************"
1918	echo "*         Kernel build completed!               *"
1919	echo "*    Boot image for a 1.44M floppy created      *"
1920	echo "*************************************************"
1921	echo ""
1922	echo "Floppy image is $(1)"
1923	echo "The following command will write it to a floppy on BeOS"
1924	echo "  dd if=$(1) of=/dev/disk/floppy/raw bs=18k"
1925	echo "Alternatively you can run"
1926	echo "  ./configure --floppy /dev/disk/floppy/raw"
1927	echo "once and build + write the image subsequently via"
1928	echo "  jam installfloppy"
1929	echo ""
1930}
1931
1932rule InstallFloppy
1933{
1934	# InstallFloppy <target> : <floppy>
1935	# "dd"s <floppy> to $(FLOPPY_PATH).
1936
1937	local target = $(1) ;
1938	local floppy = $(2) ;
1939
1940	NotFile $(target) ;
1941	Always $(target) ;
1942	Depends $(target) : $(floppy) ;
1943}
1944
1945actions InstallFloppy
1946{
1947	if [ -z $(FLOPPY_PATH) ] ; then
1948		echo "Can't install floppy: FLOPPY_PATH not set."
1949		echo "run: ./configure --floppy <floppy path>"
1950		echo
1951		exit 0
1952	fi
1953	dd if=$(2) of=$(FLOPPY_PATH) bs=18k
1954}
1955
1956#-------------------------------------------------------------------------------
1957# FreeType 2 specific rules and variables
1958#-------------------------------------------------------------------------------
1959
1960FT2_INCLUDE = [ FDirName $(OBOS_TOP) headers libs freetype2 ] ;
1961FT2_SRC     = [ FDirName $(OBOS_TOP) src libs freetype2 ] ;
1962
1963FT2_LIB     = freetype ;
1964
1965FT2_COMPONENTS ?= gzip       # support for gzip-compressed files.
1966                  autohint   # auto-hinter
1967                  base       # base component (public APIs)
1968                  bdf        # BDF font driver
1969                  cache      # cache sub-system
1970                  cff        # CFF/CEF font driver
1971                  cid        # Postscript CID-keyed font driver
1972                  pcf        # PCF font driver
1973                  pfr        # PFR/TrueDoc font driver
1974                  psaux      # Common Postscript routines module
1975                  pshinter   # Postscript hinter module
1976                  psnames    # Postscript names handling
1977                  raster     # Monochrome rasterizer
1978                  smooth     # Anti-aliased rasterizer
1979                  sfnt       # SFNT-based format support routines
1980                  truetype   # TrueType font driver
1981                  type1      # Postscript Type 1 font driver
1982                  type42     # Postscript Type 42 (embedded TrueType) driver
1983                  winfonts   # Windows FON/FNT font driver
1984                  ;
1985
1986rule UseFreeTypeHeaders
1987{
1988	SubDirHdrs $(FT2_INCLUDE) ;
1989}
1990
1991rule UseFreeTypeObjectHeaders
1992{
1993	# UseFreeTypeObjectHeaders <sources> [ : <objects> ] ;
1994	SourceHdrs $(1) : $(FT2_INCLUDE) : $(2) ;
1995}
1996
1997rule FT2_SubDir
1998{
1999	# FT2_SubDir <dir>
2000	# <dir>: Components of a directory in the original hierarchy.
2001	local dir = $(1) ;
2002	local topDir ;
2003	switch $(dir[1])
2004	{
2005		case "include"	: topDir = $(FT2_INCLUDE) ;
2006		case src		: topDir = $(FT2_SRC) ;
2007		case *			: ECHO "Unknown FreeType2 directory: " $(dir) ;
2008	}
2009	return [ FDirName $(topDir) $(dir[2-]) ] ;
2010}
2011
2012rule FT2_Library
2013{
2014	# FT2_Library <libname> : <sources>
2015	# Builds objects from sources and adds the objects to the list of objects
2016	# to be linked into the library.
2017	# <libname> The name of the library.
2018	# <sources> The sources.
2019
2020	local library = lib$(1).so ;
2021	local sources = $(2) ;
2022	SetupIncludes ;
2023	SetupObjectsDir ;
2024	MakeLocateObjects $(sources) ;
2025	Objects $(sources) ;
2026	LIBRARY_OBJECTS on $(library) += [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
2027}
2028
2029rule FT2_LinkLibrary
2030{
2031	# FT2_LinkLibrary <libname>
2032	# Links the library from the objects build with FT2_LIBRARY before.
2033
2034	local library = lib$(1).so ;
2035	local objects = [ on $(library) return $(LIBRARY_OBJECTS) ] ;
2036	ObjectReferences $(objects) ;
2037	objects = [ FGristFiles $(objects) ] ;
2038	SharedLibraryFromObjects $(1) : $(objects) ;
2039}
2040
2041#-------------------------------------------------------------------------------
2042# Packages for OBOS alpha/beta testers
2043#-------------------------------------------------------------------------------
2044
2045rule Copy
2046{
2047	Depends $(<) : $(>) ;
2048	SEARCH on $(>) = $(SEARCH_SOURCE) ;
2049}
2050
2051actions Copy
2052{
2053	cp -dp "$(>)" "$(<)" ;
2054	if [ -f "$(>)" ] ; then copyattr "$(>)" "$(<)" ; fi ;
2055}
2056
2057rule Packages
2058{
2059	local packagenames = $(1) ;
2060	local packagefiles = $(2) ;
2061	local path = $(3) ;
2062	for name in $(packagenames) {
2063		Package $(name) : $(packagefiles) : $(path) ;
2064    }
2065}
2066
2067rule Package
2068{
2069	local packagename = $(1) ;
2070    local packagefiles = $(2) ;
2071	local path = $(3) ;
2072
2073	local packagezip = $(packagename:S=.zip:G=_packages) ;
2074	local packagedir = [ FDirName $(OBOS_PACKAGE_DIR) $(packagename) ] ;
2075
2076    local installscript = install.sh ;
2077	local packageinstallscript = $(installscript:G=_packages!$(packagename)) ;
2078    local installzip = install.zip ;
2079	local packageinstallzip = $(installzip:G=_packages!$(packagename)) ;
2080
2081    local packageobjectdir
2082    	= [ FDirName $(OBOS_PACKAGE_OBJECT_DIR) $(packagename) ] ;
2083	local packagefiledir =  [ FDirName $(packageobjectdir) $(path) ] ;
2084    local packagefileinstallzip
2085    	= $(installzip:G=_package_objects!$(packagename)) ;
2086
2087	# add the files to the install.zip
2088	local packagefilegrist = [ FGrist _package_files $(packagename) $(path) ] ;
2089    for file in $(packagefiles) {
2090		if $(3[0]) = "boot" {
2091			local packagefile = $(file:G=$(packagefilegrist)) ;
2092			MakeLocate $(packagefile) : $(packagefiledir) ;
2093			Copy $(packagefile) : $(file) ;
2094			Clean cleanPackages : $(packagefile) ;
2095			PackageInstallZip $(packagefileinstallzip) : $(packagefile) ;
2096		} else {
2097			local packagefile = $(file:G=_packages!$(packagename)) ;
2098			MakeLocate $(packagefile) : $(packagedir) ;
2099			Copy $(packagefile) : [ FGristFiles $(file) ] ;
2100			Clean cleanPackages : $(packagefile) ;
2101			Depends $(packagezip) : $(packagefile) ;
2102		}
2103	}
2104
2105	# general setup for this packages -- only on first invocation
2106	if ! $(_setup_$(packagename)) {
2107		_setup_$(packagename) = true ;
2108
2109		NotFile $(packagename) ;
2110		Depends packages : $(packagename) ;
2111
2112		MakeLocate $(packagezip) : $(OBOS_PACKAGE_DIR) ;
2113		MakeLocate $(packageinstallscript) : $(packagedir) ;
2114		MakeLocate $(packageinstallzip) : $(packagedir) ;
2115		MakeLocate $(packagefileinstallzip) : $(packageobjectdir) ;
2116
2117		PackageInstallScript $(packageinstallscript) : $(packagedir) ;
2118		LinkInstallZip $(packageinstallzip) : $(packagefileinstallzip) ;
2119		Depends $(packagename) : $(packagezip) ;
2120		PackageZip $(packagezip) : $(packagedir)
2121			: $(packageinstallscript) $(packageinstallzip) ;
2122	}
2123
2124}
2125
2126rule PackageZip
2127{
2128	local dir = $(2:G=dir) ;
2129	Depends $(1) : $(dir) $(3) ;
2130	Clean cleanPackages : $(1) ;
2131	PackageZip1 $(1) : $(dir) ;
2132}
2133
2134actions together PackageZip1 {
2135	cd "$(OBOS_PACKAGE_DIR)" ;
2136	zip -rq "$(1:BS)" "$(2:BS)" ;
2137}
2138
2139rule PackageInstallScript
2140{
2141	MakeLocate $(1) : $(2) ;
2142	Clean cleanPackages : $(1) ;
2143	PackageInstallScript1 $(1) : $(2:G=dir) ;
2144}
2145
2146actions together PackageInstallScript1
2147{
2148echo '#!/bin/sh
2149base=`dirname "$0"`
2150cd "$base"
2151if [ -n "$TTY" ]
2152then
2153    unzip -d / install.zip
2154else
2155    response=`alert "Would you like to automatically overwrite existing files, or receive a prompt?" "Overwrite" "Prompt"`
2156    if [ $response == "Overwrite" ]
2157    then
2158        unzip -od / install.zip
2159        alert "Finished installing" "Thanks"
2160    else
2161        if [ -e /boot/beos/apps/Terminal ]
2162        then
2163            terminal=/boot/beos/apps/Terminal
2164        else
2165            terminal=`query Terminal | head -1`
2166        fi
2167        $terminal -t "installer" /bin/sh "$0"
2168    fi
2169fi' > "$(1)" ;
2170	chmod 755 "$(1)" ;
2171}
2172
2173rule PackageInstallZip
2174{
2175	Depends $(1) : $(2) ;
2176	Clean cleanPackages : $(1) ;
2177}
2178
2179actions together PackageInstallZip
2180{
2181	cd "$(1:P)" ;
2182	zip -rqy "$(1:BS)" boot ;
2183}
2184
2185rule LinkInstallZip
2186{
2187	Depends $(1) : $(2) ;
2188	Clean cleanPackages : $(1) ;
2189}
2190
2191actions together LinkInstallZip
2192{
2193	ln -sf "`pwd`/$(2)" "$(1)" ;
2194}
2195
2196rule SubIncludeGPL
2197{
2198	# SubInclude rule that can be used to conditionally include GPL licensed add-ons
2199	if $(INCLUDE_GPL_ADDONS) = 1 {
2200		SubInclude $(1) ;
2201	}
2202}
2203