| # Copyright 2019 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("zx_manifest.gni") |
| |
| # Generates a standalone manifest for an executable target. |
| # |
| # Parameters |
| # |
| # type (required) |
| # Type of the target to generate, e.g. `executable`, `driver`. |
| # |
| # prefix (required) |
| # String prefixed to generated manifest names. |
| |
| template("zx_binary") { |
| assert(defined(invoker.type), "Need a type") |
| assert(defined(invoker.prefix), "Need a prefix") |
| |
| local_params = [ |
| "prefix", |
| "type", |
| ] |
| |
| main_target_name = target_name |
| binary_target_name = "$target_name.binary" |
| manifest_target_name = "$target_name.manifest" |
| |
| # The actual executable target. |
| target(invoker.type, binary_target_name) { |
| forward_variables_from(invoker, "*", local_params) |
| |
| if (!defined(output_name)) { |
| output_name = main_target_name |
| } |
| } |
| |
| # This name is the name under which the binary appears in the final list of |
| # manifests. |
| _binary_name = "${invoker.prefix}." |
| if (defined(invoker.output_name)) { |
| _binary_name += invoker.output_name |
| } else { |
| _binary_name += main_target_name |
| } |
| if (defined(toolchain.shlib) && current_toolchain == toolchain.shlib) { |
| _binary_name += ".shlib" |
| } |
| |
| # Two manifest targets are needed here, to ensure that they depend on the |
| # exact spelling of the binary target as expected given the rules of variant |
| # selection. If that target ends up included in the dependency graph under |
| # two different labels, metadata generation is affected with potentially |
| # build-breaking effects. |
| |
| zx_manifest(manifest_target_name) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| |
| target = ":$binary_target_name" |
| |
| name = _binary_name |
| } |
| |
| zx_manifest("$manifest_target_name${toolchain.variant_suffix}") { |
| forward_variables_from(invoker, [ "testonly" ]) |
| |
| target = ":$binary_target_name${toolchain.variant_suffix}" |
| |
| name = "$_binary_name${toolchain.variant_suffix}" |
| } |
| |
| # Perform variant selection. |
| # This logic is duplicated from //zircon/public/gn/BUILDCONFIG.gn. It is |
| # necessary to push the awareness of variants all the way up to this template |
| # as this ensures that the right version of binary_target_name gets inserted |
| # into the dependency graph. |
| _builder_toolchain = false |
| foreach(selector, toolchain.variant_selectors) { |
| selector_matches = true |
| |
| if (selector.cpu != []) { |
| if (selector.cpu + [ current_cpu ] - [ current_cpu ] == selector.cpu) { |
| selector_matches = false |
| } |
| } |
| if (selector.dir != []) { |
| dir = get_label_info(":$main_target_name", "dir") |
| if (selector.dir + [ dir ] - [ dir ] == selector.dir) { |
| selector_matches = false |
| } |
| } |
| if (selector.environment != []) { |
| if (selector.environment + [ toolchain.environment ] - |
| [ toolchain.environment ] == selector.environment && |
| selector.environment + [ toolchain.base_environment ] - |
| [ toolchain.base_environment ] == selector.environment) { |
| selector_matches = false |
| } |
| } |
| if (selector.label != []) { |
| label = get_label_info(":$main_target_name", "label_no_toolchain") |
| if (selector.label + [ label ] - [ label ] == selector.label) { |
| selector_matches = false |
| } |
| } |
| if (selector.name != []) { |
| name = main_target_name |
| if (selector.name + [ name ] - [ name ] == selector.name) { |
| selector_matches = false |
| } |
| } |
| if (selector.os != []) { |
| if (selector.os + [ current_os ] - [ current_os ] == selector.os) { |
| selector_matches = false |
| } |
| } |
| if (selector.output_name != []) { |
| _output_name = main_target_name |
| if (defined(invoker.output_name)) { |
| _output_name = invoker.output_name |
| } |
| if (selector.output_name + [ _output_name ] - [ _output_name ] == |
| selector.output_name) { |
| selector_matches = false |
| } |
| } |
| if (selector.target_type != []) { |
| if (selector.target_type + [ invoker._type ] - [ invoker._type ] == |
| selector.target_type) { |
| selector_matches = false |
| } |
| } |
| if (defined(selector.host) && selector.host != is_host) { |
| selector_matches = false |
| } |
| if (defined(selector.kernel) && selector.kernel != is_kernel) { |
| selector_matches = false |
| } |
| |
| if (selector_matches && _builder_toolchain == false) { |
| _builder_toolchain = selector.toolchain |
| } |
| } |
| assert(_builder_toolchain != false) |
| |
| if (current_toolchain == _builder_toolchain) { |
| # In the builder toolchain... build. |
| group(main_target_name) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| |
| public_deps = [ |
| ":$binary_target_name", |
| ] |
| |
| deps = [ |
| ":$manifest_target_name", |
| ] |
| } |
| } else { |
| # In other toolchains, simply redirect to the builder toolchain. |
| group(main_target_name) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| |
| public_deps = [ |
| ":$main_target_name($_builder_toolchain)", |
| ] |
| } |
| } |
| |
| # Provide redirects to other variants in their own toolchains. |
| foreach(variant, toolchain.other_variants) { |
| variant_target_name = "$main_target_name${variant.suffix}" |
| group(variant_target_name) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| |
| public_deps = [ |
| ":$variant_target_name(${variant.label})", |
| ] |
| } |
| } |
| |
| # Provide a way to reference this variant explicitly. |
| # Note that this does not go through variant selection and therefore needs to |
| # depend on the exact version of the binary, meaning that the manifest also |
| # needs to depend on that exact version. |
| group("$main_target_name${toolchain.variant_suffix}") { |
| forward_variables_from(invoker, [ "testonly" ]) |
| |
| data_deps = [ |
| ":$binary_target_name${toolchain.variant_suffix}", |
| ] |
| |
| deps = [ |
| ":$manifest_target_name${toolchain.variant_suffix}", |
| ] |
| } |
| } |