haiku/Jamrules
Tyler Dauwalder c5ff4aa6f5 It became apparent that in order to assure obos tests are run
with obos libs and r5 tests are run with r5 libs, two separate
unit testing programs in different directories would be needed.
Thus UnitTester is now just a shell program that calls the
appropriate unittester/UnitTester or unittester_r5/UnitTester_r5
program.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@703 a95241bf-73f2-0310-859d-f6bbb57e9c96
2002-08-11 03:45:17 +00:00

1278 lines
31 KiB
Plaintext

# Vanilla Jam compatibility
if ! $(INVOCATION_SUBDIR_SET) {
rule FIsPrefix
{
# FIsPrefix <a> : <b> ;
# Returns true, if list <a> is a prefix (a proper one or equal) of
# list <b>, an empty list otherwise.
local a = $(1) ;
local b = $(2) ;
while $(a) && $(a[1]) = $(b[1]) {
a = $(a[2-]) ;
b = $(b[2-]) ;
}
if $(a) {
return ;
} else {
return true ;
}
}
rule LocalClean { Clean $(1) : $(2) ; }
rule LocalDepends { Depends $(1) : $(2) ; }
} # vanilla Jam compatibility
# Include BuildConfig
{
local buildConfig = [ GLOB $(OBOS_TOP) : BuildConfig ] ;
if ! $(buildConfig)
{
EXIT "No BuildConfig!"
"Run ./configure in the source tree's root directory first!" ;
}
include $(buildConfig) ;
}
# Determine if we're building on PPC or x86
# Determine mimetype of executable
# Cross compiling can come later
if $(METROWERKS) {
OBOS_TARGET ?= "ppc.R1" ;
OBOS_TARGET_TYPE ?= "application/x-be-executable" ;
OBOS_ARCH ?= "ppc" ;
OBOS_TARGET_DEFINE ?= "ARCH_ppc" ;
} else {
OBOS_TARGET ?= "x86.R1" ;
OBOS_TARGET_TYPE ?= "application/x-vnd.Be-elfexecutable" ;
OBOS_ARCH ?= "x86" ;
OBOS_TARGET_DEFINE ?= "ARCH_x86" ;
OBOS_TARGET_DIR ?= "x86" ;
}
# Enable warnings only if WARNINGS is defined
# Should be enabled by default later
if $(WARNINGS) {
# For an explanation of the different warning options, see:
# http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_2.html
# to get even more warnings, add:
# -Wwrite-strings (doesn't work well with some Be headers)
# -Wundef (dito)
# -Wconversion (gets you many warnings about implicit conversions)
# -W (gets you even more warnigs)
CCFLAGS ?= "-Wall -Wno-multichar -Wmissing-prototypes" ;
CCFLAGS += "-Wpointer-arith -Wcast-align -Wsign-compare" ;
C++FLAGS ?= "-Wall -Wno-multichar -Wmissing-prototypes -Wno-ctor-dtor-privacy -Woverloaded-virtual" ;
C++FLAGS += "-Wpointer-arith -Wcast-align -Wsign-compare" ;
}
# We might later want to introduce debug levels or handle the whole issue
# differently. For now there's only on or off.
#
if $(DEBUG) {
OPTIM ?= -O0 ;
CCFLAGS += -g ;
C++FLAGS += -g ;
LINKFLAGS += -g ;
} else {
OPTIM ?= -O2 ;
}
KERNEL_CCFLAGS ?= "-Wall -Wno-multichar -Wmissing-prototypes -finline -nostdinc" ;
KERNEL_CCFLAGS += "-fno-builtin -D$(OBOS_TARGET_DEFINE) " ;
KERNEL_CCFLAGS += "-DBOCHS_E9_HACK=$(BOCHS_E9_HACK) " ;
# Instructs the Library rule to not make its object files temporary.
# This is need as some objects are used in a static library and for an
# executable.
KEEPOBJS = true ;
AR = ar r ;
# If no OBOS_OBJECT_TARGET is not defined yet, use our default directory and
# include our "OBOS_TARGET" as subdirectory in there (to prevent different
# builds mixing objects from different targets).
if ! $(OBOS_OBJECT_TARGET) {
OBOS_OBJECT_TARGET ?= [ FDirName $(OBOS_TOP) objects $(OBOS_TARGET) ] ;
}
# If no OBOS_DISTRO_TARGET is not defined yet, use our default directory and
# include our "OBOS_TARGET" as subdirectory in there (to prevent different
# builds mixing executables from different targets).
if ! $(OBOS_DISTRO_TARGET) {
OBOS_DISTRO_TARGET ?= [ FDirName $(OBOS_TOP) distro $(OBOS_TARGET) ] ;
}
# Set our version number if not already set and mark it as a developer build
if ! $(OBOS_BUILD_VERSION) {
OBOS_BUILD_VERSION ?= "1 0 0 a 1" ;
OBOS_BUILD_DESCRIPTION ?= "Developer Build" ;
}
# If OBOS_BUILD_VERSION is set, but OBOS_BUILD_DESCRIPTION isn't, mark it as
# an unknown build.
if ! $(OBOS_BUILD_DESCRIPTION) {
OBOS_BUILD_DESCRIPTION ?= "Unknown Build" ;
}
# Relative subdirs for distro dir (these are for *INTERNAL* use by the following rules only!)
OBOS_APPS_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos apps ] ;
OBOS_BIN_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos bin ] ;
OBOS_PREFS_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos preferences ] ;
OBOS_SERVER_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system servers ] ;
OBOS_ADDON_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system add-ons ] ;
OBOS_SHLIB_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system lib ] ;
OBOS_STLIB_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system lib ] ;
OBOS_KERNEL_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system ] ;
OBOS_TEST_DIR ?= [ FDirName $(OBOS_TOP) tests ] ;
OBOS_KERNEL_CONFIG = config.$(OBOS_ARCH).ini ;
OBOS_KERNEL = kernel.$(OBOS_ARCH) ;
OBOS_FLOPPY = floppy.$(OBOS_ARCH) ;
rule SetupIncludes
{
OBOS_INCLUDES ?= . add-ons app be_apps device drivers game interface kernel mail media midi midi2 net opengl storage support translation ;
UsePublicHeaders $(OBOS_INCLUDES) ;
UsePosixHeaders ;
}
#-------------------------------------------------------------------------------
# Things Jam needs in order to work :)
#-------------------------------------------------------------------------------
rule UserObject
{
switch $(2)
{
case *.S : assemble $(1) : $(2) ;
case *.o : return ;
case * : ECHO "unknown suffix on" $(2) ;
}
}
# Override the default to give "prettier" command lines.
actions Cc
{
$(CC) -c "$(2)" $(CCFLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
}
actions C++
{
$(C++) -c "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
}
#-------------------------------------------------------------------------------
# General High-level OBOS target rules
#-------------------------------------------------------------------------------
rule App
{
# App <name> : <sources> ;
SetupObjectsDir ;
Main $(<) : $(>) ;
MakeLocate $(<) : $(OBOS_APPS_DIR) ;
}
rule BinCommand
{
# BinCommand <name> : <sources> : <libraries> ;
SetupObjectsDir ;
Main $(1) : $(2) ;
MakeLocate $(1) : $(OBOS_BIN_DIR) ;
LinkSharedOSLibs $(1) : $(3) ;
}
rule StdBinCommands
{
# StdBinCommands <sources> : <libs> ;
local libs = $(2) ;
local source ;
for source in $(1)
{
local target = $(source:S=) ;
target = [ FGristFiles $(target) ] ;
BinCommand $(target) : $(source) : $(libs) ;
}
}
rule Preference
{
# Preference <name> : <sources> ;
# SetupIncludes ;
SetupObjectsDir ;
Main $(<) : $(>) ;
MakeLocate $(<) : $(OBOS_PREFS_DIR) ;
}
rule Server
{
# Server <name> : <sources> ;
# SetupIncludes ;
SetupObjectsDir ;
Main $(<) : $(>) ;
MakeLocate $(<) : $(OBOS_SERVER_DIR) ;
}
# test pseudo targets
NOTFILE obostests ;
NOTFILE r5tests ;
rule CommonTestLib
{
# CommonTestLib <target> : <sources> : <obos libraries>
# : <r5 libraries> : <test libraries> : <public headers>;
# Builds a unit test for both OBOS and R5 modules.
# <target> The name of the target.
# <sources> The list of sources.
# <obos libraries> A list of link libraries for the OBOS tests (as passed
# to LinkSharedOSLibs).
# <r5 libraries> A list of link libraries for the R5 tests (as passed
# to LinkSharedOSLibs).
# <test libraries> A list of link libraries for both OBOS tests and R5 tests
# that have a common name (i.e. specify libx.so and the OBOS tests will link
# to libx.so and the R5 tests will link to libx_r5.so).
# <public headers> A list of public header dirs (as passed to
# UsePublicHeaders).
TestLib $(1) : $(2) : [ FDirName $(OBOS_TEST_DIR) unittester lib ] : $(3) $(5) : $(6) ;
R5TestLib $(1) : $(2) : [ FDirName $(OBOS_TEST_DIR) unittester_r5 lib ] : $(4) [ R5SharedLibraryNames $(5) ] ;
}
rule TestLib
{
# TestLib <target> : <sources> : <dest> : <libraries> : <public headers>
# Builds a unit test library for an OBOS module.
# <target> The name of the target.
# <sources> The list of sources.
# <dest> The directory for the target (as passed to FDirName).
# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
# <public headers> A list of public header dirs (as passed to
# UsePublicHeaders).
local target = $(1) ;
local sources = $(2) ;
local dest = $(3) ;
local libraries = $(4) ;
local headerDirs = $(5) ;
local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
# Our Main replacement.
MainFromObjects $(target) : $(objects) ;
TestObjects $(sources) : $(headerDirs) ;
MakeLocate $(target) : $(dest) ;
Depends $(target) : libcppunit.so ;
Depends obostests : $(target) ;
LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ;
LINKFLAGS on $(target) = $(LINKFLAGS) -nostart -Xlinker -soname=\"$(target)\" ;
}
rule R5TestLib
{
# R5TestLib <target> : <sources> : <dest> : <libraries>
# Builds a unit test for an R5 module. "_r5" is appended to the object
# and the target name.
# <target> The name of the target.
# <sources> The list of sources.
# <dest> The directory for the target (as passed to FDirName).
# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
local target = $(1:B)_r5$(1:S) ;
local sources = $(2) ;
local dest = $(3) ;
local libraries = $(4) ;
local objects = [ R5ObjectNames $(sources) ] ;
# Our Main replacement.
MainFromObjects $(target) : $(objects) ;
TestObjects $(sources) : : true ;
MakeLocate $(target) : $(dest) ;
Depends $(target) : libcppunit.so ;
Depends r5tests : $(target) ;
LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ;
LINKFLAGS on $(target) = $(LINKFLAGS) -nostart -Xlinker -soname=\"$(target)\" ;
}
rule CommonUnitTest
{
# CommonUnitTest <target> : <sources> : <dest> : <obos libraries>
# : <r5 libraries> : <public headers>;
# Builds a unit test for both OBOS and R5 modules.
# <target> The name of the target.
# <sources> The list of sources.
# <dest> The directory for the target (as passed to FDirName).
# <obos libraries> A list of link libraries for the OBOS tests (as passed
# to LinkSharedOSLibs).
# <r5 libraries> A list of link libraries for the R5 tests (as passed
# to LinkSharedOSLibs).
# <public headers> A list of public header dirs (as passed to
# UsePublicHeaders).
UnitTest $(1) : $(2) : $(3) : $(4) : $(6) ;
R5UnitTest $(1) : $(2) : $(3) : $(5) ;
}
rule UnitTest
{
# UnitTest <target> : <sources> : <dest> : <libraries> : <public headers>
# Builds a unit test for an OBOS module.
# <target> The name of the target.
# <sources> The list of sources.
# <dest> The directory for the target (as passed to FDirName).
# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
# <public headers> A list of public header dirs (as passed to
# UsePublicHeaders).
local target = $(1) ;
local sources = $(2) ;
local dest = $(3) ;
local libraries = $(4) ;
local headerDirs = $(5) ;
local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
# Our Main replacement.
MainFromObjects $(target) : $(objects) ;
TestObjects $(sources) : $(headerDirs) ;
MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(dest) ] ;
Depends $(target) : libcppunit.so ;
Depends obostests : $(target) ;
LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ;
}
rule R5UnitTest
{
# R5UnitTest <target> : <sources> : <dest> : <libraries>
# Builds a unit test for an R5 module. "_r5" is appended to the object
# and the target name.
# <target> The name of the target.
# <sources> The list of sources.
# <dest> The directory for the target (as passed to FDirName).
# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
local target = $(1)_r5 ;
local sources = $(2) ;
local dest = $(3) ;
local libraries = $(4) ;
local objects = [ R5ObjectNames $(sources) ] ;
# Our Main replacement.
MainFromObjects $(target) : $(objects) ;
TestObjects $(sources) : : true ;
MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(dest) ] ;
Depends $(target) : libcppunit.so ;
Depends r5tests : $(target) ;
LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ;
}
rule R5ObjectNames
{
# R5ObjectNames <sources> ;
# Returns a list of gristed object names given a list of source file names.
# Moreover each object names gets "_r5" inserted before the object suffix.
local objects = $(1:S=)_r5 ;
return [ FGristFiles $(objects:S=$(SUFOBJ)) ] ;
}
rule R5Objects
{
# R5Objects <sources>
# Similar to Objects, but appends "_r5" to the object file names.
# <sources> The source files.
local sources = $(1) ;
local source ;
for source in [ FGristFiles $(sources) ]
{
local object = [ R5ObjectNames $(source) ] ;
Object $(object) : $(source) ;
LocalDepends obj : $(object) ;
}
}
rule TestObjects
{
# TestLib <sources> : <public headers> : <r5>
# Compiles objects for tests.
# <sources> The list of sources.
# <public headers> A list of public header dirs (as passed to
# UsePublicHeaders).
# <r5> If set, "_r5" is appended to the object file names and
# <public headers> is ignored. Furthermore the pre-processor macro
# TEST_R5 is defined, TEST_OBOS otherwise.
local sources = $(1) ;
local headerDirs = $(2) ;
local r5 = $(3) ;
local objects ;
# Turn optimization off.
local optim = $(OPTIM) ;
OPTIM = ;
SetupObjectsDir ;
# compile
if $(r5) {
objects = [ R5ObjectNames $(sources) ] ;
R5Objects $(sources) ;
} else {
objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
Objects $(sources) ;
}
# set headers/defines
UseCppUnitObjectHeaders $(objects) ;
if $(r5) {
ObjectDefines $(objects) : TEST_R5 ;
} else {
UsePublicObjectHeaders $(objects) : $(headerDirs) ;
ObjectDefines $(objects) : TEST_OBOS ;
}
# Turn debugging on. That is usually desired for test code.
ObjectCcFlags $(objects) : "-g" ;
ObjectC++Flags $(objects) : "-g" ;
# Turn optimization on again.
OPTIM = $(optim) ;
}
rule R5SharedLibraryNames
{
# R5SharedLibraryNames <sources> ;
# Returns a list of shared library names given a list of file names. NO
# GRISTING IS PERFORMED :-) However, each library names gets "_r5" inserted
# before the shared lib suffix.
return $(1:S=)_r5.so ;
}
rule SimpleTest
{
# UnitTest <target> : <sources> : <libraries>
# Builds a unit test for an OBOS module.
# <target> The name of the target.
# <sources> The list of sources.
# <dest> The directory for the target (as passed to FDirName).
# <libraries> A list of link libraries (as passed to LinkSharedOSLibs).
# <public headers> A list of public header dirs (as passed to
# UsePublicHeaders).
local target = $(1) ;
local sources = $(2) ;
local libraries = $(3) ;
local relPath = [ FRelPath src tests : $(SUBDIR_TOKENS) ] ;
# Turn optimization off.
local optim = $(OPTIM) ;
OPTIM = ;
# SetupIncludes ;
SetupObjectsDir ;
MakeLocateObjects $(sources) ;
Main $(target) : $(sources) ;
MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(relPath) ] ;
Depends obostests : $(target) ;
LinkSharedOSLibs $(target) : $(libraries) ;
ObjectDefines $(sources) : TEST_OBOS ;
# Turn debugging on. That is usually desired for test code.
ObjectCcFlags $(sources) : "-g" ;
ObjectC++Flags $(sources) : "-g" ;
# Turn optimization on again.
OPTIM = $(optim) ;
}
rule Addon
{
# Addon <name> : <relpath> : <sources> ;
# SetupIncludes ;
SetupObjectsDir ;
Main $(1) : $(3) ;
# Create output dir path for addon
local targetdir;
targetdir = [ FDirName $(OBOS_ADDON_DIR) $(2) ] ;
MakeLocate $(1) : $(targetdir) ;
LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
-nostart -Xlinker -soname=\"$(1)\" ;
}
rule R5KernelAddon
{
# R5KernelAddon <name> : <relpath> : <sources> ;
local sources = $(3) ;
Addon $(1) : $(2) : $(3) ;
ObjectCcFlags $(sources) : -D_KERNEL_MODE=1 -no-fpic ;
ObjectC++Flags $(sources) : -D_KERNEL_MODE=1 -no-fpic
-fno-exceptions -fno-rtti ;
LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ] -nostdlib ;
LinkSharedOSLibs $(1) : /boot/develop/lib/x86/_KERNEL_ ;
}
rule Translator
{
# Translator <name> : <sources> ;
SetupObjectsDir ;
Main $(1) : $(2) ;
# Create output dir path for translator
local targetdir;
targetdir = [ FDirName $(OBOS_ADDON_DIR) translators ] ;
MakeLocate $(1) : $(targetdir) ;
}
rule MakeLocateObjects
{
# MakeLocateObjects <gristed_sources_or_objects> ;
local _objs = $(1:S=$(SUFOBJ)) ;
for o in $(_objs)
{
local dir = $(o:D) ;
if $(dir) {
MakeLocate $(o) : [ FDirName $(LOCATE_TARGET) $(dir) ] ;
} else {
MakeLocate $(o) : $(LOCATE_TARGET) ;
}
}
}
rule StaticLibrary
{
# StaticLibrary <name> : <sources> ;
# SetupIncludes ;
SetupObjectsDir ;
MakeLocateObjects $(2) ;
Library lib$(<).a : $(>) ;
MakeLocate lib$(<).a : $(OBOS_STLIB_DIR) ;
}
rule SharedLibrary
{
# SharedLibrary <name> : <sources> ;
local _lib = lib$(1).so ;
# SetupIncludes ;
SetupObjectsDir ;
MakeLocateObjects $(2) ;
Main $(_lib) : $(2) ;
MakeLocate $(_lib) : $(OBOS_SHLIB_DIR) ;
LINKFLAGS on $(_lib) = [ on $(_lib) return $(LINKFLAGS) ]
-nostart -Xlinker -soname=\"$(_lib)\" ;
}
rule LinkSharedOSLibs
{
# LinkSharedOSLibs <name> : <libs> ;
# Valid elements for <libs> are e.g. "be" or "libopenbeos.so" or
# "/boot/.../libfoo.so". If the basename starts with "lib" or the thingy
# has a dirname or grist, it is added to the NEEDLIBS variable (i.e. the
# file will be bound!), otherwise it is prefixed "-l" and added to
# LINKLIBS.
for i in $(>)
{
local isfile = ;
if $(i:D) || $(i:G) {
isfile = true ;
} else {
switch $(i:B)
{
case lib* : isfile = true ;
case * : isfile = ;
}
}
if $(isfile) {
NEEDLIBS on $(1) = [ on $(1) return $(NEEDLIBS) ] $(i) ;
Depends $(1) : $(i) ;
} else {
LINKLIBS on $(1) = [ on $(1) return $(LINKLIBS) ] -l$(i) ;
}
}
}
rule LinkStaticOSLibs
{
# LinkStaticOSLibs <name> : <libs> ;
for i in $(>)
{
LINKLIBS on $(<) = $(LINKLIBS) -l $(i) ;
}
}
rule AddResources
{
# AddResources <name> : <resourcefiles> ;
SEARCH on $(2) += $(SEARCH_SOURCE) ;
RESFILES on $(1) += $(2) ;
}
rule PublicHeaders
{
# PublicHeaders <group list>
#
# Returns the directory names for the public header dirs identified by
# <group list>.
local list = $(1) ;
local dirs ;
for i in $(list) {
dirs += [ FDirName $(OBOS_TOP) headers os $(i) ] ;
}
return $(dirs) ;
}
rule PrivateHeaders
{
# PrivateHeaders <group list>
#
# Returns the directory names for the private header dirs identified by
# <group list>.
local list = $(1) ;
local dirs ;
for i in $(list) {
dirs += [ FDirName $(OBOS_TOP) headers private $(i) ] ;
}
return $(dirs) ;
}
rule ArchHeaders
{
# usage: ArchHeaders <arch> ;
#
# <arch> specifies the architecture (e.g. x86).
return [ FDirName $(OBOS_TOP) headers private kernel arch $(1) ] ;
}
rule UsePublicHeaders
{
# UsePublicHeaders <group list> ;
#
# Adds the public C header dirs given by <group list> to the header search
# dirs of the subdirectory.
# NOTE: This rule must be invoked *before* the rule that builds the objects.
UseHeaders [ PublicHeaders $(1) ] ;
}
rule UsePublicObjectHeaders
{
# UsePublicObjectHeaders <sources_or_objects> : <group list> ;
#
# Adds the public C header dirs given by <group list> to the header search
# dirs of <sources_or_objects>.
# NOTE: This rule must be invoked *after* the rule that builds the objects.
ObjectHdrs $(1) : [ PublicHeaders $(2) ] ;
}
rule UsePrivateHeaders
{
# UsePrivateHeaders <group list> ;
#
# Adds the private C header dirs given by <group list> to the header search
# dirs of the subdirectory.
# NOTE: This rule must be invoked *before* the rule that builds the objects.
UseHeaders [ PrivateHeaders $(1) ] ;
}
rule UsePrivateObjectHeaders
{
# UsePrivateObjectHeaders <sources_or_objects> : <group list> ;
#
# Adds the private C header dirs given by <group list> to the header search
# dirs of <sources_or_objects>.
# NOTE: This rule must be invoked *after* the rule that builds the objects.
ObjectHdrs $(1) : [ PrivateHeaders $(2) ] ;
}
rule UseHeaders
{
# UseHeaders <headers> ;
#
# Adds the C header dirs <headers> to the header search
# dirs of the subdirectory.
# NOTE: This rule must be invoked *before* the rule that builds the objects.
local header ;
for header in $(1) {
SubDirHdrs $(header) ;
}
}
rule UseCppUnitHeaders
{
SubDirHdrs [ FDirName $(OBOS_TOP) headers tools cppunit ] ;
}
rule UseCppUnitObjectHeaders
{
ObjectHdrs $(1) : [ FDirName $(OBOS_TOP) headers tools cppunit ] ;
}
rule UseArchHeaders
{
# usage: UseArchHeaders <arch> ;
#
# <arch> specifies the architecture (e.g. x86).
# NOTE: This rule must be invoked *before* the rule that builds the objects.
local headers = [ ArchHeaders $(1) ] ;
local opt = -D$(OBOS_TARGET_DEFINE) ;
SubDirCcFlags $(opt) ;
SubDirC++Flags $(opt) ;
SubDirHdrs $(headers) ;
}
rule UseArchObjectHeaders
{
# usage: UseArchObjectHeaders <sources_or_objects> : <arch> ;
#
# <arch> specifies the architecture (e.g. x86).
# <sources_or_objects> Source or object files.
# NOTE: This rule must be invoked *after* the rule that builds the objects.
local targets = $(1) ;
local headers = [ ArchHeaders $(2) ] ;
local opt = -D$(OBOS_TARGET_DEFINE) ;
ObjectCcFlags $(targets) : $(opt) ;
ObjectC++Flags $(targets) : $(opt) ;
ObjectHdrs $(targets) : $(headers) ;
}
rule UsePosixHeaders
{
# UsePrivateHeaders <group list> ;
#
# Adds the POSIX header dir to the header search
# dirs of the subdirectory.
# NOTE: This rule must be invoked *before* the rule that builds the objects.
SubDirHdrs [ FDirName $(OBOS_TOP) headers posix ] ;
}
rule UsePosixObjectHeaders
{
# UsePosixObjectHeaders <sources_or_objects> ;
#
# Adds the POSIX header dir to the header search
# dirs of <sources_or_objects>.
# NOTE: This rule must be invoked *after* the rule that builds the objects.
ObjectHdrs $(1) : [ FDirName $(OBOS_TOP) headers posix ] ;
}
rule SplitPath
{
# SplitPath <path> ;
# Decomposes a path into its components.
local path = $(1:G=) ;
local components ;
# $(path:D) for "/" is "/". Therefore the second condition.
while $(path:D) && $(path:D) != $(path)
{
# Note: $(path:B) returns "." for "..", but $(path:D=) is fine.
components = $(path:D=) $(components) ;
path = $(path:D) ;
}
components = $(path) $(components) ;
return $(components) ;
}
rule PrependObjectHdrs
{
# PrependObjectHdrs <objects_or_sources> : <dirs> ;
# Prepends <dirs> to the list of header search dirs of the objects
# specified by <objects_or_sources>. The HDRS variable will not be
# changed, only CCHDRS.
# Note: A subsequent ObjectHdrs invocation will therefore undo the
# effect of this rule.
# NOTE: This is a hack.
local objects = [ FGristFiles $(1:S=$(SUFOBJ)) ] ;
local dirs = $(2) ;
for object in $(objects) {
# Don't change HDRS to avoid screwing up the header scanning.
PREPENDED_HDRS on $(object)
= $(dirs) [ on $(object) return $(PREPENDED_HDRS) ] ;
CCHDRS on $(object)
= [ FIncludes [ on $(object) return $(PREPENDED_HDRS) $(HDRS) ] ] ;
}
}
rule SymLink
{
# SymLink <target> : <source> ;
# Links <target> to <source>.
# <source> is the exact link contents. No binding is done.
LINKCONTENTS on $(1) = $(2) ;
SymLink1 $(1) ;
LocalDepends all : $(target) ;
}
actions SymLink1
{
$(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)"
}
rule RelSymLink
{
# RelSymLink <link> : <link target>
# Creates a relative symbolic link from <link> to <link target>.
# <link> and <link target> can be usual targets. They may have a grist
# and don't need to have any dirname. Their LOCATE variables are used to
# find their locations.
local target = $(1) ;
local source = $(2) ;
local targetDir = [ on $(target) FDirName $(LOCATE[1]) $(target:D) ] ;
local sourceDir = [ on $(source) FDirName $(LOCATE[1]) $(source:D) ] ;
local sourcePath = $(source:G=) ;
sourcePath = $(sourcePath:D=$(sourceDir)) ;
local targetDirComponents = [ SplitPath $(targetDir) ] ;
local sourceComponents = [ SplitPath $(sourcePath) ] ;
SymLink $(target)
: [ FRelPath $(targetDirComponents) : $(sourceComponents) ] ;
NOUPDATE $(target);
Depends $(target) : $(source) ;
}
#-------------------------------------------------------------------------------
# Low-level OBOS utility rules
#-------------------------------------------------------------------------------
rule SetupObjectsDir
{
local rel_objectsdir;
# Copy subdir tokens except the first, as that will be "sources", and we
# do not want to include that :)
rel_objectsdir = [ FDirName $(SUBDIR_TOKENS[2-]) ] ;
LOCATE_TARGET = [ FDirName $(OBOS_OBJECT_TARGET) $(rel_objectsdir) ] ;
}
#-------------------------------------------------------------------------------
# Link rule/action are overwritten as they don't handle linking files who's name
# contain spaces very well. Also adds resources and version to executable.
#-------------------------------------------------------------------------------
rule Link
{
# Note: RESFILES must be set before invocation.
MODE on $(<) = $(EXEMODE) ;
on $(1) XRes $(1) : $(RESFILES) ;
SetVersion $(1) ;
Chmod $(<) ;
SetType $(1) ;
MimeSet $(1) ;
}
actions Link bind NEEDLIBS
{
$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(2)" "$(NEEDLIBS)" $(LINKLIBS) ;
}
# BeOS specific rules
rule XRes
{
# XRes <target> : <resource files>
if $(2)
{
Depends $(1) : $(2) ;
XRes1 $(1) : $(2) ;
}
}
rule XRes1 { }
rule SetVersion
{
# SetVersion <target>
}
rule SetType
{
# SetType <target>
}
rule MimeSet
{
# SetType <target>
}
if $(OS) = BEOS
{
actions XRes1
{
xres -o "$(1)" "$(2)" ;
}
actions SetVersion
{
setversion "$(1)" -system $(OBOS_BUILD_VERSION) -short "$(OBOS_BUILD_DESCRIPTION)" ;
}
actions SetType
{
settype -t $(OBOS_TARGET_TYPE) "$(1)" ;
}
actions MimeSet
{
mimeset -f "$(1)" ;
}
} # if BEOS
rule assemble
{
Depends $(<) : $(>) ;
ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;
ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
}
actions assemble
{
$(CC) -c "$(2)" -O2 $(ASFLAGS) $(KERNEL_CCFLAGS) $(ASHDRS) -o "$(1)" ;
}
# Overridden to allow spaces in file names.
actions Chmod1
{
$(CHMOD) "$(MODE)" "$(1)"
}
rule ObjectReference
{
# ObjectReference <reference object> : <source object>
# Makes <reference object> refer to the same file as <source object>.
# The filenames must of course be identical.
# <source object> must have already been LOCATEd.
local ref = $(1) ;
local source = $(2) ;
if $(ref) != $(source) {
Depends $(ref) : $(source) ;
on $(ref) LOCATE = [ on $(source) return $(LOCATE) ] ;
}
}
rule ObjectReferences
{
# ObjectReferences <source objects>
# Creates local references to <source objects>, i.e. identifiers with the
# current grist referring to the same files. <source objects> must have
# already been LOCATEd.
local source ;
for source in $(1) {
ObjectReference [ FGristFiles $(source) ] : $(source) ;
}
}
rule Filter
{
# Filter <list> : <excludes> ;
# Removes all occurrences of <excludes> in <list>.
local list = $(1) ;
local excludes = $(2) ;
local newList ;
local item ;
for item in $(list) {
local skip ;
local exclude ;
for exclude in $(excludes) {
if $(item) = $(exclude) {
skip = true ;
}
}
if ! $(skip) {
newList += item ;
}
}
return $(newList) ;
}
## Kernel stuff!
rule SetupKernel
{
# Usage SetupKernel <sources_or_objects> : <extra_cc_flags>;
local _objs = $(1:S=$(SUFOBJ)) ;
UsePublicHeaders kernel support drivers ;
UsePublicHeaders [ FDirName os kernel ] ;
UsePrivateHeaders kernel ;
UsePosixHeaders ;
UseArchHeaders $(OBOS_ARCH) ;
SetupObjectsDir ;
CCFLAGS on $(_objs) = $(KERNEL_CCFLAGS) $(2) ;
C++FLAGS on $(_objs) = $(KERNEL_CCFLAGS) $(2) ;
}
rule KernelObjects
{
SetupKernel $(1) : $(2) ;
Objects $(1) ;
}
rule KernelLd
{
# KernelLd <name> : <objs> : <linkerscript> : <args> : <gcc_off> ;
SetupKernel $(2) ;
LINK on $(1) = ld ;
LINKFLAGS on $(1) = $(4) ;
if $(3) { LINKFLAGS on $(1) += --script=$(3) ; }
# Remove any preset LINKLIBS
LINKLIBS on $(1) = ;
# Show that we depend on the libraries we need
LocalClean clean : $(1) ;
LocalDepends all : $(1) ;
Depends $(1) : $(2) ;
if $(6) {
for i in $(6) {
KernelConfigSection $(i) : elf32 : $(1) ;
}
}
MakeLocate $(1) : $(LOCATE_TARGET) ;
# Add libgcc.a - NB this should be detected not hard coded!
if ! $(5) {
LINKLIBS on $(1) += -L $(GCC_PATH) -lgcc ;
}
}
actions KernelLd
{
$(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" $(LINKLIBS) ;
}
rule KernelStaticLibrary
{
# Usage KernelStaticLibrary <name> : <sources> : <extra cc flags> ;
# This is designed to take a set of sources and libraries and create
# a file called lib<name>.a
SetupKernel $(2) : $(3) ;
MakeLocateObjects $(2) ;
Library $(1) : $(2) ;
}
rule KernelStaticLibraryObjects
{
# Usage KernelStaticLibrary <name> : <sources> ;
# This is designed to take a set of sources and libraries and create
# a file called <name>
SetupKernel $(2) ;
# Show that we depend on the libraries we need
LocalClean clean : $(1) ;
LocalDepends all : $(1) ;
Depends $(1) : $(2) ;
MakeLocate $(1) : $(LOCATE_TARGET) ;
}
actions KernelStaticLibraryObjects
{
ar -r "$(1)" "$(2)" ;
}
rule SystemMain
{
# Usage SystemMain <target> : <sources> ;
SetupObjectsDir ;
LINKLIBS on $(1) = ;
Main $(1) : $(2) ;
}
rule KernelConfigSection
{
# KernelConfigSection <section> : <type> : <file> ;
SECTION_NAMES on $(OBOS_KERNEL_CONFIG) += $(1) ;
SECTION_TYPES on $(OBOS_KERNEL_CONFIG) += $(2) ;
SECTION_FILES on $(OBOS_KERNEL_CONFIG) += $(3) ;
Depends $(OBOS_KERNEL_CONFIG) : $(3) ;
}
rule WriteKernelConfig
{
# usage: WriteKernelConfig <target> ;
LocalDepends files : $(1) ;
MakeLocate $(1) : $(OBOS_OBJECT_TARGET) ;
LocalClean clean : $(1) ;
}
actions WriteKernelConfig bind SECTION_FILES
{
target="$(1)"
echo "# OpenBeOS Kernel Config File" > "$target"
echo "# Automatically generated - do not edit!" >> "$target"
count=0
for section in "$(SECTION_NAMES)" ; do
count=`expr $count + 1`
eval section$count="$section"
done
i=1
for type in "$(SECTION_TYPES)" ; do
eval type$i="$type"
i=`expr $i + 1`
done
i=1
for file in "$(SECTION_FILES)" ; do
eval file$i="$file"
i=`expr $i + 1`
done
for i in `seq $count` ; do
eval section="\$section$i"
eval type="\$type$i"
eval file="\$file$i"
echo "" >> "$target"
echo "["$section"]" >> "$target"
echo "type="$type >> "$target"
case "$file" in
/*) ;;
*) file=`pwd`/"$file";;
esac
echo "file="$file >> "$target"
done
}
rule BuildKernel
{
# Usage BuildKernel <target> : <config_file> ;
local kernel = $(1) ;
local configFile = $(2) ;
local bootmaker = bootmaker ;
LocalDepends all : $(kernel) ;
Depends $(kernel) : $(configFile) $(bootmaker) ;
LocalClean clean : $(kernel) ;
MakeLocate $(kernel) : $(LOCATE_TARGET) ;
BOOT_MAKER on $(kernel) = $(bootmaker) ;
}
actions BuildKernel bind BOOT_MAKER
{
"$(BOOT_MAKER)" --strip-debug --strip-binary strip "$(2)" -o "$(1)" ;
echo ""
echo "Kernel linked!"
echo ""
}
rule KernelFloppyImage
{
# Usage KernelFloppyImage <target> : <kernel> : <bootblock> ;
local floppy = $(1) ;
local kernel = $(2) ;
local bootblock = $(3) ;
local makeflop = makeflop ;
LocalDepends all : $(floppy) ;
Depends $(floppy) : $(kernel) $(bootblock) $(makeflop) ;
LocalClean clean : $(floppy) ;
MakeLocate $(floppy) : $(OBOS_OBJECT_TARGET) ;
BOOT_BLOCK on $(floppy) = $(bootblock) ;
MAKE_FLOP on $(floppy) = $(makeflop) ;
}
# This may be a bit verbose, but I think it's useful to show what's
# going on, at least in this early stage of development.
actions KernelFloppyImage bind BOOT_BLOCK bind MAKE_FLOP
{
"$(MAKE_FLOP)" "-p $(shell expr 18 \* 2 \* 512)" "$(BOOT_BLOCK)" "$(2)" "$(1)" ;
echo ""
echo "*************************************************"
echo "* Kernel build completed! *"
echo "* Boot image for a 1.44M floppy created *"
echo "*************************************************"
echo ""
echo "Floppy image is $(1)"
echo "The following command will write it to a floppy on BeOS"
echo " dd if=$(1) of=/dev/disk/floppy/raw bs=18k"
echo "Alternatively you can run"
echo " ./configure --floppy /dev/disk/floppy/raw"
echo "once and build + write the image subsequently via"
echo " jam installfloppy"
echo ""
}
rule InstallFloppy
{
# InstallFloppy <target> : <floppy>
# "dd"s <floppy> to $(FLOPPY_PATH).
local target = $(1) ;
local floppy = $(2) ;
NotFile $(target) ;
Always $(target) ;
Depends $(target) : $(floppy) ;
}
actions InstallFloppy
{
if [ -z $(FLOPPY_PATH) ] ; then
echo "Can't install floppy: FLOPPY_PATH not set."
echo "run: ./configure --floppy <floppy path>"
echo
exit 0
fi
dd if=$(2) of=$(FLOPPY_PATH) bs=18k
}