| # Copyright 2020 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/packages/package_metadata.gni") |
| import("//build/packages/prebuilt_package.gni") |
| |
| declare_args() { |
| # Used to configure the set of package flavors desired. |
| # |
| # Usage: |
| # |
| # package_flavor_selections = [ |
| # { |
| # name = "snazzy" |
| # flavor = "with_hooks" |
| # }, |
| # { |
| # name = "some_other_package" |
| # flavor = "some_other_flavor" |
| # }, |
| # ] |
| # |
| # The above specifies that the package "snazzy" should use the |
| # "with_hooks" flavor, and that "some_other_package" should use |
| # the "some_other_flavor" flavor instead of their default flavor |
| # all other packages using this template would use their default |
| # package flavors. |
| package_flavor_selections = [] |
| } |
| |
| # Choose which flavor from a set of signed, sealed pre-built package files |
| # which all are mutually-exclusive implementations of a given package. |
| # |
| # This template produces a single GN label and package to publish in |
| # build output TUF repo. |
| # |
| # THIS SHOULD BE USED WITH CARE |
| # |
| # This template records metadata about which flavor was chosen, which |
| # can be used to generate build output manifests of the chosen flavors |
| # |
| # src/prebuilt/snazzy/BUILD.gn: |
| # |
| # prebuilt_package_with_flavors("snazzy") { |
| # default = "release" |
| # flavors = [ |
| # { |
| # name = "release" |
| # archive = "some/path/to/snazzy/release" |
| # }, |
| # { |
| # name = "with_hooks" |
| # archive = "some/path/to/snazzy/with_hooks" |
| # } |
| # ] |
| # package_flavor_selections |
| # } |
| # |
| # and the following in GN build args: |
| # |
| # package_flavor_selections = [ |
| # { |
| # name = "snzzy" |
| # flavor = "with_hooks" |
| # }, |
| #] |
| # |
| # will produce the following GN label: |
| # `//src/prebuilt/snazzy:snazzy` |
| # |
| # a package with the name `snazzy` and will use the archive at |
| # `some/path/to/snazzy/with_hooks` as the implementation for that |
| # package. |
| # |
| # Which package flavors were chosen is emitted in the build output, at |
| # $out_dir/prebuilt_package_flavor_selections.json. This is |
| # performed by the //:prebuilt_package_flavors build_api() target. |
| # |
| # Parameters |
| # |
| # default (required; string) |
| # The name of the default flavor to use if not overridden |
| # in `flavor_selections` |
| # |
| # flavors (required) |
| # A list of "flavor" definition scopes, each of which has: |
| # name (required) |
| # The name of the flavor |
| # archive (required) |
| # The path to this flavor's prebuilt archive |
| # production_safe (optional, boolean, default: false) |
| # If not set to true, the flavor is marked with |
| # //build/validate:non_production_tag |
| # deps (optional) |
| # Extra dependencies specific to this flavor. |
| # |
| # package_name (optional) |
| # Name of the prebuilt package, defaults to template's target name |
| # |
| # selections (optional; scope) |
| # The package_flavor_selections, if and only if the caller of the template |
| # has logic that attempts to change the flavor based on other build args. |
| # This is not the preferred mechanism, but may be used in some cases. |
| # |
| # deps (optional) |
| # testonly (optional) |
| # visibility (optional) |
| # Usual GN meanings. |
| # |
| template("prebuilt_package_with_flavors") { |
| pkg_name = target_name |
| |
| # Start with the default value |
| assert(defined(invoker.default), "A default flavor must be specified") |
| flavor_name_to_use = invoker.default |
| |
| # If the invoker has modified and passed-in the package_flavor_selections |
| # list, use that instead of the one from GN args. |
| if (defined(invoker.selections)) { |
| flavor_selections = invoker.selections |
| } else { |
| flavor_selections = package_flavor_selections |
| } |
| |
| # Since we can't index into a scope by a variable, flavor_selections is a list |
| # that's walked, looking for an entry that matches this invocation of the |
| # template. If multiple entries in the list match, the last one wins |
| # (which is the same result as if it was key=value pairs in a scope). |
| foreach(selection, flavor_selections) { |
| assert(defined(selection.name), |
| "package flavor selections need to have a `name`") |
| assert( |
| defined(selection.flavor), |
| "package flavor selection for ${selection.name} doesn't have a `flavor`") |
| |
| if (selection.name == pkg_name) { |
| flavor_name_to_use = selection.flavor |
| } |
| } |
| |
| # This is used to track all the flavor names for error printing |
| all_names = [] |
| |
| # Find the selected flavor in the list of possible flavors |
| foreach(flavor, invoker.flavors) { |
| assert(defined(flavor.name), "all package flavors must be named") |
| assert(defined(flavor.archive), |
| "${flavor.name} does not define an archive to use") |
| all_names += [ flavor.name ] |
| if (flavor_name_to_use == flavor.name) { |
| flavor_to_use = flavor |
| } |
| } |
| assert( |
| defined(flavor_to_use), |
| "The chosen flavor: '${flavor_name_to_use}', is not a valid flavor: ${all_names}") |
| |
| # Default all prebuilts to not "production-safe" unless they explicitly are set to true |
| production_safe = false |
| if (defined(flavor_to_use.production_safe)) { |
| production_safe = flavor_to_use.production_safe |
| } |
| |
| # Invoke the prebuilt_package template with the chosen flavor. |
| prebuilt_package(pkg_name) { |
| archive = flavor_to_use.archive |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "testonly", |
| "visibility", |
| "package_name", |
| "repository", |
| ]) |
| |
| # setup the non-production-safe status of the package |
| if (!production_safe) { |
| if (!defined(deps)) { |
| deps = [] |
| } |
| |
| # Mark as not safe for production use. |
| deps += [ "//build/validate:non_production_tag" ] |
| } |
| |
| if (defined(flavor_to_use.deps)) { |
| if (!defined(deps)) { |
| deps = [] |
| } |
| |
| # Add flavor-specific dependencies. |
| deps += flavor_to_use.deps |
| } |
| |
| # Set up the metadata to track which flavor is being used. |
| metadata = { |
| prebuilt_package_with_flavors = [ |
| { |
| package = pkg_name |
| |
| # This also passes any other fields set on the scope for the flavor, |
| # so that it can additionally be captured in the metadata manifest. |
| forward_variables_from(flavor_to_use, "*") |
| }, |
| ] |
| } |
| } |
| } |