xref: /haiku/Jamrules (revision 9fc6b2e18b6f0e5dff4221466f97ed2693341c10)
1# Include BuildConfig
2{
3	local buildConfig = [ GLOB $(OBOS_TOP) : BuildConfig ] ;
4	if ! $(buildConfig)
5	{
6		EXIT "No BuildConfig!"
7			 "Run ./configure in the source tree's root directory first!" ;
8	}
9	include $(buildConfig) ;
10}
11
12# Determine if we're building on PPC or x86
13# Determine mimetype of executable
14# Cross compiling can come later
15
16if $(METROWERKS) {
17	OBOS_TARGET ?= "ppc.R1" ;
18	OBOS_TARGET_TYPE ?= "application/x-be-executable" ;
19	OBOS_ARCH ?= "ppc" ;
20	OBOS_TARGET_DEFINE ?= "ARCH_ppc" ;
21} else {
22	OBOS_TARGET ?= "x86.R1" ;
23	OBOS_TARGET_TYPE ?= "application/x-vnd.Be-elfexecutable" ;
24	OBOS_ARCH ?= "x86" ;
25	OBOS_TARGET_DEFINE ?= "ARCH_x86" ;
26	OBOS_TARGET_DIR ?= "x86" ;
27}
28
29# Enable warnings only if WARNINGS is defined
30# Should be enabled by default later
31
32if $(WARNINGS) {
33	# For an explanation of the different warning options, see:
34	# http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_2.html
35	# to get even more warnings, add:
36	# -Wwrite-strings  	(doesn't work well with some Be headers)
37	# -Wundef			(dito)
38	# -Wconversion		(gets you many warnings about implicit conversions)
39	# -W				(gets you even more warnigs)
40	CCFLAGS ?= "-Wall -Wno-multichar -Wmissing-prototypes" ;
41	CCFLAGS += "-Wpointer-arith -Wcast-align -Wsign-compare" ;
42	C++FLAGS ?= "-Wall -Wno-multichar -Wmissing-prototypes -Wno-ctor-dtor-privacy -Woverloaded-virtual" ;
43	C++FLAGS += "-Wpointer-arith -Wcast-align -Wsign-compare" ;
44}
45
46KERNEL_CCFLAGS ?= "-Wall -Wno-multichar -Wmissing-prototypes -finline -nostdinc" ;
47KERNEL_CCFLAGS += "-fno-builtin -D$(OBOS_TARGET_DEFINE) " ;
48
49AR = ar r ;
50OPTIM = -O2 ;
51
52# If no OBOS_OBJECT_TARGET is not defined yet, use our default directory and
53# include our "OBOS_TARGET" as subdirectory in there (to prevent different
54# builds mixing objects from different targets).
55if ! $(OBOS_OBJECT_TARGET) {
56	OBOS_OBJECT_TARGET ?= [ FDirName $(OBOS_TOP) objects $(OBOS_TARGET) ] ;
57}
58
59# If no OBOS_DISTRO_TARGET is not defined yet, use our default directory and
60# include our "OBOS_TARGET" as subdirectory in there (to prevent different
61# builds mixing executables from different targets).
62if ! $(OBOS_DISTRO_TARGET) {
63	OBOS_DISTRO_TARGET ?= [ FDirName $(OBOS_TOP) distro $(OBOS_TARGET) ] ;
64}
65
66# Set our version number if not already set and mark it as a developer build
67if ! $(OBOS_BUILD_VERSION) {
68	OBOS_BUILD_VERSION ?= "1 0 0 a 1" ;
69	OBOS_BUILD_DESCRIPTION ?= "Developer Build" ;
70}
71
72# If OBOS_BUILD_VERSION is set, but OBOS_BUILD_DESCRIPTION isn't, mark it as
73# an unknown build.
74if ! $(OBOS_BUILD_DESCRIPTION) {
75	OBOS_BUILD_DESCRIPTION ?= "Unknown Build" ;
76}
77
78# Relative subdirs for distro dir (these are for *INTERNAL* use by the following rules only!)
79OBOS_APPS_DIR   ?= [ FDirName $(OBOS_DISTRO_TARGET) beos apps ] ;
80OBOS_BIN_DIR    ?= [ FDirName $(OBOS_DISTRO_TARGET) beos bin ] ;
81OBOS_PREFS_DIR  ?= [ FDirName $(OBOS_DISTRO_TARGET) beos preferences ] ;
82OBOS_SERVER_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system servers ] ;
83OBOS_ADDON_DIR  ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system add-ons ] ;
84OBOS_SHLIB_DIR  ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system lib ] ;
85OBOS_STLIB_DIR  ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system lib ] ;
86OBOS_KERNEL_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system ] ;
87OBOS_TEST_DIR   ?= [ FDirName $(OBOS_TOP) tests ] ;
88
89OBOS_KERNEL_CONFIG = config.$(OBOS_ARCH).ini ;
90OBOS_KERNEL = kernel.$(OBOS_ARCH) ;
91OBOS_FLOPPY = floppy.$(OBOS_ARCH) ;
92
93rule SetupIncludes
94{
95	OBOS_INCLUDES ?= . add-ons app be_apps device drivers game interface kernel mail media midi midi2 net opengl storage support translation ;
96	UsePublicHeaders $(OBOS_INCLUDES) ;
97    UsePosixHeaders ;
98}
99
100#-------------------------------------------------------------------------------
101# Things Jam needs in order to work :)
102#-------------------------------------------------------------------------------
103
104rule UserObject
105{
106	switch $(2)
107	{
108	case *.S    : assemble $(1) : $(2) ;
109	case *.o    : return ;
110	case *      : ECHO "unknown suffix on" $(2) ;
111	}
112}
113
114# Override the default to give "prettier" command lines.
115actions Cc
116{
117	$(CC) -c "$(2)" $(CCFLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
118}
119
120actions C++
121{
122	$(C++) -c "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
123}
124
125
126#-------------------------------------------------------------------------------
127# General High-level OBOS target rules
128#-------------------------------------------------------------------------------
129
130rule App
131{
132	# App <name> : <sources> ;
133	SetupObjectsDir ;
134	Main $(<) : $(>) ;
135	MakeLocate $(<) : $(OBOS_APPS_DIR) ;
136}
137
138rule BinCommand
139{
140	# BinCommand <name> : <sources> : <libraries> ;
141	SetupObjectsDir ;
142	Main $(1) : $(2) ;
143	MakeLocate $(1) : $(OBOS_BIN_DIR) ;
144	LinkSharedOSLibs $(1) : $(3) ;
145}
146
147rule StdBinCommands
148{
149	# StdBinCommands <sources> : <libs> ;
150	local libs = $(2) ;
151	for source in $(1)
152	{
153		local target = $(source:S=) ;
154		target = [ FGristFiles $(target) ] ;
155		BinCommand $(target) : $(source) : $(libs) ;
156	}
157}
158
159rule Preference
160{
161	# Preference <name> : <sources> ;
162#	SetupIncludes ;
163	SetupObjectsDir ;
164	Main $(<) : $(>) ;
165	MakeLocate $(<) : $(OBOS_PREFS_DIR) ;
166}
167
168rule Server
169{
170	# Server <name> : <sources> ;
171
172#	SetupIncludes ;
173	SetupObjectsDir ;
174	Main $(<) : $(>) ;
175	MakeLocate $(<) : $(OBOS_SERVER_DIR) ;
176}
177
178# test pseudo targets
179NOTFILE obostests ;
180NOTFILE r5tests ;
181
182rule CommonUnitTest
183{
184	# CommonUnitTest <target> : <sources> : <dest> : <obos libraries>
185	#	: <r5 libraries> : <public headers>;
186	# Builds a unit test for both OBOS and R5 modules.
187	# <target> The name of the target.
188	# <sources> The list of sources.
189	# <dest> The directory for the target (as passed to FDirName).
190	# <obos libraries> A list of link libraries for the OBOS tests (as passed
191	# to LinkSharedOSLibs).
192	# <r5 libraries> A list of link libraries for the R5 tests (as passed
193	# to LinkSharedOSLibs).
194	# <public headers> A list of public header dirs (as passed to
195	# UsePublicHeaders).
196
197	UnitTest $(1) : $(2) : $(3) : $(4) : $(6) ;
198	R5UnitTest $(1) : $(2) : $(3) : $(5) ;
199}
200
201rule UnitTest
202{
203	# UnitTest <target> : <sources> : <dest> : <libraries> : <public headers>
204	# Builds a unit test for an OBOS module.
205	# <target> The name of the target.
206	# <sources> The list of sources.
207	# <dest> The directory for the target (as passed to FDirName).
208	# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
209	# <public headers> A list of public header dirs (as passed to
210	# UsePublicHeaders).
211
212	local target = $(1) ;
213	local sources = $(2) ;
214	local dest = $(3) ;
215	local libraries = $(4) ;
216	local headerDirs = $(5) ;
217
218	# Turn optimization off.
219	local optim = $(OPTIM) ;
220	OPTIM = ;
221
222#	SetupIncludes ;
223	UseCppUnitHeaders ;
224	SetupObjectsDir ;
225	MakeLocateObjects $(sources) ;
226	Main $(target) : $(sources) ;
227	MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(dest) ] ;
228	DEPENDS $(target) : libcppunit.so ;
229	DEPENDS obostests : $(target) ;
230	LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ;
231	UsePublicObjectHeaders $(sources) : $(headerDirs) ;
232	ObjectDefines $(sources) : TEST_OBOS ;
233
234	# Turn debugging on. That is usually desired for test code.
235	ObjectCcFlags $(sources) : "-g" ;
236	ObjectC++Flags $(sources) : "-g" ;
237
238	# Turn optimization on again.
239	OPTIM = $(optim) ;
240}
241
242rule R5UnitTest
243{
244	# R5UnitTest <target> : <sources> : <dest> : <libraries>
245	# Builds a unit test for an R5 module. "_r5" is appended to the object
246	# and the target name.
247	# <target> The name of the target.
248	# <sources> The list of sources.
249	# <dest> The directory for the target (as passed to FDirName).
250	# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
251
252	local target = $(1)_r5 ;
253	local sources = $(2) ;
254	local dest = $(3) ;
255	local libraries = $(4) ;
256	local objects = [ R5ObjectNames $(sources) ] ;
257
258	# Turn optimization off.
259	local optim = $(OPTIM) ;
260	OPTIM = ;
261
262	UseCppUnitHeaders ;
263	SetupObjectsDir ;
264	MakeLocateObjects $(objects) ;
265
266	# Our Main replacement.
267	MainFromObjects $(target) : $(objects) ;
268	local source ;
269	for source in [ FGristFiles $(sources) ]
270	{
271		local object = [ R5ObjectNames $(source) ] ;
272		Object $(object) : $(source) ;
273		Depends obj : $(object) ;
274	}
275
276	MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(dest) ] ;
277	DEPENDS $(target) : libcppunit.so ;
278	DEPENDS r5tests : $(target) ;
279	LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ;
280	ObjectDefines $(objects) : TEST_R5 ;
281
282	# Turn debugging on. That is usually desired for test code.
283	ObjectCcFlags $(objects) : "-g" ;
284	ObjectC++Flags $(objects) : "-g" ;
285
286	# Turn optimization on again.
287	OPTIM = $(optim) ;
288}
289
290rule R5ObjectNames
291{
292	# R5ObjectNames <sources> ;
293	# Returns a list of gristed object names given a list of source file names.
294	# Moreover each object names gets "_r5" inserted before the object suffix.
295	local objects = $(1:S=)_r5 ;
296	return [ FGristFiles $(objects:S=$(SUFOBJ)) ] ;
297}
298
299rule SimpleTest
300{
301	# UnitTest <target> : <sources> : <libraries>
302	# Builds a unit test for an OBOS module.
303	# <target> The name of the target.
304	# <sources> The list of sources.
305	# <dest> The directory for the target (as passed to FDirName).
306	# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
307	# <public headers> A list of public header dirs (as passed to
308	# UsePublicHeaders).
309
310	local target = $(1) ;
311	local sources = $(2) ;
312	local libraries = $(3) ;
313	local relPath = [ FRelPath src tests : $(SUBDIR_TOKENS) ] ;
314
315	# Turn optimization off.
316	local optim = $(OPTIM) ;
317	OPTIM = ;
318
319#	SetupIncludes ;
320	SetupObjectsDir ;
321	MakeLocateObjects $(sources) ;
322	Main $(target) : $(sources) ;
323	MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(relPath) ] ;
324	DEPENDS obostests : $(target) ;
325	LinkSharedOSLibs $(target) : $(libraries) ;
326	ObjectDefines $(sources) : TEST_OBOS ;
327
328	# Turn debugging on. That is usually desired for test code.
329	ObjectCcFlags $(sources) : "-g" ;
330	ObjectC++Flags $(sources) : "-g" ;
331
332	# Turn optimization on again.
333	OPTIM = $(optim) ;
334}
335
336rule Addon
337{
338	# Addon <name> : <relpath> : <sources> ;
339
340#	SetupIncludes ;
341	SetupObjectsDir ;
342	Main $(1) : $(3) ;
343
344	# Create output dir path for addon
345	local targetdir;
346	targetdir = [ FDirName $(OBOS_ADDON_DIR) $(2) ] ;
347
348	MakeLocate $(1) : $(targetdir) ;
349	LINKFLAGS on $(1) = $(LINKFLAGS) -nostart -Xlinker -soname=\"$(1)\" ;
350}
351
352rule MakeLocateObjects
353{
354	# MakeLocateObjects <gristed_sources_or_objects> ;
355
356	local _objs = $(1:S=$(SUFOBJ)) ;
357
358	for o in $(_objs)
359	{
360		local dir = $(o:D) ;
361		if $(dir) {
362			MakeLocate $(o) : [ FDirName $(LOCATE_TARGET) $(dir) ] ;
363		} else {
364			MakeLocate $(o) : $(LOCATE_TARGET) ;
365		}
366	}
367}
368
369rule StaticLibrary
370{
371	# StaticLibrary <name> : <sources> ;
372
373#	SetupIncludes ;
374	SetupObjectsDir ;
375	MakeLocateObjects $(2) ;
376	Library lib$(<).a : $(>) ;
377	MakeLocate lib$(<).a : $(OBOS_STLIB_DIR) ;
378}
379
380rule SharedLibrary
381{
382	# SharedLibrary <name> : <sources> ;
383	local _lib = lib$(1).so ;
384
385#	SetupIncludes ;
386	SetupObjectsDir ;
387	MakeLocateObjects $(2) ;
388	Main $(_lib) : $(2) ;
389	MakeLocate $(_lib) : $(OBOS_SHLIB_DIR) ;
390	LINKFLAGS on $(_lib) = $(LINKFLAGS) -nostart -Xlinker -soname=\"$(_lib)\" ;
391}
392
393rule LinkSharedOSLibs
394{
395	# LinkSharedOSLibs <name> : <libs> ;
396	# Valid elements for <libs> are e.g. "be" or "libopenbeos.so" or
397	# "/boot/.../libfoo.so". If the basename starts with "lib" or the thingy
398	# has a dirname or grist, it is added to the NEEDLIBS variable (i.e. the
399	# file will be bound!), otherwise it is prefixed "-l" and added to
400	# LINKLIBS.
401
402	for i in $(>)
403	{
404		local isfile = ;
405		if $(i:D) || $(i:G) {
406			isfile = true ;
407		} else {
408			switch $(i:B)
409			{
410				case lib*	: isfile = true ;
411				case *		: isfile = ;
412			}
413		}
414		if $(isfile) {
415			NEEDLIBS on $(1) += $(i) ;
416			DEPENDS $(1) : $(i) ;
417		} else {
418			LINKLIBS on $(1) += -l$(i) ;
419		}
420	}
421}
422
423rule LinkStaticOSLibs
424{
425	# LinkStaticOSLibs <name> : <libs> ;
426
427	for i in $(>)
428	{
429		LINKLIBS on $(<) = $(LINKLIBS) -l $(i) ;
430	}
431}
432
433rule AddResources
434{
435	# AddResources <name> : <resourcefiles> ;
436
437	SEARCH on $(2) += $(SEARCH_SOURCE) ;
438	RESFILES on $(1) += $(2) ;
439}
440
441rule PublicHeaders
442{
443	# PublicHeaders <group list>
444	#
445	# Returns the directory names for the public header dirs identified by
446	# <group list>.
447
448	local list = $(1) ;
449	local dirs ;
450	for i in $(list) {
451		dirs += [ FDirName $(OBOS_TOP) headers os $(i) ] ;
452	}
453	return $(dirs) ;
454}
455
456rule PrivateHeaders
457{
458	# PrivateHeaders <group list>
459	#
460	# Returns the directory names for the private header dirs identified by
461	# <group list>.
462
463	local list = $(1) ;
464	local dirs ;
465	for i in $(list) {
466		dirs += [ FDirName $(OBOS_TOP) headers private $(i) ] ;
467	}
468	return $(dirs) ;
469}
470
471rule ArchHeaders
472{
473	# usage: ArchHeaders <arch> ;
474	#
475	# <arch> specifies the architecture (e.g. x86).
476
477	return [ FDirName $(OBOS_TOP) headers private kernel arch $(1) ] ;
478}
479
480rule UsePublicHeaders
481{
482	# UsePublicHeaders <group list> ;
483	#
484	# Adds the public C header dirs given by <group list> to the header search
485	# dirs of the subdirectory.
486	# NOTE: This rule must be invoked *before* the rule that builds the objects.
487
488	UseHeaders [ PublicHeaders $(1) ] ;
489}
490
491rule UsePublicObjectHeaders
492{
493	# UsePublicObjectHeaders <sources_or_objects> : <group list> ;
494	#
495	# Adds the public C header dirs given by <group list> to the header search
496	# dirs of <sources_or_objects>.
497	# NOTE: This rule must be invoked *after* the rule that builds the objects.
498
499	ObjectHdrs $(1) : [ PublicHeaders $(2) ] ;
500}
501
502rule UsePrivateHeaders
503{
504	# UsePrivateHeaders <group list> ;
505	#
506	# Adds the private C header dirs given by <group list> to the header search
507	# dirs of the subdirectory.
508	# NOTE: This rule must be invoked *before* the rule that builds the objects.
509
510	UseHeaders [ PrivateHeaders $(1) ] ;
511}
512
513rule UsePrivateObjectHeaders
514{
515	# UsePrivateObjectHeaders <sources_or_objects> : <group list> ;
516	#
517	# Adds the private C header dirs given by <group list> to the header search
518	# dirs of <sources_or_objects>.
519	# NOTE: This rule must be invoked *after* the rule that builds the objects.
520
521	ObjectHdrs $(1) : [ PrivateHeaders $(2) ] ;
522}
523
524rule UseHeaders
525{
526	# UseHeaders <headers> ;
527	#
528	# Adds the C header dirs <headers> to the header search
529	# dirs of the subdirectory.
530	# NOTE: This rule must be invoked *before* the rule that builds the objects.
531
532	local header ;
533	for header in $(1) {
534		SubDirHdrs $(header) ;
535	}
536}
537
538rule UseCppUnitHeaders
539{
540	SubDirHdrs [ FDirName $(OBOS_TOP) headers tools cppunit ] ;
541}
542
543rule UseArchHeaders
544{
545	# usage: UseArchHeaders <arch> ;
546	#
547	# <arch> specifies the architecture (e.g. x86).
548	# NOTE: This rule must be invoked *before* the rule that builds the objects.
549
550	local headers = [ ArchHeaders $(1) ] ;
551	local opt = -D$(OBOS_TARGET_DEFINE) ;
552
553	SubDirCcFlags $(opt)  ;
554	SubDirC++Flags $(opt)  ;
555	SubDirHdrs $(headers) ;
556}
557
558rule UseArchObjectHeaders
559{
560	# usage: UseArchObjectHeaders <sources_or_objects> : <arch> ;
561	#
562	# <arch> specifies the architecture (e.g. x86).
563	# <sources_or_objects> Source or object files.
564	# NOTE: This rule must be invoked *after* the rule that builds the objects.
565
566	local targets = $(1) ;
567	local headers = [ ArchHeaders $(2) ] ;
568	local opt = -D$(OBOS_TARGET_DEFINE) ;
569
570	ObjectCcFlags $(targets) : $(opt)  ;
571	ObjectC++Flags $(targets) : $(opt)  ;
572	ObjectHdrs $(targets) : $(headers) ;
573}
574
575rule UsePosixHeaders
576{
577	# UsePrivateHeaders <group list> ;
578	#
579	# Adds the POSIX header dir to the header search
580	# dirs of the subdirectory.
581	# NOTE: This rule must be invoked *before* the rule that builds the objects.
582
583	SubDirHdrs [ FDirName $(OBOS_TOP) headers posix ] ;
584}
585
586rule UsePosixObjectHeaders
587{
588	# UsePosixObjectHeaders <sources_or_objects> ;
589	#
590	# Adds the POSIX header dir to the header search
591	# dirs of <sources_or_objects>.
592	# NOTE: This rule must be invoked *after* the rule that builds the objects.
593
594	ObjectHdrs $(1) : [ FDirName $(OBOS_TOP) headers posix ] ;
595}
596
597rule SplitPath
598{
599	# SplitPath <path> ;
600	# Decomposes a path into its components.
601	local path = $(1:G=) ;
602	local components ;
603	while $(path:D)
604	{
605		# Note: $(path:B) returns "." for "..", but $(path:D=) is fine.
606		components = $(path:D=) $(components) ;
607		path = $(path:D) ;
608	}
609	components = $(path) $(components) ;
610	return $(components) ;
611}
612
613rule PrependObjectHdrs
614{
615	# PrependObjectHdrs <objects_or_sources> : <dirs> ;
616	# Prepends <dirs> to the list of header search dirs of the objects
617	# specified by <objects_or_sources>. The HDRS variable will not be
618	# changed, only CCHDRS.
619	# Note: A subsequent ObjectHdrs invocation will therefore undo the
620	# effect of this rule.
621	# NOTE: This is a hack.
622
623	local objects = [ FGristFiles $(1:S=$(SUFOBJ)) ] ;
624	local dirs = $(2) ;
625	for object in $(objects) {
626		# Don't change HDRS to avoid screwing up the header scanning.
627		PREPENDED_HDRS on $(object)
628			= $(dirs) [ on $(object) return $(PREPENDED_HDRS) ] ;
629		CCHDRS on $(object)
630			= [ FIncludes [ on $(object) return $(PREPENDED_HDRS) $(HDRS) ] ] ;
631	}
632}
633
634rule SymLink
635{
636	# SymLink <target> : <source> ;
637	# Links <target> to <source>.
638	# <source> is the exact link contents. No binding is done.
639	LINKCONTENTS on $(1) = $(2) ;
640	SymLink1 $(1) ;
641	DEPENDS all : $(target) ;
642}
643
644actions SymLink1
645{
646	$(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)"
647}
648
649rule RelSymLink
650{
651	# RelSymLink <link> : <link target>
652	# Creates a relative symbolic link from <link> to <link target>.
653	# <link> and <link target> can be usual targets. They may have a grist
654	# and don't need to have any dirname. Their LOCATE variables are used to
655	# find their locations.
656
657	local target = $(1) ;
658	local source = $(2) ;
659	local targetDir = [ on $(target) FDirName $(LOCATE[1]) $(target:D) ] ;
660	local sourceDir = [ on $(source) FDirName $(LOCATE[1]) $(source:D) ] ;
661	local sourcePath = $(source:G=) ;
662	sourcePath = $(sourcePath:D=$(sourceDir)) ;
663	local targetDirComponents = [ SplitPath $(targetDir) ] ;
664	local sourceComponents = [ SplitPath $(sourcePath) ] ;
665
666	SymLink $(target)
667		: [ FRelPath $(targetDirComponents) : $(sourceComponents) ] ;
668	NOUPDATE $(target);
669	DEPENDS $(target) : $(source) ;
670}
671
672#-------------------------------------------------------------------------------
673# Low-level OBOS utility rules
674#-------------------------------------------------------------------------------
675rule SetupObjectsDir
676{
677	local rel_objectsdir;
678
679	# Copy subdir tokens except the first, as that will be "sources", and we
680	# do not want to include that :)
681	rel_objectsdir = [ FDirName $(SUBDIR_TOKENS[2-]) ] ;
682	LOCATE_TARGET = [ FDirName $(OBOS_OBJECT_TARGET) $(rel_objectsdir) ] ;
683}
684
685#-------------------------------------------------------------------------------
686# Link rule/action are overwritten as they don't handle linking files who's name
687# contain spaces very well. Also adds resources and version to executable.
688#-------------------------------------------------------------------------------
689rule Link
690{
691	# Note: RESFILES must be set before invocation.
692	MODE on $(<) = $(EXEMODE) ;
693	on $(1) XRes $(1) : $(RESFILES) ;
694	SetVersion $(1) ;
695	Chmod $(<) ;
696	SetType $(1) ;
697	MimeSet $(1) ;
698}
699
700actions Link bind NEEDLIBS
701{
702	$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(2)" "$(NEEDLIBS)" $(LINKLIBS) ;
703}
704
705# BeOS specific rules
706
707rule XRes
708{
709	# XRes <target> : <resource files>
710	if $(2)
711	{
712		DEPENDS $(1) : $(2) ;
713		XRes1 $(1) : $(2) ;
714	}
715}
716
717rule XRes1 { }
718
719rule SetVersion
720{
721	# SetVersion <target>
722}
723
724rule SetType
725{
726	# SetType <target>
727}
728
729rule MimeSet
730{
731	# SetType <target>
732}
733
734
735if $(OS) = BEOS
736{
737
738actions XRes1
739{
740	xres -o "$(1)" "$(2)" ;
741}
742
743actions SetVersion
744{
745	setversion "$(1)" -system $(OBOS_BUILD_VERSION) -short "$(OBOS_BUILD_DESCRIPTION)" ;
746}
747
748actions SetType
749{
750	settype -t $(OBOS_TARGET_TYPE) "$(1)" ;
751}
752
753actions MimeSet
754{
755	mimeset -f "$(1)" ;
756}
757
758}	# if BEOS
759
760
761rule assemble
762{
763	DEPENDS $(1) : $(2) ;
764	Clean clean : $(1) ;
765}
766
767actions assemble
768{
769	$(CC) -c "$(2)" -O2 $(KERNEL_CCFLAGS) -o "$(1)" ;
770}
771
772# Overridden to allow spaces in file names.
773actions Chmod1
774{
775	$(CHMOD) "$(MODE)" "$(1)"
776}
777
778rule ObjectReference
779{
780	# ObjectReference <reference object> : <source object>
781	# Makes <reference object> refer to the same file as <source object>.
782	# The filenames must of course be identical.
783	# <source object> must have already been LOCATEd.
784
785	local ref = $(1) ;
786	local source = $(2) ;
787	if $(ref) != $(source) {
788		DEPENDS $(ref) : $(source) ;
789		on $(ref) LOCATE = [ on $(source) return $(LOCATE) ] ;
790	}
791}
792
793rule ObjectReferences
794{
795	# ObjectReferences <source objects>
796	# Creates local references to <source objects>, i.e. identifiers with the
797	# current grist referring to the same files. <source objects> must have
798	# already been LOCATEd.
799
800	local source ;
801	for source in $(1) {
802		ObjectReference [ FGristFiles $(source) ] : $(source) ;
803	}
804}
805
806rule Filter
807{
808	# Filter <list> : <excludes> ;
809	# Removes all occurrences of <excludes> in <list>.
810
811	local list = $(1) ;
812	local excludes = $(2) ;
813	local newList ;
814	local item ;
815	for item in $(list) {
816		local skip ;
817		local exclude ;
818		for exclude in $(excludes) {
819			if $(item) = $(exclude) {
820				skip = true ;
821			}
822		}
823		if ! $(skip) {
824			newList += item ;
825		}
826	}
827	return $(newList) ;
828}
829
830
831## Kernel stuff!
832
833rule SetupKernel
834{
835	# Usage SetupKernel <sources_or_objects> : <extra_cc_flags>;
836
837	local _objs = $(1:S=$(SUFOBJ)) ;
838
839	UsePublicHeaders kernel support drivers ;
840	UsePublicHeaders [ FDirName os kernel ] ;
841	UsePrivateHeaders kernel ;
842	UsePosixHeaders ;
843	UseArchHeaders $(OBOS_ARCH) ;
844
845	SetupObjectsDir ;
846
847	CCFLAGS on $(_objs) = $(KERNEL_CCFLAGS) $(2) ;
848	C++FLAGS on $(_objs) = $(KERNEL_CCFLAGS) $(2) ;
849}
850
851rule KernelObjects
852{
853	SetupKernel $(1) : $(2) ;
854
855	Objects $(1) ;
856}
857
858rule KernelLd
859{
860	# KernelLd <name> : <objs> : <linkerscript> : <args> : <gcc_off> ;
861
862	SetupKernel $(2) ;
863	LINK on $(1) = ld ;
864
865	LINKFLAGS on $(1) = $(4) ;
866	if $(3) { LINKFLAGS on $(1) += --script=$(3) ; }
867
868	# Remove any preset LINKLIBS
869	LINKLIBS on $(1) =  ;
870
871	# Show that we depend on the libraries we need
872	Clean clean : $(1) ;
873	Depends all : $(1) ;
874	Depends $(1) : $(2) ;
875
876	if $(6) {
877		for i in $(6) {
878			KernelConfigSection $(i) : elf32 : $(1) ;
879		}
880	}
881
882	MakeLocate $(1) : $(LOCATE_TARGET) ;
883
884	# Add libgcc.a - NB this should be detected not hard coded!
885	if ! $(5) {
886		LINKLIBS on $(1) += -L $(GCC_PATH) -lgcc ;
887	}
888}
889
890actions KernelLd
891{
892	$(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" $(LINKLIBS) ;
893}
894
895rule KernelStaticLibrary
896{
897	# Usage KernelStaticLibrary <name> : <sources> : <extra cc flags>  ;
898	# This is designed to take a set of sources and libraries and create
899	# a file called lib<name>.a
900
901	SetupKernel $(2) : $(3) ;
902
903	MakeLocateObjects $(2) ;
904	Library $(1) : $(2) ;
905}
906
907rule KernelStaticLibraryObjects
908{
909	# Usage KernelStaticLibrary <name> : <sources> ;
910	# This is designed to take a set of sources and libraries and create
911	# a file called <name>
912
913	SetupKernel $(2) ;
914
915	# Show that we depend on the libraries we need
916	Clean clean : $(1) ;
917	Depends all : $(1) ;
918	Depends $(1) : $(2) ;
919
920	MakeLocate $(1) : $(LOCATE_TARGET) ;
921}
922
923actions KernelStaticLibraryObjects
924{
925	ar -r "$(1)" "$(2)" ;
926}
927
928rule SystemMain
929{
930	# Usage SystemMain <target> : <sources> : <rqd_by> ;
931	SetupObjectsDir ;
932
933	LINKLIBS = ;
934
935	# This allows us to preset certain commands we use
936	# for building.
937	if $(3) {
938		for obj in $(3) {
939			BUILD_CMD on $(obj) = [ FDirName $(LOCATE_TARGET) $(1) ] ;
940		}
941	}
942
943	Main $(1) : $(2) ;
944}
945
946rule KernelConfigSection
947{
948	# KernelConfigSection <section> : <type> : <file>  ;
949
950	SECTION_NAMES on $(OBOS_KERNEL_CONFIG) += $(1) ;
951	SECTION_TYPES on $(OBOS_KERNEL_CONFIG) += $(2) ;
952	SECTION_FILES on $(OBOS_KERNEL_CONFIG) += $(3) ;
953
954	Depends $(OBOS_KERNEL_CONFIG) : $(3) ;
955}
956
957rule WriteKernelConfig
958{
959	# usage: WriteKernelConfig <target> ;
960
961	Depends files : $(1) ;
962
963	MakeLocate $(1) : $(OBOS_OBJECT_TARGET) ;
964
965	Clean clean : $(1) ;
966}
967
968actions WriteKernelConfig bind SECTION_FILES
969{
970	target="$(1)"
971	echo "# OpenBeOS Kernel Config File" > "$target"
972	echo "# Automatically generated - do not edit!" >> "$target"
973	count=0
974	for section in "$(SECTION_NAMES)" ; do
975		count=`expr $count + 1`
976		eval section$count="$section"
977	done
978	i=1
979	for type in "$(SECTION_TYPES)" ; do
980		eval type$i="$type"
981		i=`expr $i + 1`
982	done
983	i=1
984	for file in "$(SECTION_FILES)" ; do
985		eval file$i="$file"
986		i=`expr $i + 1`
987	done
988	for i in `seq $count` ; do
989		eval section="\$section$i"
990		eval type="\$type$i"
991		eval file="\$file$i"
992		echo "" >> "$target"
993		echo "["$section"]" >> "$target"
994		echo "type="$type >> "$target"
995		case "$file" in
996			/*) ;;
997			*) file=`pwd`/"$file";;
998		esac
999		echo "file="$file >> "$target"
1000	done
1001}
1002
1003rule BuildKernel
1004{
1005	# Usage BuildKernel <target> : <config_file> ;
1006
1007	Depends all : $(1) ;
1008	Depends $(1) : $(2) ;
1009	Clean clean : $(1) ;
1010
1011	MakeLocate $(1) : $(LOCATE_TARGET) ;
1012}
1013
1014actions BuildKernel
1015{
1016	"$(BUILD_CMD)" --strip-debug --strip-binary strip "$(2)" -o "$(1)" ;
1017	echo ""
1018	echo "Kernel linked!"
1019	echo ""
1020}
1021
1022# At present I don't bother moving the final location for
1023# the floppy image as it makes copying it onto a floppy easier if it's
1024# where you did the build. This is easy enough changed.
1025rule KernelFloppyImage
1026{
1027	# Usage KernelFloppyImage <target> : <kernel> : <bootblock> ;
1028
1029	Depends all : $(1) ;
1030	Depends $(1) : $(2) ;
1031	Clean clean : $(1) ;
1032
1033	BOOT_BLOCK on $(1) = $(3) ;
1034}
1035
1036# This may be a bit verbose, but I think it's useful to show what's
1037# going on, at least in this early stage of development.
1038actions KernelFloppyImage
1039{
1040	"$(BUILD_CMD)" "$(BOOT_BLOCK)" "$(2)" "$(1)" ;
1041	echo ""
1042	echo "*************************************************"
1043	echo "*         Kernel build completed!               *"
1044	echo "*    Boot image for a 1.44M floppy created      *"
1045	echo "*************************************************"
1046	echo ""
1047	echo "Floppy image is $(OBOS_FLOPPY)"
1048	echo "The following command will write it to a floppy on BeOS"
1049	echo "  dd if=$(OBOS_FLOPPY) of=/dev/disk/floppy/raw bs=18k"
1050	echo ""
1051}
1052
1053
1054