| # 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/host.gni") |
| import("//build/rust/rustc_binary.gni") |
| import("//build/sdk/sdk_atom.gni") |
| import("//src/developer/ffx/build/ffx_action.gni") |
| import("//src/developer/ffx/config.gni") |
| import("//src/developer/ffx/lib/version/build/ffx_apply_version.gni") |
| |
| # Defines an ffx-compatible subtool in the form of a rust binary target |
| # |
| # All parameters to `rustc_binary` are available, along with the additional |
| # parameters below. |
| # |
| # Additional Parameters |
| # |
| # sdk_target_name (optional) |
| # The target name to generate for an sdk atom definition. If not |
| # set, no sdk target will be generated. |
| # |
| # sdk_category (required if `sdk_target_name` is set) |
| # The sdk category this will be installed to. |
| # See `sdk_atom`'s `category` argument for more information. |
| # |
| # sdk_area (optional) |
| # [string] The API area responsible for maintaining this tool. |
| # See //build/sdk/sdk_atom.gni. |
| # |
| # sdk_deps (optional, ignored if `sdk_target_name` not set) |
| # Dependencies for inclusion in the sdk. See `sdk_atom` for more |
| # information on this. |
| # |
| # The following targets will be produced, in addition to any from `rustc_binary`: |
| # |
| # `<target_name>` |
| # The rust binary before applying build version information to it. |
| # Output: `<output_name>_unversioned` |
| # |
| # `<target_name>_versioned` |
| # The rust binary after applying build version information to it. |
| # Output: `<output_name>` |
| # |
| # `<target_name>_metadata` |
| # The json metadata for this tool that allows ffx to discover it |
| # and determine compatibility information. |
| # Output: `<output_name>.json` |
| # |
| # `<target_name>_host_tool` |
| # Installation of the versioned binary and metadata as a host tool. |
| # Output: `host-tools/<output_name>`, `host-tools/<output_name>.json` |
| # |
| # `<target_name>_test_data` |
| # A `host_test_data` target that includes the files necessary to make sure |
| # this tool is available to tests. |
| # |
| # The following target will be produced only if `sdk_target_name` is set: |
| # |
| # `<sdk_target_name>` |
| # Include the tool in the sdk as a host tool with metadata attached. |
| # Output: (see `sdk_atom` for more information) |
| # |
| template("ffx_tool") { |
| if (!defined(invoker.output_name)) { |
| output_name = target_name |
| } else { |
| output_name = invoker.output_name |
| } |
| |
| # targets that are part of the 'public interface' of ffx_tool |
| target_versioned = "${target_name}_versioned" |
| target_unversioned = target_name |
| target_metadata = "${target_name}_metadata" |
| target_host_tool = "${target_name}_host_tool" |
| target_test_data = "${target_name}_test_data" |
| |
| # targets that are part of the private interface of ffx_tool |
| # (prefixed with _ to differentiate). |
| target_versioned_bin = "_${target_name}_versioned_bin" |
| |
| output_versioned = output_name |
| output_unversioned = "${output_name}_unversioned" |
| output_metadata = "${output_name}.json" |
| |
| assert_no_deps = [] |
| if (defined(invoker.assert_no_deps)) { |
| assert_no_deps += invoker.assert_no_deps |
| } |
| |
| # TODO(b/314822328): improve this logic to cascade properly |
| if (defined(invoker.sdk_category) && invoker.sdk_category != "internal") { |
| assert_no_deps += [ |
| "//sdk:marker-cts", |
| "//sdk:marker-excluded", |
| "//sdk:marker-experimental", |
| "//sdk:marker-internal", |
| "//sdk:marker-unknown", |
| ] |
| } |
| |
| # Make the rust binary |
| rustc_binary(target_unversioned) { |
| output_name = output_unversioned |
| forward_variables_from(invoker, |
| "*", |
| [ |
| "output_name", |
| "sdk_target_name", |
| "sdk_category", |
| "sdk_area", |
| "sdk_deps", |
| "assert_no_deps", |
| ]) |
| } |
| |
| # Replace the special linker sections containing the version information with the real values |
| ffx_apply_version(target_versioned_bin) { |
| output_name = output_versioned |
| ffx_unversioned_binary_path = "${root_out_dir}/${output_unversioned}" |
| runtime_files = [ "$root_out_dir/$output_metadata" ] |
| deps = [ |
| ":$target_metadata", |
| ":$target_unversioned", |
| ] |
| } |
| |
| # Create the metadata file for in-tree discovery |
| ffx_action(target_metadata) { |
| # Use the unversion-stamped binary to generate the metadata file. The |
| # ffx_action() template will convert these names to the correct ones by |
| # adding the '_unversioned' suffix to the 'output_name'. |
| # |
| # This is the default, but it's set here for extra clarity. |
| use_versioned_binary = false |
| ffx_tool = ":$target_unversioned" |
| ffx_tool_output_name = output_versioned # without _unversioned suffix |
| |
| needs_sdk = false |
| inputs = [] |
| outputs = [ "$root_out_dir/$output_metadata" ] |
| args = [ |
| "metadata", |
| rebase_path("$root_out_dir/$output_metadata", root_build_dir), |
| ] |
| } |
| |
| # Combine those into a target that represents both the versioned binary |
| # and the metadata. |
| group(target_versioned) { |
| public_deps = [ |
| ":$target_metadata", |
| ":$target_versioned_bin", |
| ] |
| } |
| |
| # Install host tool |
| install_host_tools(target_host_tool) { |
| deps = [ ":$target_versioned" ] |
| outputs = [ |
| output_name, |
| output_metadata, |
| ] |
| } |
| |
| # Install host tool and metadata as test data |
| host_test_data(target_test_data) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| |
| data_deps = [ ":$target_host_tool" ] |
| sources = [ |
| "${host_tools_dir}/${output_metadata}", |
| "${host_tools_dir}/${output_name}", |
| ] |
| } |
| |
| if (defined(invoker.sdk_target_name)) { |
| # Add to the sdk |
| file_base_root = "tools/ffx_tools" |
| if (host_os == "linux" || host_os == "mac") { |
| file_base_root = "tools/$current_cpu/ffx_tools" |
| } |
| |
| file_base = "$file_base_root/$output_name" |
| file_base_metadata = "$file_base_root/$output_metadata" |
| |
| assert( |
| defined(invoker.sdk_category), |
| "Must specify an sdk category if generating an sdk target for ffx tool") |
| |
| # for the moment this goes directly to sdk_atom because this is a 'weird' |
| # host tool that includes a json metadata file. |
| sdk_atom(invoker.sdk_target_name) { |
| forward_variables_from(invoker, [ "sdk_area" ]) |
| |
| id = "sdk://$file_base" |
| |
| category = invoker.sdk_category |
| |
| _target_files = { |
| executable = file_base |
| executable_metadata = file_base_metadata |
| } |
| |
| meta = { |
| dest = "$file_base-meta.json" |
| schema = "ffx_tool" |
| sources = [ "//build/sdk/meta/host_tool.json" ] |
| value = { |
| type = "ffx_tool" |
| name = output_name |
| root = "tools" |
| files = { |
| } |
| target_files = { |
| } |
| if (current_cpu == "arm64") { |
| target_files.arm64 = _target_files |
| } else if (current_cpu == "x64") { |
| target_files.x64 = _target_files |
| } else if (current_cpu == "riscv64") { |
| target_files.riscv64 = _target_files |
| } else { |
| assert(false, "Unknown CPU type: $current_cpu") |
| } |
| } |
| } |
| |
| files = [ |
| { |
| source = "$root_out_dir/$output_versioned" |
| dest = file_base |
| }, |
| { |
| source = "$root_out_dir/$output_metadata" |
| dest = file_base_metadata |
| }, |
| ] |
| |
| if (defined(invoker.sdk_deps)) { |
| deps = invoker.sdk_deps |
| } |
| |
| non_sdk_deps = [ |
| ":$target_metadata", |
| ":$target_versioned", |
| ] |
| } |
| } |
| } |