haiku/Jamrules
beveloper e91f3ca1a7 Added a new Jamfile rule, called SubIncludeGPL, which can be used to conditionally
include GPL licensed add-ons into the build. As GPL licensed add-ons may not be
used with non GPL compatible applications, this rule normally is not invoked when
building the tree. However, if the user is sure that he only uses GPL compatible
software, he can use the new ./configure option --include-gpl-addons to enable
the including of GPL licensed addons that are integrated by SubIncludeGPL instead
of SubInclude.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6919 a95241bf-73f2-0310-859d-f6bbb57e9c96
2004-03-06 22:39:28 +00:00

2184 lines
56 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
# The directory for build system specific files
OBOS_BUILD_DIR = [ FDirName $(OBOS_TOP) build ] ;
# Cache files for header scanning and jamfile caching
HCACHEFILE = header_cache ;
JCACHEFILE = jamfile_cache ;
LOCATE on $(HCACHEFILE) $(JCACHEFILE) = $(OBOS_BUILD_DIR) ;
# Include BuildConfig
{
local buildConfig = [ GLOB $(OBOS_BUILD_DIR) : BuildConfig ] ;
if ! $(buildConfig)
{
ECHO "No BuildConfig found in $(OBOS_BUILD_DIR)!" ;
EXIT "Run ./configure in the source tree's root directory first!" ;
}
LOCATE on BuildConfig = $(OBOS_BUILD_DIR) ;
include BuildConfig ;
}
# analyze GCC version
if ! $(GCC_RAW_VERSION) {
ECHO "Variable GCC_RAW_VERSION not set. Please run ./configure or" ;
EXIT "specify it manually." ;
}
GCC_VERSION = ;
{
# split the raw version string at `.' and `-' characters
local version = $(GCC_RAW_VERSION) ;
while $(version) {
local split = [ Match "([^.-]*)[.-](.*)" : $(version) ] ;
if $(split) {
GCC_VERSION += $(split[1]) ;
version = $(split[2]) ;
} else {
GCC_VERSION += $(version) ;
version = ;
}
}
}
# Save the platform default headers.
PLATFORM_DEFAULT_HEADERS = $(HDRS) ;
# We do not include any local BeOS system headers by default
CCFLAGS += -nostdinc ;
C++FLAGS += -nostdinc ;
# Determine if we're building on PPC or x86
# Determine mimetype of executable
# Cross compiling can come later
TARGET_CPU ?= $(OSPLAT:L) ;
OBOS_VERSION ?= R1 ;
switch $(TARGET_CPU) {
case ppc :
{
if $(METROWERKS) {
# at least parts of OpenBeOS still can be compiled with
# the Metrowerks compiler on BeOS/PPC
OBOS_TARGET_TYPE ?= "application/x-be-executable" ;
} else {
OBOS_TARGET_TYPE ?= "application/x-vnd.Be-elfexecutable" ;
}
DEFINES += __POWERPC__ ;
OBOS_BOOT_PLATFORM = openfirmware ;
}
case x86 :
{
# nothing special to do here...
OBOS_BOOT_PLATFORM = bios_ia32 ;
}
case * :
Exit "Currently unsupported build platform:" $(TARGET_CPU) ;
}
# set target specific variables
{
#Echo "Building for" $(TARGET_CPU) ;
OBOS_TARGET ?= $(TARGET_CPU).$(OBOS_VERSION) ;
OBOS_TARGET_TYPE ?= "application/x-vnd.Be-elfexecutable" ;
OBOS_ARCH ?= $(TARGET_CPU) ;
OBOS_TARGET_DEFINE ?= "ARCH_"$(TARGET_CPU) ;
}
# Disable warnings only if WARNINGS is set to 0
# Should be enabled by default later
#
WARNINGS ?= 1 ;
if $(WARNINGS) = 1 {
# 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 ;
} else {
CCFLAGS += -Wno-multichar ;
C++FLAGS += -Wno-multichar ;
}
# standard kernel C/C++ flags
KERNEL_CCFLAGS ?= -Wall -Wno-multichar -Wmissing-prototypes -finline -nostdinc ;
KERNEL_CCFLAGS += -fno-builtin -D$(OBOS_TARGET_DEFINE) ;
KERNEL_CCFLAGS += -DBOCHS_DEBUG_HACK=$(BOCHS_DEBUG_HACK) -D_KERNEL_MODE ;
KERNEL_C++FLAGS ?= -Wall -Wno-multichar -Wmissing-prototypes -finline -nostdinc ;
KERNEL_C++FLAGS += -fno-builtin -fno-exceptions -fno-rtti -D$(OBOS_TARGET_DEFINE) ;
KERNEL_C++FLAGS += -DBOCHS_DEBUG_HACK=$(BOCHS_DEBUG_HACK) -D_KERNEL_MODE ;
if $(GCC_VERSION[1]) >= 3 {
KERNEL_C++FLAGS += -fno-use-cxa-atexit ;
}
# We might later want to introduce debug levels or handle the whole issue
# differently. For now there's only on or off.
#
DEBUG ?= 0 ;
if $(DEBUG) != 0 {
OPTIM ?= -O0 ;
CCFLAGS += -g [ FDefines DEBUG=$(DEBUG) ] ;
C++FLAGS += -g [ FDefines DEBUG=$(DEBUG) ] ;
KERNEL_CCFLAGS += -g [ FDefines DEBUG=$(DEBUG) ] ;
KERNEL_C++FLAGS += -g [ FDefines DEBUG=$(DEBUG) ] ;
LINKFLAGS += -g ;
} else {
OPTIM ?= -O2 ;
}
#
# To disable for the tests OPTIM and DEBUG are overridden, set the environment
# variable NO_TEST_DEBUG.
# Instructs the Library rule to not make its object files temporary.
# This is needed as some objects are used in a static library and for an
# executable.
KEEPOBJS = true ;
# under BeOS use copyattr instead of cp
if $(OS) = BEOS
{
CP = copyattr --data ;
}
# 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
OBOS_ADDON_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system add-ons ] ;
OBOS_APPS_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos apps ] ;
OBOS_BIN_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos bin ] ;
OBOS_ETC_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos etc ] ;
OBOS_FONTS_DIR ?= [ FDirName $(OBOS_ETC_DIR) fonts ] ;
OBOS_KERNEL_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system ] ;
OBOS_PREFS_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos preferences ] ;
OBOS_SERVER_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system servers ] ;
OBOS_SHLIB_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system lib ] ;
OBOS_STLIB_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) develop lib
$(OBOS_ARCH) ] ;
OBOS_TEST_DIR ?= [ FDirName $(OBOS_TOP) tests ] ;
OBOS_PACKAGE_DIR ?= [ FDirName $(OBOS_TOP) packages $(OBOS_TARGET) ] ;
OBOS_PACKAGE_OBJECT_DIR ?= [ FDirName $(OBOS_OBJECT_TARGET) packages ] ;
OBOS_KERNEL_CONFIG = config.$(OBOS_ARCH).ini ;
OBOS_KERNEL = kernel.$(OBOS_ARCH) ;
OBOS_FLOPPY = floppy.$(OBOS_ARCH) ;
rule SetupIncludes
{
# XXX add "opengl" later
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 ;
# Overwrite any exiting content when changing HDRS. This rule may be invoked multiple times.
# Use headers directory, to allow to do things like include <posix/string.h>
HDRS = [ FDirName $(OBOS_TOP) headers ] ;
# Use posix headers directory
HDRS += [ FDirName $(OBOS_TOP) headers posix ] ;
# Use public OS header directories
HDRS += [ PublicHeaders $(os_includes) ] ;
# Used as a fallback, the R5 header directories (we should remove this as soon as possible)
HDRS += /boot/develop/headers/posix /boot/develop/headers/cpp ;
# The platform dependent headers.
HDRS += $(PLATFORM_HEADERS) ;
}
rule SetupR5Includes
{
# Unsets HDRS, so that the OBOS headers do not `shadow' the system headers.
HDRS = ;
}
rule SetupDefaultIncludes
{
# Resets HDRS to the default headers for the build platform.
HDRS = $(PLATFORM_DEFAULT_HEADERS) ;
}
#-------------------------------------------------------------------------------
# Things Jam needs in order to work :)
#-------------------------------------------------------------------------------
# TODO: back-ported from jam 2.5: remove when not longer needed
rule MakeLocate
{
if $(>)
{
LOCATE on $(<) = $(>) ;
Depends $(<) : $(>[1]:G=dir) ;
MkDir $(>[1]:G=dir) ;
}
}
rule Object
{
# This is basically the original Jambase 2.4 Object rule stripped by
# comments. Only the final switch statement has been changed to allow
# intermediate C++ files for Yacc and Lex.
LocalClean clean : $(<) ;
MakeLocate $(<) : $(LOCATE_TARGET) ;
SEARCH on $(>) = $(SEARCH_SOURCE) ;
HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
HDRRULE on $(>) = HdrRule ;
HDRSCAN on $(>) = $(HDRPATTERN) ;
HDRSEARCH on $(>) =
$(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;
HDRGRIST on $(>) = $(HDRGRIST) ;
DEFINES on $(<) += $(DEFINES) ;
# if source is not .c, generate .c with specific rule
switch $(>:S)
{
case .asm : As $(<) : $(>) ;
case .c : Cc $(<) : $(>) ;
case .C : C++ $(<) : $(>) ;
case .cc : C++ $(<) : $(>) ;
case .cpp : C++ $(<) : $(>) ;
case .f : Fortran $(<) : $(>) ;
case .l : if [ on $(2) return $(GENERATE_C++) ] {
C++ $(<) : $(<:S=.cpp) ;
LexC++ $(<:S=.cpp) : $(>) ;
} else {
Cc $(<) : $(<:S=.c) ;
Lex $(<:S=.c) : $(>) ;
}
case .s : As $(<) : $(>) ;
case .y : if [ on $(2) return $(GENERATE_C++) ] {
C++ $(<) : $(<:S=.cpp) ;
Bison $(<:S=.cpp) : $(>) ;
} else {
Cc $(<) : $(<:S=$(YACCGEN)) ;
Yacc $(<:S=$(YACCGEN)) : $(>) ;
}
case * : UserObject $(<) : $(>) ;
}
}
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> : <libraries> ;
SetupIncludes ;
SetupObjectsDir ;
Main $(1) : $(2) ;
MakeLocate $(1) : $(OBOS_APPS_DIR) ;
LinkSharedOSLibs $(1) : $(3) ;
LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
-Xlinker -soname=_APP_ ;
}
rule BinCommand
{
# BinCommand <name> : <sources> : <libraries> ;
SetupIncludes ;
SetupObjectsDir ;
Main $(1) : $(2) ;
MakeLocate $(1) : $(OBOS_BIN_DIR) ;
LinkSharedOSLibs $(1) : $(3) ;
LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
-Xlinker -soname=_APP_ ;
}
rule StdBinCommands
{
# StdBinCommands <sources> : <libs> ;
SetupIncludes ;
SetupObjectsDir ;
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> : <libraries> ;
SetupIncludes ;
SetupObjectsDir ;
Main $(1) : $(2) ;
MakeLocate $(1) : $(OBOS_PREFS_DIR) ;
LinkSharedOSLibs $(1) : $(3) ;
LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
-Xlinker -soname=_APP_ ;
}
rule Server
{
# Server <name> : <sources> : <libraries> ;
SetupIncludes ;
SetupObjectsDir ;
Main $(1) : $(2) ;
MakeLocate $(1) : $(OBOS_SERVER_DIR) ;
LinkSharedOSLibs $(1) : $(3) ;
LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ]
-Xlinker -soname=_APP_ ;
}
# 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 and
# removes `-nostdinc' from the CC and C++ flags to enable system headers.
# <sources> The source files.
# Remove `-nostdinc' from CCFLAGS and C++FLAGS.
local oldCCFLAGS = $(CCFLAGS) ;
local oldC++FLAGS = $(C++FLAGS) ;
CCFLAGS = [ Filter $(CCFLAGS) : -nostdinc ] ;
C++FLAGS = [ Filter $(C++FLAGS) : -nostdinc ] ;
local sources = $(1) ;
local source ;
for source in [ FGristFiles $(sources) ]
{
local object = [ R5ObjectNames $(source) ] ;
Object $(object) : $(source) ;
LocalDepends obj : $(object) ;
}
# Reset CCFLAGS and C++FLAGS to original values.
CCFLAGS = $(oldCCFLAGS) ;
C++FLAGS = $(oldC++FLAGS) ;
}
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.
if ! $(NO_TEST_DEBUG) {
local optim = $(OPTIM) ;
OPTIM = ;
}
SetupObjectsDir ;
# compile
if $(r5) {
SetupR5Includes ;
objects = [ R5ObjectNames $(sources) ] ;
R5Objects $(sources) ;
} else {
SetupIncludes ;
objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
Objects $(sources) ;
}
# set headers/defines
UseCppUnitObjectHeaders $(sources) : $(objects) ;
if $(r5) {
ObjectsDefines $(objects) : TEST_R5 ;
} else {
UsePublicObjectHeaders $(sources) : $(headerDirs) : $(objects) ;
ObjectsDefines $(objects) : TEST_OBOS ;
}
if ! $(NO_TEST_DEBUG) {
# 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.
if ! $(NO_TEST_DEBUG) {
local optim = $(OPTIM) ;
OPTIM = ;
}
SetupIncludes ;
SetupObjectsDir ;
MakeLocateObjects $(sources) ;
Main $(target) : $(sources) ;
MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(relPath) ] ;
Depends obostests : $(target) ;
LinkSharedOSLibs $(target) : $(libraries) ;
ObjectsDefines $(sources) : TEST_OBOS ;
if ! $(NO_TEST_DEBUG) {
# 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> : <is executable> : <libraries> ;
# <name>: Name of the add-on.
# <relpath>: Path where the add-on shall live relative to the add-on dir.
# <sources>: Source files.
# <is executable>: true, if the target shall be executable as well.
# <libraries>: Libraries to be linked against.
local isExecutable = $(4) ;
SetupIncludes ;
SetupObjectsDir ;
Main $(1) : $(3) ;
# Create output dir path for addon
local targetdir;
targetdir = [ FDirName $(OBOS_ADDON_DIR) $(2) ] ;
MakeLocate $(1) : $(targetdir) ;
local linkFlags = -Xlinker -soname=\"$(1)\" ;
if $(isExecutable) != true {
linkFlags = -nostart $(linkFlags) ;
}
LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ] $(linkFlags) ;
LinkSharedOSLibs $(1) : $(5) ;
}
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> : <libraries> ;
SetupIncludes ;
SetupObjectsDir ;
Main $(1) : $(2) ;
LinkSharedOSLibs $(1) : $(3) ;
# Create output dir path for translator
local targetdir;
targetdir = [ FDirName $(OBOS_ADDON_DIR) Translators ] ;
MakeLocate $(1) : $(targetdir) ;
}
rule MakeLocateObjects
{
# MakeLocateObjects <sources_or_objects> ;
local _objs = [ FGristFiles $(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> [ : <target dir> ] ;
# Creates a static library from sources.
# <name>: Basename of the library, without leading "lib" and trailing ".a".
# Grist is allowed -- it will be re-prepended after constructing
# the complete library name.
# <source>: List of source files.
# <target dir>: Directory into which the library shall be placed. Defaults
# to the objects directory for this subdir. If
# STATIC_LIBRARY_DIR is supplied (the literal string)
# the standard directory for static libs is used, otherwise
# the parameter is interpreted as directory path.
#
local lib = lib$(1:B)$(SUFLIB) ;
lib = $(lib:G=$(1:G)) ;
SetupIncludes ;
SetupObjectsDir ;
MakeLocateObjects $(2) ;
Library $(lib) : $(2) ;
local targetDir = $(3) ;
if $(targetDir) {
if $(targetDir) = STATIC_LIBRARY_DIR {
targetDir = $(OBOS_STLIB_DIR) ;
}
MakeLocate $(lib) : $(targetDir) ;
} else {
# nothing to do, since the Library rule already located the library
# in $(LOCATE_TARGET)
}
# If KEEPOBJS is set, Library doesn't make the library depend on
# `lib'.
if $(KEEPOBJS) {
LocalDepends lib : $(lib) ;
}
}
rule R5KernelStaticLibrary
{
# R5KernelStaticLibrary <name> : <sources> ;
local lib = lib$(1)$(SUFLIB) ;
local sources = $(2) ;
SetupIncludes ;
SetupObjectsDir ;
MakeLocateObjects $(sources) ;
Library $(lib) : $(sources) ;
ObjectCcFlags $(sources) : -D_KERNEL_MODE=1 -no-fpic ;
ObjectC++Flags $(sources) : -D_KERNEL_MODE=1 -no-fpic
-fno-exceptions -fno-rtti ;
}
rule MergeObjectFromObjects
{
# MergeObjectFromObjects <name> : <objects> : <other objects> ;
# Merges object files to an object file.
# <name>: Name of the object file to create. No grist will be added.
# <objects>: Object files to be merged. Grist will be added.
# <other objects>: Object files or static libraries to be merged. No grist
# will be added.
#
local objects = [ FGristFiles $(2) ] ;
MakeLocate $(1) : $(LOCATE_TARGET) ;
Depends $(1) : $(objects) ;
Depends $(1) : $(3) ;
LINK on $(1) = ld ;
MergeObjectFromObjects1 $(1) : $(objects) $(3) ;
}
actions MergeObjectFromObjects1
{
$(LINK) -r $(2) -o $(1) ;
}
rule MergeObject
{
# MergeObject <name> : <sources> : <other objects> ;
# Compiles source files and merges the object files to an object file.
# <name>: Name of the object file to create. No grist will be added.
# <sources>: Sources to be compiled. Grist will be added.
# <other objects>: Object files or static libraries to be merged. No grist
# will be added.
#
SetupIncludes ;
SetupObjectsDir ;
MakeLocateObjects $(2) ;
Objects $(2) ;
MergeObjectFromObjects $(1) : $(2:S=$(SUFOBJ)) : $(3) ;
}
rule SharedLibraryFromObjects
{
# SharedLibraryFromObjects <name> : <objects> : <libraries> ;
local _lib = lib$(1:B).so ;
_lib = $(_lib:G=$(1:G)) ;
MainFromObjects $(_lib) : $(2) ;
MakeLocate $(_lib) : $(OBOS_SHLIB_DIR) ;
LINKFLAGS on $(_lib) = [ on $(_lib) return $(LINKFLAGS) ]
-nostart -Xlinker -soname=\"$(_lib)\" ;
LinkSharedOSLibs $(_lib) : $(3) ;
}
rule SharedLibrary
{
# SharedLibrary <name> : <sources> : <libraries> ;
SetupIncludes ;
SetupObjectsDir ;
MakeLocateObjects $(2) ;
Objects $(2) ;
SharedLibraryFromObjects $(1) : $(2:S=$(SUFOBJ)) : $(3) ;
}
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. If you want to specify a target that isn't a library and
# also has neither grist nor a dirname, you can prepend "<nogrist>" as
# grist; it will be stripped by this rule.
for i in $(>)
{
local isfile = ;
if $(i:D) || $(i:G) {
isfile = true ;
if $(i:G) = <nogrist> {
i = $(i:G=) ;
}
} else {
switch $(i:B)
{
# XXX: _APP_ and _KERNEL_ should not be needed for ELF.
case _APP_ : isfile = true ;
case _KERNEL_ : isfile = true ;
case lib* : isfile = true ;
case * : isfile = ;
}
if ! $(isfile) && ( $(i:S) = .so || $(i:S) = .a ) {
isfile = true ;
}
}
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> ;
local resfiles = [ FGristFiles $(2) ] ;
SEARCH on $(resfiles) += $(SEARCH_SOURCE) ;
for file in $(resfiles) {
if $(file:S) = .rdef {
local rdef = $(file) ;
file = $(rdef:S=.rsrc) ;
ResComp $(file) : $(rdef) ;
}
RESFILES on $(1) += $(file) ;
}
}
rule ResComp
{
# ResComp <resource file> : <rdef file> ;
#
# <resource file> and <rdef file> must be gristed.
SetupObjectsDir ;
SEARCH on $(2) += $(SEARCH_SOURCE) ;
MakeLocate $(1) : $(LOCATE_TARGET) ;
Depends $(1) : $(2) rc ;
LocalClean clean : $(1) ;
ResComp1 $(1) : rc $(2) ;
}
actions ResComp1
{
$(2[1]) -o $(1) $(2[2-])
}
rule ObjectsDefines
{
# Like ObjectDefines, but allows multiple files to be supplied
local file ;
for file in $(1) {
ObjectDefines $(file) : $(2) ;
}
}
rule SourceHdrs
{
# SourceHdrs <sources> : <headers> [ : <gristed objects> ] ;
#
# Is a wrapper for ObjectHdrs, that passes <sources> and <headers> or,
# if supplied <objects> and <headers>, and also adjusts HDRSEARCH (not
# done by ObjectHdrs).
local sources = [ FGristFiles $(1) ] ;
local headers = $(2) ;
local objects = $(3) ;
local file ;
if $(objects) {
for file in $(objects) {
ObjectHdrs $(file) : $(headers) ;
}
} else {
for file in $(sources) {
ObjectHdrs $(file) : $(headers) ;
}
}
# Also add the header search dirs to HDRSEARCH. Note, that these dirs
# will be listed after the STDHDRS (if any), but that's better than not
# being listed at all.
HDRSEARCH on $(sources) += $(headers) ;
}
rule PublicHeaders
{
# PublicHeaders <group list>
#
# Returns the directory names for the public header dirs identified by
# <group list>.
local list = $(1) ;
local dirs = [ FDirName $(OBOS_TOP) headers os ] ;
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 LibraryHeaders
{
# LibraryHeaders <group list>
#
# Returns the directory names for the library header dirs identified by
# <group list>.
local list = $(1) ;
local dirs ;
for i in $(list) {
dirs += [ FDirName $(OBOS_TOP) headers libs $(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> : <group list> [ : <objects> ] ;
#
# Adds the public C header dirs given by <group list> to the header search
# dirs of either the object targets of <sources> or if supplied to
# <objects>. Also adjusts HDRSEARCH of <sources>.
# NOTE: This rule must be invoked *after* the rule that builds the objects.
SourceHdrs $(1) : [ PublicHeaders $(2) ] : $(3) ;
}
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> : <group list> [ : <objects> ] ;
#
# Adds the private C header dirs given by <group list> to the header search
# dirs of either the object targets of <sources> or if supplied to
# <objects>. Also adjusts HDRSEARCH of <sources>.
# NOTE: This rule must be invoked *after* the rule that builds the objects.
SourceHdrs $(1) : [ PrivateHeaders $(2) ] : $(3) ;
}
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
{
# UseCppUnitObjectHeaders <sources> [ : <objects> ] ;
SourceHdrs $(1) : [ FDirName $(OBOS_TOP) headers tools cppunit ] : $(2) ;
}
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) ;
HDRS += $(headers) ;
}
rule UseArchObjectHeaders
{
# usage: UseArchObjectHeaders <sources> : <arch> : [ <objects> ] ;
#
# <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 sources = $(1) ;
local headers = [ ArchHeaders $(2) ] ;
local objects = $(3) ;
local targets ;
if $(objects) {
targets = $(objects) ;
} else {
targets = $(sources) ;
}
local opt = -D$(OBOS_TARGET_DEFINE) ;
ObjectCcFlags $(targets) : $(opt) ;
ObjectC++Flags $(targets) : $(opt) ;
SourceHdrs $(sources) : $(headers) : $(objects) ;
}
rule UsePosixHeaders
{
# XXX changed to do nothing
}
rule UsePosixObjectHeaders
{
# UsePosixObjectHeaders <sources> [ : <objects> ] ;
#
# Adds the POSIX header dir to the header search
# dirs of either the object targets of <sources> or if supplied to
# <objects>. Also adjusts HDRSEARCH of <sources>.
# NOTE: This rule must be invoked *after* the rule that builds the objects.
SourceHdrs $(1) : [ FDirName $(OBOS_TOP) headers posix ] : $(2) ;
}
rule UseLibraryHeaders
{
# UseLibraryHeaders <group list> ;
#
# Adds the library 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 [ LibraryHeaders $(1) ] ;
}
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> : <makeDefaultDependencies> ;
# Links <target> to <source>.
# <source> is the exact link contents. No binding is done.
# <makeDefaultDependencies> If true, <target> will be made a dependency
# of the `all' pseudo target, i.e. it will be made by default, and removed
# on `jam clean'.
local target = $(1) ;
local source = $(2) ;
local makeDefaultDependencies = $(3) ;
if ! $(makeDefaultDependencies) {
makeDefaultDependencies = true ;
}
LINKCONTENTS on $(target) = $(source) ;
SymLink1 $(target) ;
if $(makeDefaultDependencies) = true {
LocalDepends files : $(target) ;
LocalClean clean : $(target) ;
}
}
actions SymLink1
{
$(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)"
}
rule RelSymLink
{
# RelSymLink <link> : <link target> : <makeDefaultDependencies> ;
# 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.
# <makeDefaultDependencies> If true (which is the default), <link> will be
# made a dependency of the `files' pseudo target, i.e. it will be made by
# default, and removed on `jam clean'.
local target = $(1) ;
local source = $(2) ;
local makeDefaultDependencies = $(3) ;
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) ]
: $(makeDefaultDependencies) ;
NOUPDATE $(target) ;
Depends $(target) : $(source) ;
}
rule AbsSymLink
{
# AbsSymLink <link> : <link target> : <link dir>
# : <makeDefaultDependencies> ;
# Creates an absolute symbolic link from <link> to <link target>.
# <link> and <link target> must be usual targets. If <link dir> is
# given, then it is set as LOCATE directory on <link>.
# <makeDefaultDependencies> If true (which is the default), <link> will be
# made a dependency of the `files' pseudo target, i.e. it will be made by
# default, and removed on `jam clean'.
local makeDefaultDependencies = $(4) ;
if ! $(makeDefaultDependencies) {
makeDefaultDependencies = true ;
}
Depends $(1) : $(2) ;
if $(3) {
MakeLocate $(1) : $(3) ;
}
SEARCH on $(2) += $(SEARCH_SOURCE) ;
if $(makeDefaultDependencies) = true {
LocalDepends files : $(1) ;
LocalClean clean : $(1) ;
}
}
actions AbsSymLink
{
target="$(2)"
case "$target" in
/*) ;;
*) target=`pwd`/"$target";;
esac
$(RM) "$(1)" && $(LN) -s "$target" "$(1)"
}
rule OBOSInstall
{
# Usage: OBOSInstall <[ install [ and uninstall ] pseudotarget ]>
# : <directory> : <sources to install>
# : [ <installgrist> ] : [ <install rule> ] ;
local install = $(1[1]) ;
install ?= install ;
local uninstall = $(1[2]) ;
uninstall ?= un$(install) ;
local dir = $(2) ;
local sources = $(3) ;
local installgrist = $(4) ;
installgrist ?= $(INSTALLGRIST) ;
local installRule = $(5) ;
installRule ?= Install ;
local targets = $(sources:G=$(installgrist)) ;
NotFile $(install) ;
NotFile $(uninstall) ;
Depends $(install) : $(targets) ;
Clean $(uninstall) : $(targets) ;
SEARCH on $(sources) += $(SEARCH_SOURCE) ;
MakeLocate $(targets) : $(dir) ;
local source ;
for source in $(sources) {
local target = $(source:G=$(installgrist)) ;
Depends $(target) : $(source) ;
$(installRule) $(target) : $(source) ;
if [ on $(target) return $(MODE) ] {
Chmod $(target) ;
}
if $(OWNER) && $(CHOWN) {
Chown $(target) ;
OWNER on $(target) = $(OWNER) ;
}
if $(GROUP) && $(CHGRP) {
Chgrp $(target) ;
GROUP on $(target) = $(GROUP) ;
}
}
}
rule InstallAbsSymLinkAdapter
{
# InstallAbsSymLinkAdapter <link> : <link target>
if ! [ on $(2) return $(TARGET) ] {
TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
}
AbsSymLink $(1) : $(2) : : false ;
}
rule OBOSInstallAbsSymLink
{
# Usage: OBOSInstallAbsSymLink <[ install [ and uninstall ] pseudotarget ]>
# : <directory> : <sources to install>
# : [ <installgrist> ] ;
OBOSInstall $(1) : $(2) : $(3) : $(4) : InstallAbsSymLinkAdapter ;
}
rule InstallRelSymLinkAdapter
{
# InstallRelSymLinkAdapter <link> : <link target>
if ! [ on $(2) return $(TARGET) ] {
TARGET on $(2) = [ on $(2) return $(SEARCH) ] ;
}
RelSymLink $(1) : $(2) : false ;
}
rule OBOSInstallRelSymLink
{
# Usage: OBOSInstallRelSymLink <[ install [ and uninstall ] pseudotarget ]>
# : <directory> : <sources to install>
# : [ <installgrist> ] ;
OBOSInstall $(1) : $(2) : $(3) : $(4) : InstallRelSymLinkAdapter ;
}
#-------------------------------------------------------------------------------
# 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) ] ;
LOCATE_SOURCE = $(LOCATE_TARGET) ;
SEARCH_SOURCE = [ Filter $(SEARCH_SOURCE) : $(LOCATE_TARGET) ]
$(LOCATE_TARGET) ;
}
#-------------------------------------------------------------------------------
# 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) ;
Chmod $(<) ;
SetType $(1) ;
MimeSet $(1) ;
SetVersion $(1) ;
}
actions Link bind NEEDLIBS
{
$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(2)" "$(NEEDLIBS)" $(LINKLIBS) ;
}
rule LexC++
{
Depends $(1) : $(2) ;
MakeLocate $(1) : $(LOCATE_SOURCE) ;
LocalClean clean : $(1) ;
}
actions LexC++
{
$(LEX) -o$(1) $(2)
}
rule Bison
{
local _h ;
_h = $(1).h ;
MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;
Depends $(<) $(_h) : $(>) ;
Bison1 $(<) $(_h) : $(>) ;
LocalClean clean : $(<) $(_h) ;
# make sure someone includes $(_h) else it will be
# a deadly independent target
Includes $(<) : $(_h) ;
}
actions Bison1
{
bison $(YACCFLAGS) -o $(1[1]) $(2)
}
# 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) -D_ASSEMBLER $(KERNEL_CCFLAGS) $(ASHDRS) -o "$(1)" ;
}
# Overridden to allow spaces in file names.
actions Chmod1
{
$(CHMOD) "$(MODE)" "$(1)"
}
# Overridden to allow spaces in file names.
actions piecemeal together existing Clean
{
$(RM) "$(>)"
}
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) ;
LOCATE on $(ref) = [ 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 = [ FGristFiles $(1:S=$(SUFOBJ)) ] ;
#Setup Kernel header directories
local public_kernel_includes = add-ons/file_system add-ons/graphics device drivers kernel storage support ;
local private_kernel_includes = kernel libroot kernel/boot/platform/$(OBOS_BOOT_PLATFORM) ;
# Use posix headers directory
HDRS = [ FDirName $(OBOS_TOP) headers posix ] ;
# Use public OS header directories
HDRS += [ PublicHeaders $(public_kernel_includes) ] ;
# Use private directories
HDRS += [ PrivateHeaders $(private_kernel_includes) ] ;
# The platform dependent headers.
HDRS += $(PLATFORM_HEADERS) ;
UseArchHeaders $(OBOS_ARCH) ;
SetupObjectsDir ;
CCFLAGS on $(_objs) = $(KERNEL_CCFLAGS) $(2) ;
C++FLAGS on $(_objs) = $(KERNEL_C++FLAGS) $(2) ;
}
rule KernelObjects
{
SetupKernel $(1) : $(2) ;
Objects $(1) ;
}
rule KernelLd
{
# KernelLd <name> : <objs> : <linkerscript> : <args> : <gcc_off> : <config_section> ;
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 the platform specific static libs (libgcc.a).
if ! $(5) {
LINKLIBS on $(1) += $(PLATFORM_LINKLIBS) ;
}
}
actions KernelLd
{
$(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" $(LINKLIBS) ;
}
rule KernelMergeObject
{
# KernelMergeObject <name> : <sources> : <extra CFLAGS> : <other objects> ;
# Compiles source files and merges the object files to an object file.
# <name>: Name of the object file to create. No grist will be added.
# <sources>: Sources to be compiled. Grist will be added.
# <extra CFLAGS>: Additional flags for compilation.
# <other objects>: Object files or static libraries to be merged. No grist
# will be added.
#
SetupKernel $(2) : $(3) ;
MakeLocateObjects $(2) ;
Objects $(2) ;
MergeObjectFromObjects $(1) : $(2:S=$(SUFOBJ)) : $(4) ;
}
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 BuildPlatformMain
{
# Usage BuildPlatformMain <target> : <sources> ;
SetupObjectsDir ;
SetupDefaultIncludes ;
# Remove `-nostdinc' from CCFLAGS and C++FLAGS.
local oldCCFLAGS = $(CCFLAGS) ;
local oldC++FLAGS = $(C++FLAGS) ;
CCFLAGS = [ Filter $(CCFLAGS) : -nostdinc ] ;
C++FLAGS = [ Filter $(C++FLAGS) : -nostdinc ] ;
Main $(1) : $(2) ;
# Reset CCFLAGS and C++FLAGS to original values.
CCFLAGS = $(oldCCFLAGS) ;
C++FLAGS = $(oldC++FLAGS) ;
}
rule BuildPlatformTest
{
# Usage BuildPlatformTest <target> : <sources> ;
local target = $(1) ;
local sources = $(2) ;
BuildPlatformMain $(target) : $(sources) ;
local relPath ;
if [ FIsPrefix src tests : $(SUBDIR_TOKENS) ] {
relPath = $(SUBDIR_TOKENS[3-]) ;
} else {
relPath = $(SUBDIR_TOKENS[2-]) ;
}
MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(relPath) ] ;
}
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
}
#-------------------------------------------------------------------------------
# FreeType 2 specific rules and variables
#-------------------------------------------------------------------------------
FT2_INCLUDE = [ FDirName $(OBOS_TOP) headers libs freetype2 ] ;
FT2_SRC = [ FDirName $(OBOS_TOP) src libs freetype2 ] ;
FT2_LIB = freetype ;
FT2_COMPONENTS ?= gzip # support for gzip-compressed files.
autohint # auto-hinter
base # base component (public APIs)
bdf # BDF font driver
cache # cache sub-system
cff # CFF/CEF font driver
cid # Postscript CID-keyed font driver
pcf # PCF font driver
pfr # PFR/TrueDoc font driver
psaux # Common Postscript routines module
pshinter # Postscript hinter module
psnames # Postscript names handling
raster # Monochrome rasterizer
smooth # Anti-aliased rasterizer
sfnt # SFNT-based format support routines
truetype # TrueType font driver
type1 # Postscript Type 1 font driver
type42 # Postscript Type 42 (embedded TrueType) driver
winfonts # Windows FON/FNT font driver
;
rule UseFreeTypeHeaders
{
SubDirHdrs $(FT2_INCLUDE) ;
}
rule UseFreeTypeObjectHeaders
{
# UseFreeTypeObjectHeaders <sources> [ : <objects> ] ;
SourceHdrs $(1) : $(FT2_INCLUDE) : $(2) ;
}
rule FT2_SubDir
{
# FT2_SubDir <dir>
# <dir>: Components of a directory in the original hierarchy.
local dir = $(1) ;
local topDir ;
switch $(dir[1])
{
case "include" : topDir = $(FT2_INCLUDE) ;
case src : topDir = $(FT2_SRC) ;
case * : ECHO "Unknown FreeType2 directory: " $(dir) ;
}
return [ FDirName $(topDir) $(dir[2-]) ] ;
}
rule FT2_Library
{
# FT2_Library <libname> : <sources>
# Builds objects from sources and adds the objects to the list of objects
# to be linked into the library.
# <libname> The name of the library.
# <sources> The sources.
local library = lib$(1).so ;
local sources = $(2) ;
SetupIncludes ;
SetupObjectsDir ;
MakeLocateObjects $(sources) ;
Objects $(sources) ;
LIBRARY_OBJECTS on $(library) += [ FGristFiles $(sources:S=$(SUFOBJ)) ] ;
}
rule FT2_LinkLibrary
{
# FT2_LinkLibrary <libname>
# Links the library from the objects build with FT2_LIBRARY before.
local library = lib$(1).so ;
local objects = [ on $(library) return $(LIBRARY_OBJECTS) ] ;
ObjectReferences $(objects) ;
objects = [ FGristFiles $(objects) ] ;
SharedLibraryFromObjects $(1) : $(objects) ;
}
#-------------------------------------------------------------------------------
# Packages for OBOS alpha/beta testers
#-------------------------------------------------------------------------------
rule Copy
{
Depends $(<) : $(>) ;
SEARCH on $(>) = $(SEARCH_SOURCE) ;
}
actions Copy
{
cp -dp "$(>)" "$(<)" ;
if [ -f "$(>)" ] ; then copyattr "$(>)" "$(<)" ; fi ;
}
rule Packages
{
local packagenames = $(1) ;
local packagefiles = $(2) ;
local path = $(3) ;
for name in $(packagenames) {
Package $(name) : $(packagefiles) : $(path) ;
}
}
rule Package
{
local packagename = $(1) ;
local packagefiles = $(2) ;
local path = $(3) ;
local packagezip = $(packagename:S=.zip:G=_packages) ;
local packagedir = [ FDirName $(OBOS_PACKAGE_DIR) $(packagename) ] ;
local installscript = install.sh ;
local packageinstallscript = $(installscript:G=_packages!$(packagename)) ;
local installzip = install.zip ;
local packageinstallzip = $(installzip:G=_packages!$(packagename)) ;
local packageobjectdir
= [ FDirName $(OBOS_PACKAGE_OBJECT_DIR) $(packagename) ] ;
local packagefiledir = [ FDirName $(packageobjectdir) $(path) ] ;
local packagefileinstallzip
= $(installzip:G=_package_objects!$(packagename)) ;
# add the files to the install.zip
local packagefilegrist = [ FGrist _package_files $(packagename) $(path) ] ;
for file in $(packagefiles) {
if $(3[0]) = "boot" {
local packagefile = $(file:G=$(packagefilegrist)) ;
MakeLocate $(packagefile) : $(packagefiledir) ;
Copy $(packagefile) : $(file) ;
Clean cleanPackages : $(packagefile) ;
PackageInstallZip $(packagefileinstallzip) : $(packagefile) ;
} else {
local packagefile = $(file:G=_packages!$(packagename)) ;
MakeLocate $(packagefile) : $(packagedir) ;
Copy $(packagefile) : [ FGristFiles $(file) ] ;
Clean cleanPackages : $(packagefile) ;
Depends $(packagezip) : $(packagefile) ;
}
}
# general setup for this packages -- only on first invocation
if ! $(_setup_$(packagename)) {
_setup_$(packagename) = true ;
NotFile $(packagename) ;
Depends packages : $(packagename) ;
MakeLocate $(packagezip) : $(OBOS_PACKAGE_DIR) ;
MakeLocate $(packageinstallscript) : $(packagedir) ;
MakeLocate $(packageinstallzip) : $(packagedir) ;
MakeLocate $(packagefileinstallzip) : $(packageobjectdir) ;
PackageInstallScript $(packageinstallscript) : $(packagedir) ;
LinkInstallZip $(packageinstallzip) : $(packagefileinstallzip) ;
Depends $(packagename) : $(packagezip) ;
PackageZip $(packagezip) : $(packagedir)
: $(packageinstallscript) $(packageinstallzip) ;
}
}
rule PackageZip
{
local dir = $(2:G=dir) ;
Depends $(1) : $(dir) $(3) ;
Clean cleanPackages : $(1) ;
PackageZip1 $(1) : $(dir) ;
}
actions together PackageZip1 {
cd "$(OBOS_PACKAGE_DIR)" ;
zip -rq "$(1:BS)" "$(2:BS)" ;
}
rule PackageInstallScript
{
MakeLocate $(1) : $(2) ;
Clean cleanPackages : $(1) ;
PackageInstallScript1 $(1) : $(2:G=dir) ;
}
actions together PackageInstallScript1
{
echo '#!/bin/sh
base=`dirname "$0"`
cd "$base"
if [ -n "$TTY" ]
then
unzip -d / install.zip
else
response=`alert "Would you like to automatically overwrite existing files, or receive a prompt?" "Overwrite" "Prompt"`
if [ $response == "Overwrite" ]
then
unzip -od / install.zip
alert "Finished installing" "Thanks"
else
if [ -e /boot/beos/apps/Terminal ]
then
terminal=/boot/beos/apps/Terminal
else
terminal=`query Terminal | head -1`
fi
$terminal -t "installer" /bin/sh "$0"
fi
fi' > "$(1)" ;
chmod 755 "$(1)" ;
}
rule PackageInstallZip
{
Depends $(1) : $(2) ;
Clean cleanPackages : $(1) ;
}
actions together PackageInstallZip
{
cd "$(1:P)" ;
zip -rqy "$(1:BS)" boot ;
}
rule LinkInstallZip
{
Depends $(1) : $(2) ;
Clean cleanPackages : $(1) ;
}
actions together LinkInstallZip
{
ln -sf "`pwd`/$(2)" "$(1)" ;
}
rule SubIncludeGPL
{
# SubInclude rule that can be used to conditionally include GPL licensed add-ons
if $(INCLUDE_GPL_ADDONS) = 1 {
SubInclude $(1) ;
}
}