# Rules without side effects.# Vanilla Jam compatibilityif ! $(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 compatibilityrule FFilter{# FFilter <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) ;}rule FGetGrist{# FGetGrist <target> ;## Returns the grist of a target, not including leading "<" and trailing ">".local grist = $(1[1]:G) ;if ! $(grist) {return ;}return [ Match <(.*)> : $(grist) ] ;}rule FSplitString string : delimiterChar{local result ;while $(string) {local split = [ Match $(delimiterChar)*([^$(delimiterChar)]+)(.*): $(string) ] ;result += $(split[1]) ;string = $(split[2-]) ;}return $(result) ;}rule FSplitPath{# 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 FConditionsHold conditions : predicate{# FConditionsHold <conditions> : <predicate> ;# Checks whether the conditions <conditions> are satisfied by the predicate# rule <predicate> and returns a respective result (if so: "1", if not:# empty list). The conditions are satisfied when <conditions> is not empty# and# * none of the negative conditions it contains hold and# * if <conditions> contains any positive conditions, at least one of those# holds.# A positive condition is an element not starting with a "!". It holds when# the predicate rule <predicate> returns true for the element.# A negative condition is an element that starts with a "!". It holds when# the predicate rule <predicate> returns true for the string resulting from# removing the leading "!".## <conditions> - The list of conditions.# <predicate> - The predicate rule invoked to test the elements.## Examples:# For a predicate that holds for the elements of the set { a b c } the# following conditions hold:# { a }, { a d }, { !d }, { !d !e }, { a !d }, { b !e !f }# The following conditions don't hold:# { }, { d }, { d e }, { !a }, { !a b }, { !d e } { a b !c !d }local hasPositive ;local hasNegative ;local positiveMatch ;local condition ;for condition in $(conditions) {switch $(condition) {case !* :{hasNegative = 1 ;condition = [ Match "!(.*)" : $(condition) ] ;if [ $(predicate) $(condition) ] {return ;}}case * :{hasPositive = 1 ;if [ $(predicate) $(condition) ] {positiveMatch = 1 ;}}}}if $(hasPositive) {return $(positiveMatch) ;}return $(hasNegative) ;}rule SetPlatformCompatibilityFlagVariables{# SetPlatformCompatibilityFlagVariables <platform var> : <var prefix># : <platform kind> [ : other platforms ] ;local platformVar = $(1) ;local platform = $($(platformVar)) ;local varPrefix = $(2) ;local platformKind = $(3) ;local otherPlatforms = $(4) ;if ! $(platform) {ECHO "Variable $(platformVar) not set. Please run ./configure or" ;EXIT "specify it manually." ;}# special case: Haiku libbe.so built for testing under Haikuif $(platform) = libbe_test {platform = $(HOST_PLATFORM) ;}# unset variables first$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE = ;switch $(platform){case haiku_host :{$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE = true ;}case haiku :{$(varPrefix)_PLATFORM_HAIKU_COMPATIBLE = true ;}case host :# not compatible to anythingcase * :{if ! ( $(platform) in $(otherPlatforms) ) {Exit Unsupported $(platformKind) platform: $(platform) ;}}}# set the machine friendly flags$(varPrefix)_PLATFORM_(haiku)_COMPATIBLE?= $($(varPrefix)_PLATFORM_HAIKU_COMPATIBLE) ;$(varPrefix)_PLATFORM_(haiku_host)_COMPATIBLE?= $($(varPrefix)_PLATFORM_HAIKU_COMPATIBLE) ;}rule SetIncludePropertiesVariables prefix : suffix{# SetIncludePropertiesVariables <prefix> : <suffix> ;#suffix = $(suffix:E=) ;if $($(prefix)_CC_IS_LEGACY_GCC$(suffix)) = 1 {$(prefix)_INCLUDES_SEPARATOR$(suffix) = -I- ;$(prefix)_LOCAL_INCLUDES_OPTION$(suffix) = -I ;$(prefix)_SYSTEM_INCLUDES_OPTION$(suffix) = -I ;} else {$(prefix)_INCLUDES_SEPARATOR$(suffix) = ;$(prefix)_LOCAL_INCLUDES_OPTION$(suffix) = "-iquote " ;$(prefix)_SYSTEM_INCLUDES_OPTION$(suffix) = "-I " ;}}#pragma mark -rule SetPlatformForTarget{# SetPlatformForTarget <target> : <platform> ;PLATFORM on $(1) = $(2) ;}rule SetSubDirPlatform{# SetSubDirPlatform <platform> ;PLATFORM = $(1) ;}rule SetSupportedPlatformsForTarget{# SetSupportedPlatformsForTarget <target> : <platforms> ;SUPPORTED_PLATFORMS on $(1) = $(2) ;}rule SetSubDirSupportedPlatforms{# SetSubDirSupportedPlatforms <platforms> ;SUPPORTED_PLATFORMS = $(1) ;}rule AddSubDirSupportedPlatforms{# AddSubDirSupportedPlatforms <platforms> ;SUPPORTED_PLATFORMS += $(1) ;}rule IsPlatformSupportedForTarget{# IsPlatformSupportedForTarget <target> [ : <platform> ]#on $(1) {if $(PLATFORM) in $(SUPPORTED_PLATFORMS) {return true ;} else {return ;}}}rule InheritPlatform{# InheritPlatform <children> : <parent> ;# PLATFORM and SUPPORTED_PLATFORMS are set on <children> to their value# on <parent>.#local children = $(1) ;local parent = $(2) ;on $(parent) {PLATFORM on $(children) = $(PLATFORM) ;SUPPORTED_PLATFORMS on $(children) = $(SUPPORTED_PLATFORMS) ;}}rule SubDirAsFlags{SUBDIRASFLAGS += $(<) ;}