## Haiku Generic Jamfile Engine v1.0.2## Does all the hard work for the Generic Jamfile## which simply defines the project parameters.## Most of the real work is done in the Jambase## embedded into the jam executable.#### Inspired by the Be Makefile Engine#### Supports Generic Jamfile v1.0.1#### Copyright (c) 2002-2010 Ryan Leavengood## Copyright (c) 2011 Peter Polรกฤik## Released under the Terms of the MIT License, see## http://www.opensource.org/licenses/mit-license.html##-------------------------------------------------------------------## Define some utility rules##-------------------------------------------------------------------# AddResources <Application Name> : <Resource Files> ;# Adds the given resources to the given application.rule AddResources{Depends $(<) : $(>) ;}actions AddResources{$(XRES) -o "$(<)" $(>)}# MimeSet <Application Name> ;# Sets the mime type of the given application to be an application.actions MimeSet{$(MIMESET) -f "$(<)"}# ProcessLibs <List of Library Names> ;# Prepends -l to any library names that aren't _APP_ or _KERNEL_ or# that don't have .a or .so file extensions. The result will be given# to the linker so that it links to the right libraries.rule ProcessLibs{local result ;for i in $(1){if ( ( $(i) in _APP_ _KERNEL_ ) || ( $(i:S) in .so .a ) ){result += $(i) ;}else{result += -l$(i) ;}}return $(result) ;}# MkObjectDirs <List of Source Files> ;# Makes the necessary sub-directories in the object target directory based# on the sub-directories used for the source files.rule MkObjectDirs{local dir ;for i in $(1){dir = [ FDirName $(LOCATE_TARGET) $(i:D) ] ;Depends $(i:S=$(SUFOBJ)) : $(dir) ;MkDir $(dir) ;}}# CollectCatKeys <Pseudotarget Name> : <Source Files> ;# Collects catalog keys for localization from sources into per-locale filesrule CollectCatKeys{Depends $(<) : $(>) ;Depends $(<) : $(LOCATE_TARGET) ;#Depends $(<) : $(SRCS) ;Depends $(CATKEYS_DIR)/en.catkeys : $(<) ;}actions CollectCatKeys{cat $(SRCS) | gcc -E -x c++ $(HDRS) $(CCFLAGS) \-DB_COLLECTING_CATKEYS - > $(LOCATE_TARGET)/$(NAME).premkdir -p "$(CATKEYS_DIR)"collectcatkeys -s $(APP_MIME_SIG) $(LOCATE_TARGET)/$(NAME).pre \-o $(CATKEYS_DIR)/en.catkeys}# Catalogs <Pseudotarget Name> : <CollectCatKeys Target> ;# Compiles .catkeys files into .catalog files, one per localerule Catalogs{Depends $(<) : $(>) ;Depends $(<) : $(SRCS) ;for lng in $(LOCALES){Depends $(<) : $(CATKEYS_DIR)/$(lng:S=.catkeys) ;Depends $(CATKEYS_DIR)/$(lng:S=.catkeys) : $(>) ;#Clean clean : $(CATKEYS_DIR)/$(lng:S=.catkeys) ;Clean clean :$(LOCATE_TARGET)/$(APP_MIME_SIG)/$(lng:S=.catalog) ;}Clean clean : $(LOCATE_TARGET)/$(NAME).pre ;}actions Catalogs{mkdir -p $(LOCATE_TARGET)/$(APP_MIME_SIG)TMP=`echo "$(LOCALES)" | tr ';' ' '`for lang in $TMP ; doif [ ! -f $(CATKEYS_DIR)/$lang.catkeys ]; thencp $(CATKEYS_DIR)/en.catkeys \$(CATKEYS_DIR)/$lang.catkeys; filinkcatkeys \-o $(LOCATE_TARGET)/$(APP_MIME_SIG)/$lang.catalog \-s $(APP_MIME_SIG) \-l `basename $(LOCATE_TARGET)/$(APP_MIME_SIG)/$lang.catalog` \$(CATKEYS_DIR)/$lang.catkeysdone}# CatalogsInstall <Pseudotarget Name> : <Catalog Files> ;# Copies .catalog files into system locale directoryrule CatalogsInstall{Depends $(<) : $(>) ;Depends $(>) : catalogs ;}actions CatalogsInstall{mkdir -p "/boot/home/config/data/locale/catalogs/$(APP_MIME_SIG)" ;cp $(LOCATE_TARGET)/$(APP_MIME_SIG)/*.catalog \/boot/home/config/data/locale/catalogs/$(APP_MIME_SIG)}# BindCatalogs <Pseudotarget Name> : <Catalog Files> ;# Binds .catalog files into program executablerule BindCatalogs{Depends $(<) : $(>) ;Depends $(<) : $(NAME) ;Depends $(<) : $(LOCATE_TARGET)/$(NAME) ;Depends $(LOCATE_TARGET)/$(NAME) : $(NAME) ;Clean clean : $(<) ;}actions BindCatalogs{TMP=`echo $(LOCALES) | tr ';' ' '`for lc in $TMP; dolinkcatkeys -o $(LOCATE_TARGET)/$(NAME) \-s $(APP_MIME_SIG) -tr \-l $lc $(CATKEYS_DIR)/$lc.catkeysdone}# RmApp <Pseudotarget Name> : <Application Name> ;# Removes the given application file when the given pseudotarget# is specified.rule RmApp{Depends $(<) : $(>) ;}actions RmApp{rm -rf "$(>)"}# RunApp <Pseudotarget Name> : <Application Name> ;# Runs the given application in the background when the given pseudotarget# is specified.rule RunApp{Depends $(<) : $(>) ;}actions RunApp{"$(>)" &}# InstallDriver1 <Pseudotarget Name> : <Driver File> ;# Installs the given driver in the correct location when the given pseudotarget# is specified.rule InstallDriver1{Depends $(<) : $(>) ;USER_BIN_PATH = /boot/home/config/add-ons/kernel/drivers/bin ;USER_DEV_PATH = /boot/home/config/add-ons/kernel/drivers/dev ;}actions InstallDriver1{copyattr --data "$(>)" "$(USER_BIN_PATH)/$(>:B)"mkdir -p $(USER_DEV_PATH)/$(DRIVER_PATH)ln -sf "$(USER_BIN_PATH)/$(>:B)" "$(USER_DEV_PATH)/$(DRIVER_PATH)/$(>:B)"}# InstallDriver <Pseudotarget Name> : <Driver File> ;# Installs the given driver in the correct location when the given pseudotarget# is specified, after making sure that this is actually a driver.rule InstallDriver{if ( $(TYPE) = DRIVER ){InstallDriver1 $(<) : $(>) ;}}# Link <Application Name> : <List of Object Files> ;# Replaces the actions for the default Jam Link rule with one that handles spaces# in application names.actions Link bind NEEDLIBS{$(LINK) $(LINKFLAGS) -o "$(<)" $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)}# BeMain <Application Name> : <List of Source Files> ;# This is the main rule that builds the project.rule BeMain{MkObjectDirs $(>) ;if ( $(TYPE) = STATIC ){Library $(<) : $(>) ;}else{Main $(<) : $(>) ;}if ( $(RSRCS) ){AddResources $(<) : $(RSRCS) ;}if ( $(LOCALES) ){CollectCatKeys ;}MimeSet $(<) ;}##-------------------------------------------------------------------## Now all the needed variables are defined##-------------------------------------------------------------------# Set the directory where object files and binaries will be created.# The pre-defined Jam variable OSPLAT will indicate what platform we# are on (X86 vs PPC, etc.)LOCATE_TARGET = obj.$(OSPLAT) ;# Set some defaultsif ( ! $(NAME) ){ECHO "No NAME defined!" ;NAME = NameThisApp ;}if ( ! $(TYPE) ){ECHO "No TYPE defined...defaulting to APP" ;TYPE = APP ;}if ( ! $(SRCS) ){ECHO "NO SRCS defined...defaulting to *.cpp in current directory" ;SRCS = [ GLOB . : *.cpp ] ;}if ( ! $(DRIVER_PATH) ){DRIVER_PATH = misc ;}# Now handle platform-specific settingsif ( $(OSPLAT) = X86 ){if ( $(TYPE) = DRIVER ){CCFLAGS += -D_KERNEL_MODE=1 -no-fpic ;C++FLAGS += -D_KERNEL_MODE=1 -no-fpic ;}switch $(OPTIMIZE){case FULL : OPTIMIZER = -O3 ;case SOME : OPTIMIZER = -O1 ;case NONE : OPTIMIZER = -O0 ;# Default to FULLcase * : OPTIMIZER = -O3 ;}DEBUG = ;if ( $(DEBUGGER) = TRUE ){DEBUG += -g ;OPTIMIZER = -O0 ;}CCFLAGS += $(OPTIMIZER) $(DEBUG) ;C++FLAGS += $(OPTIMIZER) $(DEBUG) ;if ( $(WARNINGS) = ALL ){CCFLAGS += -Wall -Wno-multichar -Wno-ctor-dtor-privacy ;C++FLAGS += -Wall -Wno-multichar -Wno-ctor-dtor-privacy ;}else if ( $(WARNINGS) = NONE ){CCFLAGS += -w ;C++FLAGS += -w ;}LINKFLAGS += $(DEBUG) ;# Set linker flagsswitch $(TYPE){case APP : LINKFLAGS += -Xlinker -soname=_APP_ ;case SHARED : LINKFLAGS += -shared -Xlinker -soname=$(NAME) ;case DRIVER : LINKFLAGS += -nostdlib /boot/develop/lib/x86/_KERNEL_ ;}}else if ( $(OSPLAT) = PPC ){switch $(OPTIMIZE){case FULL : OPTIMIZER = -O7 ;case SOME : OPTIMIZER = -O3 ;case NONE : OPTIMIZER = -O0 ;# Default to FULLcase * : OPTIMIZER = -O7 ;}DEBUG = ;if ( $(DEBUGGER) = TRUE ){DEBUG += -g ;}CCFLAGS += $(OPTIMIZER) $(DEBUG) ;C++FLAGS += $(OPTIMIZER) $(DEBUG) ;if ( $(WARNINGS) = ALL ){CCFLAGS += -w on -requireprotos ;C++FLAGS += -w on -requireprotos ;}else if ( $(WARNINGS) = NONE ){CCFLAGS += -w off ;C++FLAGS += -w off ;}# Clear the standard environment variable# Now there are no standard libraries to link againstBELIBFILES = ;# Set linker flagsif ( $(TYPE) = SHARED ){LINKFLAGS += -xms ;}if ( $(TYPE) = DRIVER ){LINKFLAGS += -nodefaults -export all -G/boot/develop/lib/ppc/glue-noinit.a/boot/develop/lib/ppc/_KERNEL_ ;}else{LINKFLAGS += -export pragma -init _init_routine_-term _term_routine_ -lroot/boot/develop/lib/ppc/glue-noinit.a/boot/develop/lib/ppc/init_term_dyn.o/boot/develop/lib/ppc/start_dyn.o ;}if ( $(SYMBOLS) = TRUE ){LINKFLAGS += -map $(NAME).xMAP ;}if ( $(DEBUGGER) = TRUE ){LINKFLAGS += -g -osym $(NAME).SYM ;}}else{EXIT "Your platform is unsupported" ;}# Handle the other settingsLINKLIBS += [ ProcessLibs $(LIBS) ] ;for i in $(LIBPATHS){LINKFLAGS += -L$(i) ;}HDRS += $(SYSTEM_INCLUDE_PATHS) ;HDRS += $(LOCAL_INCLUDE_PATHS) ;CCFLAGS += $(COMPILER_FLAGS) ;C++FLAGS += $(COMPILER_FLAGS) ;LINKFLAGS += $(LINKER_FLAGS) ;# Localization specific variablesif ( ! $(APP_MIME_SIG) ){ECHO "No mime signature defined! Defaulting to x.vnd-Haiku-$(NAME)" ;APP_MIME_SIG = x.vnd-Haiku-$(NAME) ;}CATKEYS_DIR = locales ;if ( $(APP_MIME_SIG) ){CATALOGS_DIR = $(LOCATE_TARGET)/$(APP_MIME_SIG) ;CATALOGS = $(LOCALES:D=$(CATALOGS_DIR):S=.catalog) ;}# Define some toolsXRES = xres ;MIMESET = mimeset ;# Defining this variable keeps objects from being deleted by the Library# rule. By default the objects are deleted after being archived into# the library. I prefer they not be.KEEPOBJS = true ;# Set up the driverinstall target...this makes it easy to install drivers# for testingAlways driverinstall ;NotFile driverinstall ;InstallDriver driverinstall : $(NAME) ;# Set up the rmapp target...this removes only the applicationAlways rmapp ;NotFile rmapp ;RmApp rmapp : $(NAME) ;# Set up the test target...this runs the application in the background#Always test ;NotFile test ;RunApp test : $(NAME) ;Always catkeys ;NotFile catkeys ;CollectCatKeys catkeys : $(SRCS) ;#Always catalogs ;NotFile catalogs ;Catalogs catalogs : catkeys ;#Always catalogsinstall ;NotFile catalogsinstall ;CatalogsInstall catalogsinstall : $(CATALOGS_DIR)/$(LOCALES:S=.catalog) ;#Always bindcatalogs ;NotFile bindcatalogs ;BindCatalogs bindcatalogs : $(CATALOGS_DIR)/$(LOCALES:S=.catalog) ;##-------------------------------------------------------------------## OK, let's build##-------------------------------------------------------------------BeMain $(NAME) : $(SRCS) ;