From d31a50eef768be42588772f94a101e28c8b6415c Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 5 Aug 2013 00:17:46 +0200 Subject: [PATCH] Move build feature rules to separate file --- Jamrules | 1 + build/jam/BuildFeatureRules | 417 +++++++++++++++++++++++++++++++++++ build/jam/MiscRules | 422 ------------------------------------ 3 files changed, 418 insertions(+), 422 deletions(-) create mode 100644 build/jam/BuildFeatureRules diff --git a/Jamrules b/Jamrules index 4ce01e8ddc..2c5ed7bc48 100644 --- a/Jamrules +++ b/Jamrules @@ -41,6 +41,7 @@ include [ FDirName $(HAIKU_BUILD_RULES_DIR) HelperRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) MathRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) ArchitectureRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) BeOSRules ] ; +include [ FDirName $(HAIKU_BUILD_RULES_DIR) BuildFeatureRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) LocaleRules ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) CommandLineArguments ] ; include [ FDirName $(HAIKU_BUILD_RULES_DIR) ConfigRules ] ; diff --git a/build/jam/BuildFeatureRules b/build/jam/BuildFeatureRules new file mode 100644 index 0000000000..85b3cea671 --- /dev/null +++ b/build/jam/BuildFeatureRules @@ -0,0 +1,417 @@ +rule FIsBuildFeatureEnabled feature +{ + # FIsBuildFeatureEnabled ; + # Returns whether the given build feature is enabled (if so: "1", + # if not: empty list). + # + # - The name of the build feature (all lower case). + + if $(feature) in $(HAIKU_BUILD_FEATURES) { + return 1 ; + } + + return ; +} + + +rule FMatchesBuildFeatures specification +{ + # FMatchesBuildFeatures ; + # Returns whether the given build feature specification + # holds. consists of positive and negative build feature + # conditions. Conditions can be individual list elements and multiple + # conditions can be joined, separated by ",", in a single list element. The + # effect is the same; they are considered as single set of conditions. + # A positive condition does not start with a "!". It holds when the build + # feature named by the element is enabled. + # A negative condition starts with a "!". It holds when the build feature + # named by the string resulting from removing the leading "!" is not + # enabled. + # holds when it is not empty and + # * none of the negative conditions it contains hold and + # * if it contains any positive conditions, at least one one of them holds. + # + # - The build feature specification. A list of individual + # conditions or conditions joined by ",". + + local splitSpecification ; + local element ; + for element in $(specification) { + splitSpecification += [ FSplitString $(element) : "," ] ; + } + return [ FSetConditionsHold $(splitSpecification) + : $(HAIKU_BUILD_FEATURES) ] ; +} + + +rule FFilterByBuildFeatures list +{ + # FFilterByBuildFeatures ; + # Filters the list annotated by build feature specifications and returns the + # resulting list. The list can be annotated in two different ways: + # * A single list element can be annotated by appending "@" + # to it, with being a build feature specification (a + # single comma-separated string). The element appears in the resulting + # list, only if holds. + # * A sublist can be annotated by enclosing it in " @{" (two + # separate list elements) and "}@", with being a build + # feature specification (a single comma-separated string). The enclosed + # sublist appears in the resulting list, only if holds. + # The sublist annotations can be nested. The annotations themselves don't + # appear in the resulting list. + # + # - A list annotated with build feature specifications. + + local filteredList ; + + # Since we must look ahead one element to be able to decide whether an + # element is a regular list element or a features specification for a + # subsequent "@{". Hence we always process an element other than "@{" and + # "}@" in the next iteration. We append a dummy element to the list so we + # don't need special handling for the last element. + local evaluationStack = 1 ; + local previousElement ; + local element ; + for element in $(list) dummy { + local stackTop = $(evaluationStack[1]) ; + local processElement = $(previousElement) ; + switch $(element) { + case }@ : + { + # Pop the topmost specification off the stack. + evaluationStack = $(evaluationStack[2-]) ; + if ! $(evaluationStack) { + Exit "FFilterByBuildFeatures: Unbalanced @( in: " $(list) ; + } + + processElement = $(previousElement) ; + previousElement = ; + } + case @{ : + { + if ! $(previousElement) { + Exit "FFilterByBuildFeatures: No feature specification" + "after )@ in: " $(list) ; + } + + if $(evaluationStack[1]) = 1 + && [ FMatchesBuildFeatures $(previousElement) ] { + evaluationStack = 1 $(evaluationStack) ; + } else { + evaluationStack = 0 $(evaluationStack) ; + } + + processElement = ; + previousElement = ; + } + case * : + { + processElement = $(previousElement) ; + previousElement = $(element) ; + } + } + + if $(processElement) && $(stackTop) = 1 { + local splitElement = [ Match "(.*)@([^@]*)" : $(processElement) ] ; + if $(splitElement) { + if [ FMatchesBuildFeatures $(splitElement[2]) ] { + filteredList += $(splitElement[1]) ; + } + } else { + filteredList += $(processElement) ; + } + } + } + + if $(evaluationStack[2-]) { + Exit "FFilterByBuildFeatures: Unbalanced )@ in: " $(list) ; + } + + return $(filteredList) ; +} + + +rule EnableBuildFeatures features : specification +{ + # EnableBuildFeatures : ; + # Enables the build features , if the build features specification + # holds. If is omitted, the features are + # enabled unconditionally. + # The rule enables a build feature by adding its given lower case name to + # the build variable HAIKU_BUILD_FEATURES and defining a build variable + # HAIKU_BUILD_FEATURE__ENABLED ( being the upper case name + # of the build feature) to "1". + # + # - A list of build feature names (lower case). + # - An optional build features specification (cf. + # FMatchesBuildFeatures). + + if ! $(specification) + || [ FMatchesBuildFeatures $(specification) + : $(HAIKU_BUILD_FEATURES) ] { + local feature ; + for feature in $(features) { + HAIKU_BUILD_FEATURES += $(feature) ; + HAIKU_BUILD_FEATURE_$(feature:U)_ENABLED = 1 ; + } + } +} + + +rule BuildFeatureObject feature +{ + # BuildFeatureObject ; + # Returns a unique object for the given build feature. It is used for + # attaching attribute values to it. + + local featureObject = $(HAIKU_BUILD_FEATURE_$(feature:U)) ; + if ! $(featureObject) { + featureObject = [ NewUniqueTarget ] ; + HAIKU_BUILD_FEATURE_$(feature:U) = $(featureObject) ; + } + + return $(featureObject) ; +} + + +rule SetBuildFeatureAttribute feature : attribute : values : package +{ + # SetBuildFeatureAttribute : : + # [ : ] ; + # Sets attribute of a build feature to value . + # If is specified, it names the package the attribute belongs to. + + local featureObject = [ BuildFeatureObject $(feature) ] ; + HAIKU_ATTRIBUTE_$(attribute) on $(featureObject) = $(values) ; + if $(package) { + HAIKU_ATTRIBUTE_$(attribute):package on $(featureObject) = $(package) ; + } +} + + +rule BuildFeatureAttribute feature : attribute : flags +{ + # BuildFeatureAttribute : [ : ] ; + # Returns the value of attribute of a build feature . + # Flags can be a list of flags which influence the returned value. Currently + # only flag "path" is defined, which will convert the attribute value -- + # which is assumed to be a list of (gristed) targets with a path relative to + # the extraction directory of the build feature archive files -- to paths. + # A typical example is the "headers" attribute, whose value can be used as + # dependency, but which must be converted to a path to be a valid headers + # search path. + + local featureObject = [ BuildFeatureObject $(feature) ] ; + local values + = [ on $(featureObject) return $(HAIKU_ATTRIBUTE_$(attribute)) ] ; + if path in $(flags) { + # get the attribute's package and the corresponding extraction dir + local package + = [ BuildFeatureAttribute $(feature) : $(attribute):package ] ; + local directory ; + if $(package) { + directory = [ BuildFeatureAttribute $(feature) + : $(package):directory ] ; + } + + # translate the values + local paths ; + local value ; + for value in $(values:G=) { + paths += [ FDirName $(directory) $(value) ] ; + } + values = $(paths) ; + } + + return $(values) ; +} + + +rule ExtractBuildFeatureArchivesExpandValue value : fileName +{ + if ! $(value) { + return $(value) ; + } + + # split the value + local splitValue ; + while $(value) { + local components = [ Match "([^%]*)(%[^%]*%)(.*)" : $(value) ] ; + if ! $(components) { + splitValue += $(value) ; + break ; + } + + if $(components[1]) { + splitValue += $(components[1]) ; + } + splitValue += $(components[2]) ; + value = $(components[3]) ; + } + + # reassemble the value, performing the substitutions + local %packageName% ; + local %portName% ; + local %packageFullVersion% ; + value = "" ; + while $(splitValue) { + local component = $(splitValue[1]) ; + splitValue = $(splitValue[2-]) ; + switch $(component) { + case %packageRevisionedName% : + splitValue = %packageName% "-" %packageFullVersion% + $(splitValue) ; + + case %portRevisionedName% : + splitValue = %portName% "-" %packageFullVersion% $(splitValue) ; + + case %*% : + if ! x$(%packageName%) { + # extract package name and version from file name + local splitName + = [ Match "([^-]*)-(.*).hpkg" : $(fileName) ] ; + if $(splitName) { + %packageName% = $(splitName[1]) ; + %packageFullVersion% + = [ Match "([^-]*-[^-]*)-.*" : $(splitName[2]) ] ; + if ! $(packageFullVersion%) { + packageFullVersion% = $(splitName[2]) ; + } + } else { + %packageName% = [ Match "(.*).hpkg" : $(fileName) ] ; + if ! $(%packageName%) { + %packageName% = $(fileName) ; + } + %packageFullVersion% = "" ; + } + + # get the port name from the package name + splitName = [ Match "(.*)_([^_]*)" : $(%packageName%) ] ; + local knownPackageSuffixes = devel doc source debuginfo ; + if $(splitName[2]) + && $(splitName[2]) in $(knownPackageSuffixes) { + %portName% = $(splitName[1]) ; + } else { + %portName% = $(%packageName%) ; + } + } + + value = "$(value)$($(component):E=)" ; + + case * : + value = "$(value)$(component)" ; + } + } + + return $(value) ; +} + + +rule ExtractBuildFeatureArchives feature : list +{ + # ExtractBuildFeatureArchives : ; + # Downloads and extracts one or more archives for build feature + # and sets attributes for the build feature to extracted entries. The syntax + # for is: + # "file:" + # : ... + # ... + # "file:" + # ... + # + # specifies a short name for the archive (e.g. "base" for the + # base package, "devel" for the development package, etc.), + # the unversioned name of the package (e.g. "libsolv_devel"). + # can be any name and any relative path in the + # extraction directory. The following placeholders in will be + # replaced with the respective value: + # * %packageName% is replaced with the name of the package as extracted from + # the package file name (may differ from the specified package name e.g. + # for bootstrap packages). + # * %portName% is replaced with the name of the port the package belongs to. + # That is %packageName% with any well-known package type suffix ("_devel", + # "_source", etc.) removed. + # * %packageFullVersion% is replaced with the the full version string of the + # package (i.e. including the revision) as extracted frmo the package file + # name. + # * %packageRevisionedName% is replaced with what + # %packageName%-%packageFullVersion% would be replaced. + # * %portRevisionedName% is replaced with what + # %portName%-%packageFullVersion% would be replaced. + # + # The attribute with the name "depends" will be handled specially. Its + # specifies the name of a package the current package depends on + # (e.g. "devel" typically depends on "base"). If such a dependency is + # specified the current package will be extracted to the same directory as + # the package it depends on. The "depends" attribute must precede any other + # attribute for the package. + # + # The rule also sets the build feature attribute ":directory" + # to the extraction directory for each package. + + while $(list) { + if $(list[1]) != file: { + Exit "ExtractBuildFeatureArchives: Expected \"file: ...\", got:" + $(list) ; + } + + local package = $(list[2]) ; + local file = [ FetchPackage $(list[3]) ] ; + local fileName = $(file:BS) ; + list = $(list[4-]) ; + + local directory = [ FDirName $(HAIKU_OPTIONAL_BUILD_PACKAGES_DIR) + $(fileName:B) ] ; + directory = $(directory:G=$(package)) ; + + while $(list) { + local attribute = [ Match "(.*):" : $(list[1]) ] ; + if ! $(attribute) { + Exit "ExtractBuildFeatureArchives: Expected attribute, got:" + $(list) ; + } + if $(attribute) = file { + break ; + } + + list = $(list[2-]) ; + + local values ; + + while $(list) { + switch $(list[1]) { + case *: : + { + break ; + } + case * : + { + values += [ ExtractBuildFeatureArchivesExpandValue + $(list[1]) : $(fileName) ] ; + list = $(list[2-]) ; + } + } + } + + if $(attribute) = depends { + # Inherit the extraction directory (with a different grist) and + # depend on the extraction directory of the base package. + local basePackage = $(values[1]) ; + local baseDirectory = [ BuildFeatureAttribute $(feature) + : $(basePackage):directory ] ; + directory = $(baseDirectory:G=$(package)) ; + Depends $(directory) : $(directory:G=$(basePackage)) ; + } else { + SetBuildFeatureAttribute $(feature) : $(attribute) + : [ ExtractArchive $(directory) + : $(values) : $(file) + : extracted-$(feature)-$(package) ] ; + SetBuildFeatureAttribute $(feature) : $(attribute):package + : $(package) ; + } + } + + SetBuildFeatureAttribute $(feature) : $(package):directory + : $(directory:G=) ; + } +} diff --git a/build/jam/MiscRules b/build/jam/MiscRules index 68f9cbab6b..df285fdbd4 100644 --- a/build/jam/MiscRules +++ b/build/jam/MiscRules @@ -437,425 +437,3 @@ rule DefineBuildProfile name : type : path { return 1 ; } - - -# pragma mark - Build Features - - -rule FIsBuildFeatureEnabled feature -{ - # FIsBuildFeatureEnabled ; - # Returns whether the given build feature is enabled (if so: "1", - # if not: empty list). - # - # - The name of the build feature (all lower case). - - if $(feature) in $(HAIKU_BUILD_FEATURES) { - return 1 ; - } - - return ; -} - - -rule FMatchesBuildFeatures specification -{ - # FMatchesBuildFeatures ; - # Returns whether the given build feature specification - # holds. consists of positive and negative build feature - # conditions. Conditions can be individual list elements and multiple - # conditions can be joined, separated by ",", in a single list element. The - # effect is the same; they are considered as single set of conditions. - # A positive condition does not start with a "!". It holds when the build - # feature named by the element is enabled. - # A negative condition starts with a "!". It holds when the build feature - # named by the string resulting from removing the leading "!" is not - # enabled. - # holds when it is not empty and - # * none of the negative conditions it contains hold and - # * if it contains any positive conditions, at least one one of them holds. - # - # - The build feature specification. A list of individual - # conditions or conditions joined by ",". - - local splitSpecification ; - local element ; - for element in $(specification) { - splitSpecification += [ FSplitString $(element) : "," ] ; - } - return [ FSetConditionsHold $(splitSpecification) - : $(HAIKU_BUILD_FEATURES) ] ; -} - - -rule FFilterByBuildFeatures list -{ - # FFilterByBuildFeatures ; - # Filters the list annotated by build feature specifications and returns the - # resulting list. The list can be annotated in two different ways: - # * A single list element can be annotated by appending "@" - # to it, with being a build feature specification (a - # single comma-separated string). The element appears in the resulting - # list, only if holds. - # * A sublist can be annotated by enclosing it in " @{" (two - # separate list elements) and "}@", with being a build - # feature specification (a single comma-separated string). The enclosed - # sublist appears in the resulting list, only if holds. - # The sublist annotations can be nested. The annotations themselves don't - # appear in the resulting list. - # - # - A list annotated with build feature specifications. - - local filteredList ; - - # Since we must look ahead one element to be able to decide whether an - # element is a regular list element or a features specification for a - # subsequent "@{". Hence we always process an element other than "@{" and - # "}@" in the next iteration. We append a dummy element to the list so we - # don't need special handling for the last element. - local evaluationStack = 1 ; - local previousElement ; - local element ; - for element in $(list) dummy { - local stackTop = $(evaluationStack[1]) ; - local processElement = $(previousElement) ; - switch $(element) { - case }@ : - { - # Pop the topmost specification off the stack. - evaluationStack = $(evaluationStack[2-]) ; - if ! $(evaluationStack) { - Exit "FFilterByBuildFeatures: Unbalanced @( in: " $(list) ; - } - - processElement = $(previousElement) ; - previousElement = ; - } - case @{ : - { - if ! $(previousElement) { - Exit "FFilterByBuildFeatures: No feature specification" - "after )@ in: " $(list) ; - } - - if $(evaluationStack[1]) = 1 - && [ FMatchesBuildFeatures $(previousElement) ] { - evaluationStack = 1 $(evaluationStack) ; - } else { - evaluationStack = 0 $(evaluationStack) ; - } - - processElement = ; - previousElement = ; - } - case * : - { - processElement = $(previousElement) ; - previousElement = $(element) ; - } - } - - if $(processElement) && $(stackTop) = 1 { - local splitElement = [ Match "(.*)@([^@]*)" : $(processElement) ] ; - if $(splitElement) { - if [ FMatchesBuildFeatures $(splitElement[2]) ] { - filteredList += $(splitElement[1]) ; - } - } else { - filteredList += $(processElement) ; - } - } - } - - if $(evaluationStack[2-]) { - Exit "FFilterByBuildFeatures: Unbalanced )@ in: " $(list) ; - } - - return $(filteredList) ; -} - - -rule EnableBuildFeatures features : specification -{ - # EnableBuildFeatures : ; - # Enables the build features , if the build features specification - # holds. If is omitted, the features are - # enabled unconditionally. - # The rule enables a build feature by adding its given lower case name to - # the build variable HAIKU_BUILD_FEATURES and defining a build variable - # HAIKU_BUILD_FEATURE__ENABLED ( being the upper case name - # of the build feature) to "1". - # - # - A list of build feature names (lower case). - # - An optional build features specification (cf. - # FMatchesBuildFeatures). - - if ! $(specification) - || [ FMatchesBuildFeatures $(specification) - : $(HAIKU_BUILD_FEATURES) ] { - local feature ; - for feature in $(features) { - HAIKU_BUILD_FEATURES += $(feature) ; - HAIKU_BUILD_FEATURE_$(feature:U)_ENABLED = 1 ; - } - } -} - - -rule BuildFeatureObject feature -{ - # BuildFeatureObject ; - # Returns a unique object for the given build feature. It is used for - # attaching attribute values to it. - - local featureObject = $(HAIKU_BUILD_FEATURE_$(feature:U)) ; - if ! $(featureObject) { - featureObject = [ NewUniqueTarget ] ; - HAIKU_BUILD_FEATURE_$(feature:U) = $(featureObject) ; - } - - return $(featureObject) ; -} - - -rule SetBuildFeatureAttribute feature : attribute : values : package -{ - # SetBuildFeatureAttribute : : - # [ : ] ; - # Sets attribute of a build feature to value . - # If is specified, it names the package the attribute belongs to. - - local featureObject = [ BuildFeatureObject $(feature) ] ; - HAIKU_ATTRIBUTE_$(attribute) on $(featureObject) = $(values) ; - if $(package) { - HAIKU_ATTRIBUTE_$(attribute):package on $(featureObject) = $(package) ; - } -} - - -rule BuildFeatureAttribute feature : attribute : flags -{ - # BuildFeatureAttribute : [ : ] ; - # Returns the value of attribute of a build feature . - # Flags can be a list of flags which influence the returned value. Currently - # only flag "path" is defined, which will convert the attribute value -- - # which is assumed to be a list of (gristed) targets with a path relative to - # the extraction directory of the build feature archive files -- to paths. - # A typical example is the "headers" attribute, whose value can be used as - # dependency, but which must be converted to a path to be a valid headers - # search path. - - local featureObject = [ BuildFeatureObject $(feature) ] ; - local values - = [ on $(featureObject) return $(HAIKU_ATTRIBUTE_$(attribute)) ] ; - if path in $(flags) { - # get the attribute's package and the corresponding extraction dir - local package - = [ BuildFeatureAttribute $(feature) : $(attribute):package ] ; - local directory ; - if $(package) { - directory = [ BuildFeatureAttribute $(feature) - : $(package):directory ] ; - } - - # translate the values - local paths ; - local value ; - for value in $(values:G=) { - paths += [ FDirName $(directory) $(value) ] ; - } - values = $(paths) ; - } - - return $(values) ; -} - - -rule ExtractBuildFeatureArchivesExpandValue value : fileName -{ - if ! $(value) { - return $(value) ; - } - - # split the value - local splitValue ; - while $(value) { - local components = [ Match "([^%]*)(%[^%]*%)(.*)" : $(value) ] ; - if ! $(components) { - splitValue += $(value) ; - break ; - } - - if $(components[1]) { - splitValue += $(components[1]) ; - } - splitValue += $(components[2]) ; - value = $(components[3]) ; - } - - # reassemble the value, performing the substitutions - local %packageName% ; - local %portName% ; - local %packageFullVersion% ; - value = "" ; - while $(splitValue) { - local component = $(splitValue[1]) ; - splitValue = $(splitValue[2-]) ; - switch $(component) { - case %packageRevisionedName% : - splitValue = %packageName% "-" %packageFullVersion% - $(splitValue) ; - - case %portRevisionedName% : - splitValue = %portName% "-" %packageFullVersion% $(splitValue) ; - - case %*% : - if ! x$(%packageName%) { - # extract package name and version from file name - local splitName - = [ Match "([^-]*)-(.*).hpkg" : $(fileName) ] ; - if $(splitName) { - %packageName% = $(splitName[1]) ; - %packageFullVersion% - = [ Match "([^-]*-[^-]*)-.*" : $(splitName[2]) ] ; - if ! $(packageFullVersion%) { - packageFullVersion% = $(splitName[2]) ; - } - } else { - %packageName% = [ Match "(.*).hpkg" : $(fileName) ] ; - if ! $(%packageName%) { - %packageName% = $(fileName) ; - } - %packageFullVersion% = "" ; - } - - # get the port name from the package name - splitName = [ Match "(.*)_([^_]*)" : $(%packageName%) ] ; - local knownPackageSuffixes = devel doc source debuginfo ; - if $(splitName[2]) - && $(splitName[2]) in $(knownPackageSuffixes) { - %portName% = $(splitName[1]) ; - } else { - %portName% = $(%packageName%) ; - } - } - - value = "$(value)$($(component):E=)" ; - - case * : - value = "$(value)$(component)" ; - } - } - - return $(value) ; -} - - -rule ExtractBuildFeatureArchives feature : list -{ - # ExtractBuildFeatureArchives : ; - # Downloads and extracts one or more archives for build feature - # and sets attributes for the build feature to extracted entries. The syntax - # for is: - # "file:" - # : ... - # ... - # "file:" - # ... - # - # specifies a short name for the archive (e.g. "base" for the - # base package, "devel" for the development package, etc.), - # the unversioned name of the package (e.g. "libsolv_devel"). - # can be any name and any relative path in the - # extraction directory. The following placeholders in will be - # replaced with the respective value: - # * %packageName% is replaced with the name of the package as extracted from - # the package file name (may differ from the specified package name e.g. - # for bootstrap packages). - # * %portName% is replaced with the name of the port the package belongs to. - # That is %packageName% with any well-known package type suffix ("_devel", - # "_source", etc.) removed. - # * %packageFullVersion% is replaced with the the full version string of the - # package (i.e. including the revision) as extracted frmo the package file - # name. - # * %packageRevisionedName% is replaced with what - # %packageName%-%packageFullVersion% would be replaced. - # * %portRevisionedName% is replaced with what - # %portName%-%packageFullVersion% would be replaced. - # - # The attribute with the name "depends" will be handled specially. Its - # specifies the name of a package the current package depends on - # (e.g. "devel" typically depends on "base"). If such a dependency is - # specified the current package will be extracted to the same directory as - # the package it depends on. The "depends" attribute must precede any other - # attribute for the package. - # - # The rule also sets the build feature attribute ":directory" - # to the extraction directory for each package. - - while $(list) { - if $(list[1]) != file: { - Exit "ExtractBuildFeatureArchives: Expected \"file: ...\", got:" - $(list) ; - } - - local package = $(list[2]) ; - local file = [ FetchPackage $(list[3]) ] ; - local fileName = $(file:BS) ; - list = $(list[4-]) ; - - local directory = [ FDirName $(HAIKU_OPTIONAL_BUILD_PACKAGES_DIR) - $(fileName:B) ] ; - directory = $(directory:G=$(package)) ; - - while $(list) { - local attribute = [ Match "(.*):" : $(list[1]) ] ; - if ! $(attribute) { - Exit "ExtractBuildFeatureArchives: Expected attribute, got:" - $(list) ; - } - if $(attribute) = file { - break ; - } - - list = $(list[2-]) ; - - local values ; - - while $(list) { - switch $(list[1]) { - case *: : - { - break ; - } - case * : - { - values += [ ExtractBuildFeatureArchivesExpandValue - $(list[1]) : $(fileName) ] ; - list = $(list[2-]) ; - } - } - } - - if $(attribute) = depends { - # Inherit the extraction directory (with a different grist) and - # depend on the extraction directory of the base package. - local basePackage = $(values[1]) ; - local baseDirectory = [ BuildFeatureAttribute $(feature) - : $(basePackage):directory ] ; - directory = $(baseDirectory:G=$(package)) ; - Depends $(directory) : $(directory:G=$(basePackage)) ; - } else { - SetBuildFeatureAttribute $(feature) : $(attribute) - : [ ExtractArchive $(directory) - : $(values) : $(file) - : extracted-$(feature)-$(package) ] ; - SetBuildFeatureAttribute $(feature) : $(attribute):package - : $(package) ; - } - } - - SetBuildFeatureAttribute $(feature) : $(package):directory - : $(directory:G=) ; - } -}