## Haiku Generic Jamfile Engine v1.0.3 ## 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.3 ## ## 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 : ; # Adds the given resources to the given application. rule AddResources { Depends $(<) : $(>) ; } actions AddResources { $(XRES) -o "$(<)" "$(>)" } # Rc : ; # Compile an rdef file into a binary resources file rule Rc { Depends $(<) : $(>) ; LOCATE on $(<) = $(LOCATE_TARGET) ; } actions Rc { rc -o "$(<)" $(>) } # MimeSet ; # Sets the mime type of the given application to be an application. actions MimeSet { $(MIMESET) -f "$(<)" } # ProcessLibs ; # 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 ; # 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 : ; # Collects catalog keys for localization from sources into per-locale files rule 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).pre mkdir -p "$(CATKEYS_DIR)" collectcatkeys -s $(APP_MIME_SIG) $(LOCATE_TARGET)/$(NAME).pre \ -o $(CATKEYS_DIR)/en.catkeys } # Catalogs : ; # Compiles .catkeys files into .catalog files, one per locale rule 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 ; do if [ ! -f $(CATKEYS_DIR)/$lang.catkeys ]; then cp $(CATKEYS_DIR)/en.catkeys \ $(CATKEYS_DIR)/$lang.catkeys; fi linkcatkeys \ -o $(LOCATE_TARGET)/$(APP_MIME_SIG)/$lang.catalog \ -s $(APP_MIME_SIG) \ -l `basename $(LOCATE_TARGET)/$(APP_MIME_SIG)/$lang.catalog` \ $(CATKEYS_DIR)/$lang.catkeys done } # CatalogsInstall : ; # Copies .catalog files into system locale directory rule 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 : ; # Binds .catalog files into program executable rule 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; do linkcatkeys -o $(LOCATE_TARGET)/$(NAME) \ -s $(APP_MIME_SIG) -tr \ -l $lc $(CATKEYS_DIR)/$lc.catkeys done } # RmApp : ; # Removes the given application file when the given pseudotarget # is specified. rule RmApp { Depends $(<) : $(>) ; } actions RmApp { rm -rf "$(>)" } # RunApp : ; # Runs the given application in the background when the given pseudotarget # is specified. rule RunApp { Depends $(<) : $(>) ; } actions RunApp { "$(>)" & } # InstallDriver1 : ; # 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 : ; # 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 : ; # 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 : ; # This is the main rule that builds the project. rule BeMain { MkObjectDirs $(>) ; if ( $(TYPE) = STATIC ) { Library $(<) : $(>) ; } else { Main $(<) : $(>) ; } if ( $(RDEFS) ) { RSRCS += $(NAME).rsrc ; Rc $(NAME).rsrc : $(RDEFS) ; } 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 defaults if ( ! $(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 settings if ( $(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 FULL case * : 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 flags switch $(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 FULL case * : 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 against BELIBFILES = ; # Set linker flags if ( $(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 settings LINKLIBS += [ 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 variables if ( ! $(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 tools XRES = 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 testing Always driverinstall ; NotFile driverinstall ; InstallDriver driverinstall : $(NAME) ; # Set up the rmapp target...this removes only the application Always 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) ;