#3798: [PATCH] Arch-specific capabilities patch for HaikuImage ----------------------------+--------------------------- Reporter: umccullough | Owner: umccullough Type: enhancement | Status: assigned Priority: normal | Milestone: R1 Component: Build System | Version: R1/pre-alpha1 Resolution: | Keywords: Blocked By: | Blocking: Has a Patch: 1 | Platform: All ----------------------------+--------------------------- Comment (by bonefish): The reason why I suggested a new build/jam/BuildFeatures is that those aren't really optional in that they represent features one can build with or without (e.g. SSL). Instead their availability depends merely on the architecture. Admittedly this line is rather blurry, since some stuff is provided as an optional package only for some architectures, and, even worse, AFAIK some stuff isn't even optional at all (ICU). So it might be better to just rename OptionalBuildFeatures to BuildFeatures and put the declarations for all the features in there. Anyway regarding the actual solution for HaikuImage, I think that the `*_ONLY` approach has outgrown its originally simple elegance. Instead of a `$(X86_ONLY)` tag here and there we have those tags in a lot of places now, and with x86-64 coming into the fold and maybe ARM soon as well there'll be even more. We won't get around declaring what target is enable for which architecture/feature, but I was thinking of a syntactically more elegant solution. I'm attaching a test Jamfile with the rules needed for that solution. Some examples for the interesting ones: {{{ EnableBuildFeatures opengl ffmpeg freebsd_network : x86 x86_64 ; EnableBuildFeatures ssl : !arm ; }}} The first argument to `EnableBuildFeatures` is the list of features to enable, the second is a list of conditions. If no conditions are given, the features are enabled unconditionally, otherwise only when the conditions hold true. The condition list can consist of any number of positive and negative ('!' prefix) conditions. The features are enabled, when any of the positive conditions and none of the negative conditions hold true. The condition elements are build features themselves. A positive/negative condition holds true when the respective build feature was/wasn't enabled before. The architecture is initially added as a build feature unconditionally (`EnableBuildFeatures $(HAIKU_ARCH) ;`), so the above examples work. When a feature is enabled its name is added to the variable `HAIKU_BUILD_FEATURES` and a variable `HAIKU_<FEATURE>_ENABLED` is defined (`<FEATURE>` is all upper case). The second rule is `FMatchesBuildFeatures`. It returns "1" (i.e. true), if the given condition holds, or an empty list (i.e. false) otherwise. It supports the same condition lists as `EnableBuildFeatures` and additionally a comma-separated form. {{{ if [ FMatchesBuildFeatures x86 x86_64 ] { # x86 or x86-64 } if [ FMatchesBuildFeatures opengl,!arm ] { # OpenGL but not ARM } }}} The most interesting rule for HaikuImage is `FFilterByBuildFeatures`. It takes a list annotated with build feature conditions and returns a list filtered accordingly. {{{ AddBootModuleSymlinksToHaikuImage [ FFilterByBuildFeatures x86,x86_64 @{ acpi isa ide_isa }@ openpic@ppc ata @{ ata ata_adapter }@ ide @{ ide ide_adapter }@ pci config_manager dpc locked_pool scsi_periph scsi usb ahci generic_ide_pci it8211 legacy_sata silicon_image_3112 <usb>uhci <usb>ohci <usb>ehci scsi_cd scsi_disk usb_disk efi_gpt intel bfs ] ; }}} There are two kinds of annotations. Individual list elements can be annotated (e.g. `openpic@ppc` -- `openpic` only when `ppc` is enabled) and groups of elements can be annotated by enclosing them in `@{ ... }@` preceded by the condition string. Nesting those groups is possible as well as using element annotations within a group. For an element to be included in the filtered list its own condition (if any) and the condition of every containing group has to hold. All `*ToImage` (or generally `*ToContainer`) rules could filter their targets argument list by default, which would allow us to omit the explicit invocation of `FFilterByBuildFeatures` when the list is passed to such a rule directly (as in the example above). The exact syntax is only a proposal. If anyone has a nicer idea, let's hear it. I picked the `@` symbol as a separator for the element annotation, since it is a symbol that's rather unlikely to appear in regular target names. The annotation is a suffix, since it felt more natural at first. Though with the group annotation condition being a prefix, that could be reconsidered. Also for the group condition everything is separated by spaces while no spaces are used for the element annotations. Admittedly `openpic @ ppc` is nicer to read than `openpic@ppc`. OTOH, in a single-line list it's clearly the other way around (`foo@x86 bar@ppc foobar@arm` vs. `foo @ x86 bar @ ppc foobar @ arm`). For grouping using something with matching opening and closing symbol is nice. The obvious simple pairs `( )`, `[ ]`, `{ }`, `< >` can't be used, since they are special jam tokens and would have to be quoted. Due to `@` being used for the element annotations `@{ }@` seemed a reasonable choice. Though other alternatives -- e.g. `@x86,x86_64( ... )@` -- would look just as reasonable. Opinions and suggestions welcome. -- Ticket URL: <http://dev.haiku-os.org/ticket/3798#comment:12> Haiku <http://dev.haiku-os.org> Haiku - the operating system.