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