diff --git a/build/jam/HeadersRules b/build/jam/HeadersRules index b111dcba81..da07f9e4fa 100644 --- a/build/jam/HeadersRules +++ b/build/jam/HeadersRules @@ -412,6 +412,20 @@ rule UsePrivateSystemHeaders } +rule UseBuildFeatureHeaders feature : attribute +{ + # UseBuildFeatureHeaders : [ ] ; + # A shorthand for + # UseHeaders [ BuildFeatureAttribute : ] : true ; + # Moreover the default value for is "headers", which usually + # allows the rule to be called with the feature name as the only parameter. + + local headers = [ BuildFeatureAttribute $(feature) : $(attribute:E=headers) + : path ] ; + UseHeaders $(headers) : true ; +} + + rule FStandardOSHeaders { local osIncludes = add-ons add-ons/file_system add-ons/graphics diff --git a/build/jam/MiscRules b/build/jam/MiscRules index dca26616f7..784351d1ff 100644 --- a/build/jam/MiscRules +++ b/build/jam/MiscRules @@ -590,3 +590,168 @@ rule EnableBuildFeatures features : specification } } } + + +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 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 URL + # from which to download the file. and be any name and + # any relative path in the extraction directory. + # + # 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 url = $(list[3]) ; + local fileName = $(url:BS) ; + list = $(list[4-]) ; + + local file = [ DownloadFile $(fileName) : $(url) ] ; + + 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 += $(list[1]) ; + 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=) ; + } +}