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