#-------------------------------------------------------------------------------# 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.local architecture = [ on $(1) return $(TARGET_PACKAGING_ARCH) ] ;if [ on $(1) return $(PLATFORM) ] = host {LINK on $(1) = $(HOST_LINK) ;LINKFLAGS on $(1) = $(HOST_LINKFLAGS) [ on $(1) return $(LINKFLAGS) ] ;} else {LINK on $(1) = $(TARGET_LINK_$(architecture)) ;LINKFLAGS on $(1) = $(TARGET_LINKFLAGS_$(architecture))[ on $(1) return $(LINKFLAGS) ] ;}HAIKU_TARGET_IS_EXECUTABLE on $(1) = 1 ;NEEDLIBS on $(1) = [ on $(1) return $(NEEDLIBS) ] ;LINKLIBS on $(1) = [ on $(1) return $(LINKLIBS) ] ;MODE on $(<) = $(EXEMODE) ;on $(1) XRes $(1) : $(RESFILES) ;if ! [ on $(1) return $(DONT_USE_BEOS_RULES) ] {SetType $(1) ;MimeSet $(1) : sharedObject ;SetVersion $(1) ;# For applications for the target also generate the MIME DB entries.if [ on $(1) return $(PLATFORM) ] != host&& [ on $(1) return $(RESFILES) ] {CreateAppMimeDBEntries $(1) ;}# If the generic attribute emulation is enabled, make sure the tool to# remove the attributes is built first.if $(HOST_RM_ATTRS_TARGET) {Depends $(1) : $(HOST_RM_ATTRS_TARGET) ;}}Chmod $(<) ;}# When using "real" attributes (i.e. BeOS attributes or xattr/extattr) on the# host platform, unlinking the main target by gcc will also automatically get# rid of the attributes. When using the generic attribute emulation, which# uses separate files, we need to remove the target explicitely first, so that# the attributes won't be "leaked".if $(HAIKU_HOST_USE_XATTR) = 1 {actions Link bind NEEDLIBS LINK_BEGIN_GLUE LINK_END_GLUE VERSION_SCRIPT{$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(LINK_BEGIN_GLUE)" "$(2)" \"$(NEEDLIBS)" $(LINKLIBS) "$(LINK_END_GLUE)" \-Wl,--version-script,$(VERSION_SCRIPT)}} else {actions Link bind NEEDLIBS LINK_BEGIN_GLUE LINK_END_GLUE VERSION_SCRIPT{$(RM) "$(1)"$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(LINK_BEGIN_GLUE)" "$(2)" \"$(NEEDLIBS)" $(LINKLIBS) "$(LINK_END_GLUE)" \-Wl,--version-script,$(VERSION_SCRIPT)}}rule Object{# find out which headers and defines to uselocal headers ;local sysHeaders ;local defines ;on $(1) { # use on $(1) variable valuesif ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {return ;}# Save HDRS for -I$(HDRS) on compile.# We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers# in the .c file's directory, but generated .c files (from# yacc, lex, etc) are located in $(LOCATE_TARGET), possibly# different from $(SEARCH_SOURCE).headers = $(HAIKU_CONFIG_HEADERS) $(SEARCH_SOURCE) $(SUBDIRHDRS)$(HDRS) ;sysHeaders = $(SUBDIRSYSHDRS) $(SYSHDRS) ;defines = $(DEFINES) ;if $(PLATFORM) = host {sysHeaders += $(HOST_HDRS) ;defines += $(HOST_DEFINES) ;if $(USES_BE_API) {sysHeaders += $(HOST_BE_API_HEADERS) ;}} else {local language ;if $(>:S) = .cpp || [ on $(2) return $(GENERATE_C++) ] {language = C++ ;}sysHeaders += [ FStandardHeaders $(TARGET_PACKAGING_ARCH) : $(language) ]$(TARGET_HDRS_$(TARGET_PACKAGING_ARCH)) ;defines += $(TARGET_DEFINES_$(TARGET_PACKAGING_ARCH))$(TARGET_DEFINES) ;}}# locate object and search for sourceLocalClean clean : $(<) ;MakeLocateDebug $(<) ;SEARCH on $(>) = $(SEARCH_SOURCE) ;HDRS on $(<) = $(headers) ;SYSHDRS on $(<) = $(sysHeaders) ;# handle #includes for source: Jam scans for headers with# the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)# with the scanned file as the target and the found headers# as the sources. HDRSEARCH is the value of SEARCH used for# the found header files. Finally, if jam must deal with# header files of the same name in different directories,# they can be distinguished with HDRGRIST.# $(SEARCH_SOURCE:E) is where cc first looks for #include# "foo.h" files. If the source file is in a distant directory,# look there. Else, look in "" (the current directory).HDRRULE on $(>) = HdrRule ;HDRSCAN on $(>) = $(HDRPATTERN) ;HDRSEARCH on $(>) = $(headers) $(sysHeaders) $(STDHDRS) ;HDRGRIST on $(>) = $(HDRGRIST) ;# propagate target specific-definesDEFINES on $(1) = $(defines) ;# if source is not .c, generate .c with specific ruleswitch $(>:S){case .asm : As $(<) : $(>) ;case .nasm : AssembleNasm $(<) : $(>) ;case .c : Cc $(<) : $(>) ;case .C : C++ $(<) : $(>) ;case .cc : C++ $(<) : $(>) ;case .cpp : C++ $(<) : $(>) ;case .f : Fortran $(<) : $(>) ;case .l : if [ on $(2) return $(GENERATE_C++) ] {InheritPlatform $(<:S=.cpp) : $(1) ;C++ $(<) : $(<:S=.cpp) ;Lex $(<:S=.cpp) : $(>) ;} else {InheritPlatform $(<:S=.c) : $(1) ;Cc $(<) : $(<:S=.c) ;Lex $(<:S=.c) : $(>) ;}case *.o : return ;case .s : As $(<) : $(>) ;case .S : As $(<) : $(>) ;case .y : if [ on $(2) return $(GENERATE_C++) ] {InheritPlatform $(1:S=.cpp) $(1:S=.hpp) : $(1) ;C++ $(1) : $(1:S=.cpp) ;Yacc $(1:S=.cpp) $(1:S=.hpp) : $(2) ;} else {InheritPlatform $(1:S=.c) $(1:S=.h) : $(1) ;Cc $(1) : $(1:S=.c) ;Yacc $(1:S=.c) $(1:S=.h) : $(2) ;}case * : UserObject $(<) : $(>) ;}}rule As{Depends $(<) : $(>) [ on $(1) return $(PLATFORM) ] ;on $(1) {local flags ;local includesSeparator ;local localIncludesOption ;local systemIncludesOption ;if $(PLATFORM) = host {flags = $(HOST_ASFLAGS) $(ASFLAGS) ;CC on $(1) = $(HOST_CC) ;includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;} else {flags = $(TARGET_ASFLAGS_$(TARGET_PACKAGING_ARCH)) $(ASFLAGS) ;CC on $(1) = $(TARGET_CC_$(TARGET_PACKAGING_ARCH)) ;includesSeparator= $(TARGET_INCLUDES_SEPARATOR_$(TARGET_PACKAGING_ARCH)) ;localIncludesOption= $(TARGET_LOCAL_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;systemIncludesOption= $(TARGET_SYSTEM_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;}ASFLAGS on $(<) += $(flags) $(SUBDIRASFLAGS) ;ASHDRS on $(<) = [ on $(<) FIncludes $(HDRS) : $(localIncludesOption) ]$(includesSeparator)[ on $(<) FSysIncludes $(SYSHDRS) : $(systemIncludesOption) ] ;ASDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;}}actions As{$(CC) -c "$(2)" -O2 $(ASFLAGS) -D_ASSEMBLER $(ASDEFS) $(ASHDRS) -o "$(1)"}rule Lex{Depends $(1) : $(2) [ on $(1) return $(PLATFORM) ] ;MakeLocateArch $(1) ;LocalClean clean : $(1) ;}actions Lex{$(LEX) $(LEXFLAGS) -o$(1) $(2)}rule Yacc{local source = $(1[1]) ;local header = $(1[2]) ;local yaccSource = $(2) ;MakeLocateArch $(source) $(header) ;Depends $(source) $(header): $(yaccSource) [ on $(source) return $(PLATFORM) ] ;Yacc1 $(source) $(header) : $(yaccSource) ;LocalClean clean : $(source) $(header) ;# make sure someone includes $(header) else it will be# a deadly independent targetIncludes $(source) : $(header) ;}actions Yacc1{bison $(YACCFLAGS) -o $(1[1]) $(2)[ -f $(1[1]).h ] && mv $(1[1]).h $(1[2]) || true}rule Cc{Depends $(<) : $(>) [ on $(1) return $(PLATFORM) ] ;on $(1) {local flags ;local includesSeparator ;local localIncludesOption ;local systemIncludesOption ;# optimization flagsif $(DEBUG) = 0 {flags += $(OPTIM) ;} else {flags += -O0 ;}if $(PLATFORM) = host {# warning flagsif $(WARNINGS) != 0 {flags += $(HOST_WARNING_CCFLAGS) ;if $(WARNINGS) = treatAsErrors {flags += -Werror $(HOST_WERROR_FLAGS) ;}}# debug and other flagsflags += $(HOST_CCFLAGS) $(HOST_DEBUG_$(DEBUG)_CCFLAGS)$(SUBDIRCCFLAGS) $(CCFLAGS) ;if $(USES_BE_API) {flags += $(HOST_BE_API_CCFLAGS) ;}CC on $(1) = $(HOST_CC) ;includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;} else {# warning flagsif $(WARNINGS) != 0 {flags += $(TARGET_WARNING_CCFLAGS_$(TARGET_PACKAGING_ARCH)) ;if $(WARNINGS) = treatAsErrors {flags += -Werror$(TARGET_WERROR_FLAGS_$(TARGET_PACKAGING_ARCH)) ;}}# debug and other flagsflags += $(TARGET_CCFLAGS_$(TARGET_PACKAGING_ARCH))$(TARGET_DEBUG_$(DEBUG)_CCFLAGS_$(TARGET_PACKAGING_ARCH))$(SUBDIRCCFLAGS) $(CCFLAGS) ;CC on $(1) = $(TARGET_CC_$(TARGET_PACKAGING_ARCH)) ;includesSeparator= $(TARGET_INCLUDES_SEPARATOR_$(TARGET_PACKAGING_ARCH)) ;localIncludesOption= $(TARGET_LOCAL_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;systemIncludesOption= $(TARGET_SYSTEM_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;}CCFLAGS on $(<) = $(flags) ;CCHDRS on $(<) = [ FIncludes $(HDRS) : $(localIncludesOption) ]$(includesSeparator)[ FSysIncludes $(SYSHDRS) : $(systemIncludesOption) ] ;CCDEFS on $(<) = [ FDefines $(DEFINES) ] ;}}actions Cc{$(CC) $(CCFLAGS) -c "$(2)" $(CCDEFS) $(CCHDRS) -o "$(1)"}rule C++{Depends $(<) : $(>) [ on $(1) return $(PLATFORM) ] ;on $(1) {local flags ;local includesSeparator ;local localIncludesOption ;local systemIncludesOption ;# optimization flagsif $(DEBUG) = 0 {flags += $(OPTIM) ;} else {flags += -O0 ;}if $(PLATFORM) = host {# warning flagsif $(WARNINGS) != 0 {flags += $(HOST_WARNING_C++FLAGS) ;if $(WARNINGS) = treatAsErrors {flags += -Werror $(HOST_WERROR_FLAGS) ;}}# debug and other flagsflags += $(HOST_C++FLAGS) $(HOST_DEBUG_$(DEBUG)_C++FLAGS)$(SUBDIRC++FLAGS) $(C++FLAGS) ;if $(USES_BE_API) {flags += $(HOST_BE_API_C++FLAGS) ;}C++ on $(1) = $(HOST_C++) ;includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;} else {# warning flagsif $(WARNINGS) != 0 {flags += $(TARGET_WARNING_C++FLAGS_$(TARGET_PACKAGING_ARCH)) ;if $(WARNINGS) = treatAsErrors {flags += -Werror$(TARGET_WERROR_FLAGS_$(TARGET_PACKAGING_ARCH)) ;}}# debug and other flagsflags += $(TARGET_C++FLAGS_$(TARGET_PACKAGING_ARCH))$(TARGET_DEBUG_$(DEBUG)_C++FLAGS_$(TARGET_PACKAGING_ARCH))$(SUBDIRC++FLAGS) $(C++FLAGS) ;C++ on $(1) = $(TARGET_C++_$(TARGET_PACKAGING_ARCH)) ;includesSeparator= $(TARGET_INCLUDES_SEPARATOR_$(TARGET_PACKAGING_ARCH)) ;localIncludesOption= $(TARGET_LOCAL_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;systemIncludesOption= $(TARGET_SYSTEM_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;}C++FLAGS on $(<) = $(flags) ;CCHDRS on $(<) = [ FIncludes $(HDRS) : $(localIncludesOption) ]$(includesSeparator)[ FSysIncludes $(SYSHDRS) : $(systemIncludesOption) ] ;CCDEFS on $(<) = [ FDefines $(DEFINES) ] ;}}actions C++{$(C++) -c "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)"}# Force recreation of the archive to avoid build errors caused by# stale dependencies after renaming or deleting object files.actions together Archive{$(RM) $(<)$(AR) $(<) $(>)}rule Library{local lib = $(1) ;local sources = [ FGristFiles $(2) ] ;local objects = $(sources:S=$(SUFOBJ)) ;InheritPlatform $(objects) : $(lib) ;LibraryFromObjects $(lib) : $(objects) ;Objects $(sources) ;}rule LibraryFromObjects{local _i _l _s ;# Add grist to file names# bonefish: No, don't. The Library rule does that anyway, and when we# have an object from another dir, we certainly don't want that._s = $(>) ;_l = $(<:S=$(SUFLIB)) ;on $(_l) {# set the tools according to the platformif $(PLATFORM) = host {AR on $(_l) = $(HOST_AR) $(HOST_ARFLAGS) ;RANLIB on $(_l) = $(HOST_RANLIB) ;} else {AR on $(_l) = $(TARGET_AR_$(TARGET_PACKAGING_ARCH))$(TARGET_ARFLAGS_$(TARGET_PACKAGING_ARCH)) ;RANLIB on $(_l) = $(TARGET_RANLIB_$(TARGET_PACKAGING_ARCH)) ;}# library depends on its member objectsif $(KEEPOBJS) {LocalDepends obj : $(_s) ;}LocalDepends lib : $(_l) ;# Set LOCATE for the library and its contents. The bound# value shows up as $(NEEDLIBS) on the Link actions.# For compatibility, we only do this if the library doesn't# already have a path.if ! $(_l:D) {# locate the library only, if it hasn't been located yetlocal dir = $(LOCATE[1]) ;if ! $(dir) {MakeLocateDebug $(_l) ;dir = [ on $(_l) return $(LOCATE[1]) ] ;# Note: The "on ..." is necessary, since our environment# isn't changed by MakeLocateDebug.}MakeLocate $(_l)($(_s:BS)) : $(dir) ;}if $(NOARSCAN) {# If we can't scan the library to timestamp its contents,# we have to just make the library depend directly on the# on-disk object files.Depends $(_l) : $(_s) ;} else {# If we can scan the library, we make the library depend# on its members and each member depend on the on-disk# object file.Depends $(_l) : $(_l)($(_s:BS)) ;for _i in $(_s){Depends $(_l)($(_i:BS)) : $(_i) ;}}LocalClean clean : $(_l) ;Archive $(_l) : $(_s) ;if $(RANLIB) { Ranlib $(_l) ; }# If we can't scan the library, we have to leave the .o's around.if ! ( $(KEEPOBJS) || $(NOARSCAN) || $(NOARUPDATE) ) {RmTemps $(_l) : $(_s) ;}}}rule Main{local target = $(1) ;local sources = [ FGristFiles $(2) ] ;local objects = $(sources:S=$(SUFOBJ)) ;InheritPlatform $(objects) : $(target) ;MainFromObjects $(target) : $(objects) ;Objects $(sources) ;}rule MainFromObjects{local _s _t ;# Add grist to file names# Add suffix to exe_s = [ FGristFiles $(>) ] ;_t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;# so 'jam foo' works when it's really foo.exeif $(_t) != $(<){Depends $(<) : $(_t) ;NotFile $(<) ;}# make compiled sources a dependency of targetLocalDepends exe : $(_t) ;Depends $(_t) : $(_s) ;MakeLocateDebug $(_t) ;LocalClean clean : $(_t) ;Link $(_t) : $(_s) ;}# Override Jam 2.5rc3 MakeLocate and MkDir to deal more intelligently# with grist set on the supplied directory name. Also do nothing for already# located files.rule MakeLocate{local dir = $(2[1]) ;if $(dir) {if ! $(dir:G) {dir = $(dir:G=dir) ;}local target ;for target in $(1) {# don't relocate once locatedLOCATE on $(target) += $(dir:G=) ;if [ on $(target) return $(LOCATE) ] = $(dir:G=) {Depends $(target) : $(dir) ;MkDir $(dir) ;}}}}# Overridden to use "-p", as Jam does not properly normalize# paths passed to NoUpdate, and so tries to make some directories# twice: once for the relative path, and once for the absolute path.actions MkDir1{$(MKDIR) -p "$(<)"}rule MkDir{local dir = $(<) ;if ! $(dir:G) {dir = $(dir:G=dir) ;}# make this and all super directorieswhile true {# If dir exists, don't update it# Do this even for $(DOT).NoUpdate $(dir) ;# Bail out when reaching the CWD (".") or a directory we've already# made.if $(dir:G=) = $(DOT) || $($(dir:G=)-mkdir) {return ;}local s ;# Cheesy gate to prevent multiple invocations on same dir# MkDir1 has the actions# Arrange for jam dirs$(dir:G=)-mkdir = true ;MkDir1 $(dir) ;LocalDepends dirs : $(dir) ;# Recursively make parent directories.# $(dir:P) = $(dir)'s parent, & we recurse until roots = $(dir:P) ; # parent keeps gristif $(s:G=) && $(s) != $(dir) {Depends $(dir) : $(s) ;dir = $(s) ;} else if $(s) {NotFile $(s) ;break ;}}}rule ObjectCcFlags{# supports inheriting the global variable valuelocal file ;for file in [ FGristFiles $(1:S=$(SUFOBJ)) ] {CCFLAGS on $(file) = [ on $(file) return $(CCFLAGS) ] $(2) ;}}rule ObjectC++Flags{# supports inheriting the global variable valuelocal file ;for file in [ FGristFiles $(1:S=$(SUFOBJ)) ] {C++FLAGS on $(file) = [ on $(file) return $(C++FLAGS) ] $(2) ;}}rule ObjectDefines{# supports inheriting the global variable value and multiple filesif $(2) {local file ;for file in [ FGristFiles $(1:S=$(SUFOBJ)) ] {DEFINES on $(file) = [ on $(file) return $(DEFINES) ] $(2) ;CCDEFS on $(file) = [ on $(file) FDefines $(DEFINES) ] ;}}}rule ObjectHdrs{# ObjectHdrs <sources or objects> : <headers> : <gristed objects># Note: Parameter 3 <gristed objects> is an extension.local objects = [ FGristFiles $(1:S=$(SUFOBJ)) ] $(3) ;local headers = $(2) ;local file ;for file in $(objects) {on $(file) {local localHeaders = $(HDRS) $(headers) ;SYSHDRS on $(file) = $(localHeaders) ;# reformat ASHDRS and CCHDRSlocal fileHeaders ;if $(PLATFORM) = host {fileHeaders =[ FIncludes $(localHeaders) : $(HOST_LOCAL_INCLUDES_OPTION) ]$(HOST_INCLUDES_SEPARATOR)[ FSysIncludes $(SYSHDRS): $(HOST_SYSTEM_INCLUDES_OPTION) ] ;} else {local architecture = $(TARGET_PACKAGING_ARCH) ;fileHeaders =[ FIncludes $(localHeaders): $(TARGET_LOCAL_INCLUDES_OPTION_$(architecture)) ]$(TARGET_INCLUDES_SEPARATOR_$(architecture))[ FSysIncludes $(SYSHDRS): $(TARGET_SYSTEM_INCLUDES_OPTION_$(architecture)) ] ;}ASHDRS on $(file) = $(fileHeaders) ;CCHDRS on $(file) = $(fileHeaders) ;}}}# Overridden to avoid calling SubDir for a directory twice (in SubInclude# and from the Jamfile in the directory).rule SubInclude{# SubInclude TOP d1 ... ;## Include a subdirectory's Jamfile.if ! $($(<[1])){Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ;}# Set up the config variables for the subdirectory.local config = [ ConfigObject $(1) ] ;__configured = ;if ! [ on $(config) return $(__configured) ] {# No custom configuration defined for the subdir. We use the variable# values inherited by the closest ancestor.config = $(HAIKU_INHERITED_SUBDIR_CONFIG) ;}# store SUBDIR_TOKENSlocal oldSubDirTokens = $(SUBDIR_TOKENS) ;on $(config) {include [ FDirName $($(1[1])) $(1[2-) $(JAMFILE) ] ;}# restore SUBDIR_TOKENSSUBDIR_TOKENS = $(oldSubDirTokens) ;}