rule AddSharedObjectGlueCode { # AddSharedObjectGlueCode : ; # we link with -nostdlib and add the required libs manually, when building # for Haiku local platform ; on $(1) { platform = $(PLATFORM) ; if $(platform) = haiku { local stdLibs = libroot.so ; local beginGlue ; local endGlue ; if $(2) = true { beginGlue += $(HAIKU_EXECUTABLE_BEGIN_GLUE_CODE) ; endGlue += $(HAIKU_EXECUTABLE_END_GLUE_CODE) ; } else { beginGlue += $(HAIKU_LIBRARY_BEGIN_GLUE_CODE) ; endGlue += $(HAIKU_LIBRARY_END_GLUE_CODE) ; # special case for libroot: don't link it against itself if $(DONT_LINK_AGAINST_LIBROOT) { stdLibs = ; } } LINK_BEGIN_GLUE on $(1) = $(beginGlue) ; LINK_END_GLUE on $(1) = $(endGlue) ; NEEDLIBS on $(1) = [ on $(1) return $(NEEDLIBS) ] $(stdLibs) ; Depends $(1) : $(stdLibs) $(beginGlue) $(endGlue) ; LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ] -nostdlib -Xlinker --no-undefined ; } } # link against the compatibility libraries needed for the target if $(platform) != host && $(TARGET_HAIKU_COMPATIBILITY_LIBS) { LinkAgainst $(1) : $(TARGET_HAIKU_COMPATIBILITY_LIBS) ; } } rule Executable { # Executable : : : ; # if ! [ IsPlatformSupportedForTarget $(1) ] { return ; } AddResources $(1) : $(4) ; Main $(1) : $(2) ; LinkAgainst $(1) : $(3) ; LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ] -Xlinker -soname=_APP_ ; # we link with -nostdlib and add the required libs manually, when building # for Haiku AddSharedObjectGlueCode $(1) : true ; } rule Application { # Application : : : ; Executable $(1) : $(2) : $(3) : $(4) ; } rule BinCommand { # BinCommand : : : ; Executable $(1) : $(2) : $(3) : $(4) ; } rule StdBinCommands { # StdBinCommands : : ; local libs = $(2) ; local ress = $(3) ; local source ; for source in $(1) { local target = $(source:S=) ; BinCommand $(target) : $(source) : $(libs) : $(ress) ; } } rule Preference { # Preference : : : ; Executable $(1) : $(2) : $(3) : $(4) ; } rule Server { # Server : : : ; Executable $(1) : $(2) : $(3) : $(4) ; } rule Addon target : sources : libraries : isExecutable { # Addon : : : ; # : The add-on. # : Source files. # : Libraries to be linked against. # : true, if the target shall be executable as well. if ! [ IsPlatformSupportedForTarget $(target) ] { return ; } Main $(target) : $(sources) ; local linkFlags = -Xlinker -soname=\"$(target:G=)\" ; if $(isExecutable) != true { linkFlags = -nostart $(linkFlags) ; } LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ] $(linkFlags) ; LinkAgainst $(target) : $(libraries) ; AddSharedObjectGlueCode $(target) : $(isExecutable) ; } rule Translator target : sources : libraries : isExecutable { # Translator : : : ; Addon $(target) : $(sources) : $(libraries) : $(isExecutable) ; } rule ScreenSaver target : sources : libraries { # ScreenSaver : : ; Addon $(target) : $(sources) : $(libraries) : false ; } rule StaticLibrary { # StaticLibrary : : ; # Creates a static library from sources. # : The static library to be built. # : List of source files. # : List of additional object files. # local lib = $(1) ; local sources = [ FGristFiles $(2) ] ; local otherObjects = $(3) ; local objects = $(sources:S=$(SUFOBJ)) ; if ! [ IsPlatformSupportedForTarget $(1) ] { return ; } InheritPlatform $(objects) : $(lib) ; StaticLibraryFromObjects $(lib) : $(objects) $(otherObjects) ; Objects $(2) ; } rule StaticLibraryFromObjects { if ! [ IsPlatformSupportedForTarget $(1) ] { return ; } LibraryFromObjects $(1) : $(2) ; } rule AssembleNasm { Depends $(<) : $(>) ; } actions AssembleNasm { if test $(ASFLAGS) ; then $(HAIKU_YASM) -d $(ASFLAGS) -f elf32 -o $(1) $(2); else $(HAIKU_YASM) -f elf32 -o $(1) $(2); fi } rule Ld { # Ld : : : ; # local target = $(1) ; local objects = $(2) ; local linkerScript = $(3) ; local linkerFlags = $(4) ; if $(linkerScript) { linkerFlags += --script=$(linkerScript) ; } on $(target) { if $(PLATFORM) = host { LINK on $(target) = $(HOST_LD) ; LINKFLAGS on $(target) = $(HOST_LDFLAGS) $(LINKFLAGS) $(linkerFlags) ; } else { LINK on $(target) = $(TARGET_LD) ; LINKFLAGS on $(target) = $(TARGET_LDFLAGS) $(LINKFLAGS) $(linkerFlags) ; } NEEDLIBS on $(target) = $(NEEDLIBS) ; LINKLIBS on $(target) = $(LINKLIBS) ; } LocalClean clean : $(target) ; LocalDepends all : $(target) ; Depends $(target) : $(objects) ; MakeLocateDebug $(target) ; on $(1) XRes $(1) : $(RESFILES) ; if ! [ on $(1) return $(DONT_USE_BEOS_RULES) ] { SetType $(1) ; MimeSet $(1) ; SetVersion $(1) ; } } actions Ld { $(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" "$(NEEDLIBS)" $(LINKLIBS) } rule CreateAsmStructOffsetsHeader header : source { # CreateAsmStructOffsetsHeader header : source # # Grist will be added to both header and source. header = [ FGristFiles $(header) ] ; source = [ FGristFiles $(source) ] ; # find out which headers, defines, etc. to use local headers ; local sysHeaders ; local defines ; local flags ; local includesSeparator ; local localIncludesOption ; local systemIncludesOption ; on $(header) { # use on $(1) variable values if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) { return ; } # headers and defines 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 { sysHeaders += $(TARGET_HDRS) ; defines += $(TARGET_DEFINES) ; } # optimization flags if $(DEBUG) = 0 { flags += $(OPTIM) ; } else { flags += -O0 ; } if $(PLATFORM) = host { # warning flags if $(WARNINGS) != 0 { flags += $(HOST_WARNING_C++FLAGS) ; } # debug and other flags flags += $(HOST_C++FLAGS) $(HOST_DEBUG_$(DEBUG)_C++FLAGS) $(SUBDIRC++FLAGS) $(C++FLAGS) ; if $(USES_BE_API) { flags += $(HOST_BE_API_C++FLAGS) ; } C++ on $(header) = $(HOST_C++) ; includesSeparator = $(HOST_INCLUDES_SEPARATOR) ; localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ; systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ; } else { # warning flags if $(WARNINGS) != 0 { flags += $(TARGET_WARNING_C++FLAGS) ; } # debug and other flags flags += $(TARGET_C++FLAGS) $(TARGET_DEBUG_$(DEBUG)_C++FLAGS) $(SUBDIRC++FLAGS) $(C++FLAGS) ; C++ on $(header) = $(TARGET_C++) ; includesSeparator = $(TARGET_INCLUDES_SEPARATOR) ; localIncludesOption = $(TARGET_LOCAL_INCLUDES_OPTION) ; systemIncludesOption = $(TARGET_SYSTEM_INCLUDES_OPTION) ; } } # locate object, search for source, and set on target variables Depends $(header) : $(source) ; SEARCH on $(source) += $(SEARCH_SOURCE) ; MakeLocateArch $(header) ; LocalClean clean : $(header) ; HDRRULE on $(source) = HdrRule ; HDRSCAN on $(source) = $(HDRPATTERN) ; HDRSEARCH on $(source) = $(headers) $(sysHeaders) $(STDHDRS) ; HDRGRIST on $(source) = $(HDRGRIST) ; C++FLAGS on $(header) = $(flags) ; CCHDRS on $(header) = [ FIncludes $(headers) : $(localIncludesOption) ] $(includesSeparator) [ FSysIncludes $(sysHeaders) : $(systemIncludesOption) ] ; CCDEFS on $(header) = [ FDefines $(defines) ] ; CreateAsmStructOffsetsHeader1 $(header) : $(source) ; } actions CreateAsmStructOffsetsHeader1 { $(C++) -S "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o - \ | grep "#define" | sed -e 's/[\$\#]\([0-9]\)/\1/' > "$(1)" } rule MergeObjectFromObjects { # MergeObjectFromObjects : : ; # Merges object files to an object file. # : Name of the object file to create. No grist will be added. # : Object files to be merged. Grist will be added. # : Object files or static libraries to be merged. No grist # will be added. # local objects = [ FGristFiles $(2) ] ; on $(1) { if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) { return ; } if $(PLATFORM) = host { LINK on $(1) = $(HOST_LD) ; LINKFLAGS on $(target) = $(HOST_LDFLAGS) ; } else { LINK on $(1) = $(TARGET_LD) ; LINKFLAGS on $(target) = $(TARGET_LDFLAGS) ; } } MakeLocateDebug $(1) ; Depends $(1) : $(objects) ; Depends $(1) : $(3) ; LocalDepends obj : $(1) ; MergeObjectFromObjects1 $(1) : $(objects) $(3) ; } actions MergeObjectFromObjects1 { $(LINK) $(LINKFLAGS) -r $(2) -o $(1) ; } rule MergeObject { # MergeObject : : ; # Compiles source files and merges the object files to an object file. # : Name of the object file to create. No grist will be added. # : Sources to be compiled. Grist will be added. # : Object files or static libraries to be merged. No grist # will be added. # local target = $(1) ; local sources = [ FGristFiles $(2) ] ; local otherObjects = $(3) ; local objects = $(sources:S=$(SUFOBJ)) ; if ! [ IsPlatformSupportedForTarget $(1) ] { return ; } InheritPlatform $(objects) : $(target) ; Objects $(sources) ; MergeObjectFromObjects $(target) : $(objects) : $(otherObjects) ; } rule SharedLibraryFromObjects { # SharedLibraryFromObjects : : ; # local _lib = $(1) ; if ! [ IsPlatformSupportedForTarget $(1) ] { return ; } local soname = [ on $(_lib) return $(HAIKU_SONAME) ] ; soname ?= $(_lib:BS) ; MainFromObjects $(_lib) : $(2) ; LINKFLAGS on $(_lib) = [ on $(_lib) return $(LINKFLAGS) ] -nostart -Xlinker -soname=\"$(soname)\" ; LinkAgainst $(_lib) : $(3) ; AddSharedObjectGlueCode $(_lib) : false ; } rule SharedLibrary { # SharedLibrary : : : ; local lib = $(1) ; local sources = [ FGristFiles $(2) ] ; local objects = $(sources:S=$(SUFOBJ)) ; local libs = $(3) ; local abiVersion = $(4) ; # major ABI (soname) version for lib (if any) if ! [ IsPlatformSupportedForTarget $(1) ] { return ; } if $(abiVersion) { HAIKU_SONAME on $(lib) = $(lib:BS).$(abiVersion) ; HAIKU_LIB_ABI_VERSION on $(lib) = $(abiVersion) ; } InheritPlatform $(objects) : $(lib) ; Objects $(sources) ; SharedLibraryFromObjects $(lib) : $(objects) : $(libs) ; } rule LinkAgainst { # LinkAgainst : [ : ] ; # Valid elements for are e.g. "be" or "libtranslation.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 "" as # grist; it will be stripped by this rule. # specifies whether the to translate library names (e.g. "be" # to "libbe.so" in case of target platform "haiku"). Defaults to "true". # local target = $(1) ; local libs = $(2) ; local mapLibs = $(3:E=true) ; on $(target) { # map libraries, if desired and target platform is Haiku if $(PLATFORM) != host && $(mapLibs) = true && $(TARGET_LIBRARY_NAME_MAP) { local mappedLibs ; for i in $(libs) { local mapped = $($(TARGET_LIBRARY_NAME_MAP)_$(i)) ; mapped ?= $(i) ; mappedLibs += $(mapped) ; } libs = $(mappedLibs) ; } local linkLibs ; local needLibs ; for i in $(libs) { local isfile = ; if $(i:D) || $(i:G) { isfile = true ; if $(i:G) = { 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 += $(i) ; } else { linkLibs += $(i) ; } } NEEDLIBS on $(1) = $(NEEDLIBS) $(needLibs) ; LINKLIBS on $(1) = $(LINKLIBS) -l$(linkLibs) ; if $(needLibs) && ! $(NO_LIBRARY_DEPENDENCIES) { Depends $(1) : $(needLibs) ; } } } rule AddResources { # AddResources : ; # add grist to the resource files which don't have any yet local resfiles ; local file ; for file in $(2) { if ! $(file:G) { file = [ FGristFiles $(file) ] ; } resfiles += $(file) ; } SEARCH on $(resfiles) += $(SEARCH_SOURCE) ; for file in $(resfiles) { if $(file:S) = .rdef { local rdef = $(file) ; file = $(rdef:S=.rsrc) ; ResComp $(file) : $(rdef) ; } InheritPlatform $(file) : $(1) ; RESFILES on $(1) += $(file) ; } } rule SetVersionScript target : versionScript { # SetVersionScript : # # Sets the version script for . Grist will be added to # and SEARCH will be set on it. versionScript = [ FGristFiles $(versionScript) ] ; SEARCH on $(versionScript) += $(SEARCH_SOURCE) ; VERSION_SCRIPT on $(target) = $(versionScript) ; Depends $(target) : $(versionScript) ; } rule BuildPlatformObjects { # Usage BuildPlatformObjects ; # The sources. # local sources = [ FGristFiles $(1) ] ; local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ; PLATFORM on $(objects) = host ; SUPPORTED_PLATFORMS on $(objects) = host ; Objects $(sources) ; } actions CygwinExtensionFix { if test -f $(1).exe ; then rm -f $(1) mv $(1).exe $(1) fi } rule BuildPlatformMain { # Usage BuildPlatformMain : : ; # The executable/library. # The sources. # Libraries to link against. # local target = $(1) ; local sources = $(2) ; local libs = $(3) ; local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ; PLATFORM on $(target) = host ; SUPPORTED_PLATFORMS on $(target) = host ; DONT_USE_BEOS_RULES on $(target) = true ; local usesBeAPI = [ on $(target) return $(USES_BE_API) ] ; if $(usesBeAPI) { # propagate the flag to the objects USES_BE_API on $(objects) = $(usesBeAPI) ; # add the build libroot if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) { local libroot = [ on $(target) return $(HOST_LIBROOT) ] ; Depends $(target) : $(libroot) ; NEEDLIBS on $(target) += $(libroot) ; } } Main $(target) : $(sources) ; LinkAgainst $(target) : $(libs) ; if $(HOST_PLATFORM) = cygwin { # Cygwin gcc adds the ".exe" extension. We cannot force # jam to use SUFEXE as haiku target executables are not # supposed to have this extension, thus finding # dependencies will fail for these. # The hack is to remove the extension after a successful # build of the Target. CygwinExtensionFix $(target) ; } } rule BuildPlatformSharedLibrary { # Usage BuildPlatformSharedLibrary : : ; # The library. # The sources. # Libraries to link against. # local target = $(1) ; local sources = $(2) ; local libs = $(3) ; BuildPlatformMain $(target) : $(sources) : $(libs) ; if $(HOST_PLATFORM) = darwin { LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ] -dynamic -dynamiclib -Xlinker -flat_namespace ; } else if $(HOST_PLATFORM) = cygwin { LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ] -shared -Xlinker --allow-multiple-definition ; } else { LINKFLAGS on $(target) = [ on $(target) return $(LINKFLAGS) ] -shared -Xlinker -soname=\"$(target:G=)\" ; } local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ; CCFLAGS on $(objects) += $(HOST_PIC_CCFLAGS) ; C++FLAGS on $(objects) += $(HOST_PIC_C++FLAGS) ; } rule BuildPlatformMergeObject { # BuildPlatformMergeObject : : ; # Compiles source files and merges the object files to an object file. # : Name of the object file to create. No grist will be added. # : Sources to be compiled. Grist will be added. # : Object files or static libraries to be merged. No grist # will be added. # local target = $(1) ; local sources = $(2) ; local otherObjects = $(3) ; local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ; PLATFORM on $(target) = host ; SUPPORTED_PLATFORMS on $(target) = host ; local usesBeAPI = [ on $(target[1]) return $(USES_BE_API) ] ; if $(usesBeAPI) { # propagate the flag to the objects USES_BE_API on $(objects) = $(usesBeAPI) ; } MergeObject $(target) : $(sources) : $(otherObjects) ; } rule BuildPlatformMergeObjectPIC target : sources : otherObjects { # BuildPlatformMergeObjectPIC : : ; # Compiles source files and merges the object files to an object file. # Same as BuildPlatformMergeObject rule but adds position-independent # flags to the compiler (if any). # : Name of the object file to create. No grist will be added. # : Sources to be compiled. Grist will be added. # : Object files or static libraries to be merged. No grist # will be added. # ObjectCcFlags $(sources) : $(HOST_PIC_CCFLAGS) ; ObjectC++Flags $(sources) : $(HOST_PIC_C++FLAGS) ; BuildPlatformMergeObject $(target) : $(sources) : $(otherObjects) ; } rule BuildPlatformStaticLibrary lib : sources : otherObjects { # BuildPlatformStaticLibrary : ; # Creates a static library from sources. # : The static library to be built. # : List of source files. # : List of additional object files. # local objects = [ FGristFiles $(sources:S=$(SUFOBJ)) ] ; PLATFORM on $(lib) = host ; SUPPORTED_PLATFORMS on $(lib) = host ; local usesBeAPI = [ on $(lib) return $(USES_BE_API) ] ; if $(usesBeAPI) { # propagate the flag to the objects USES_BE_API on $(objects) = $(usesBeAPI) ; } StaticLibrary $(lib) : $(sources) : $(otherObjects) ; }