| # 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("//build/components/fuchsia_package.gni") |
| import("//build/dist/distribution_manifest.gni") |
| |
| # Produce a package that collects all binaries entries produced by packages |
| # declared in deps, into a new package. |
| # |
| # There are two ways of contributing to a shell_commands package: |
| # 1. Preferred: using the `shell_command()` template below. |
| # 2. Legacy: using the `package()` template by specifying `shell = true`. |
| # |
| # The generated package doesn't include any actual binaries, but rather |
| # "trampolines" that launch these binaries from other packages. |
| # This allows putting a shell_commands package in base, such that it cannot be |
| # updated at runtime, while updating the packages that include the actual |
| # binaries. |
| # |
| # Paramters |
| # |
| # package_name (optional) |
| # Default: target_name |
| # |
| # deps (optional) |
| # testonly (optional) |
| # visibility (optional) |
| # Usual GN meanings. |
| template("shell_commands") { |
| # Collect all shell binaries. |
| shell_binary_entries_target = "${target_name}_shell_binary_entries" |
| shell_binary_entries = "$target_out_dir/$shell_binary_entries_target" |
| generated_file(shell_binary_entries_target) { |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "testonly", |
| ]) |
| visibility = [ ":*" ] |
| |
| # This contract is known to package.gni. |
| data_keys = [ |
| "shell_binary_entries", |
| "shell_binary_entries_files", |
| ] |
| walk_keys = [ "shell_binary_barrier" ] |
| outputs = [ shell_binary_entries ] |
| output_conversion = "json" |
| metadata = { |
| # Don't pick up resources from deps |
| distribution_entries_barrier = [] |
| } |
| } |
| |
| # Expose the distribution manifest to the shell commands package. |
| distribution_entries_target = "${target_name}_distribution_entries_file" |
| distribution_entries_file(distribution_entries_target) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| visibility = [ ":*" ] |
| deps = [ ":$shell_binary_entries_target" ] |
| file = shell_binary_entries |
| } |
| |
| fuchsia_package(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "package_name", |
| "testonly", |
| "visibility", |
| ]) |
| deps = [ ":$distribution_entries_target" ] |
| metadata = { |
| shell_binary_barrier = [] |
| } |
| } |
| } |
| |
| # Wrap binaries as shell commands. |
| # |
| # Any binaries produced by `deps` will be available in the shell, and can be |
| # launched for instance with `fx shell`. |
| # |
| # Binaries will be available in the shell by their intrinsic names. |
| # For instance, if you defined: |
| # |
| # executable("foo") { ... } |
| # |
| # Then adding ":foo" to your deps will result in the binary "foo" being |
| # available in the shell. |
| # To rename binaries, change their intrinsic name. For instance: |
| # |
| # executable("foo") { |
| # output_name = "bar" |
| # } |
| # |
| # Parameters |
| # |
| # package_name (required) |
| # The name of a package that the binary is included in. |
| # |
| # deps (required) |
| # One or more targets that package files into `bin/`. |
| # |
| # testonly |
| # visibility |
| template("shell_command") { |
| assert(defined(invoker.package_name), "Must specify package_name") |
| assert(defined(invoker.deps), "Must specify deps") |
| |
| # Collect all distribution entries from deps. |
| distribution_manifest_target = "${target_name}_distribution_manifest" |
| distribution_manifest = "$target_out_dir/$distribution_manifest_target" |
| distribution_manifest(distribution_manifest_target) { |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "testonly", |
| ]) |
| visibility = [ ":*" ] |
| outputs = [ distribution_manifest ] |
| } |
| |
| # Generate shebang files for each `bin/` entry, |
| # then create distribution entries for the generated shebang files. |
| output = "$target_out_dir/${target_name}_resolve_files" |
| depfile = "$target_out_dir/$target_name.d" |
| action(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "testonly", |
| "visibility", |
| ]) |
| script = "//build/images/shell_commands.py" |
| inputs = [ distribution_manifest ] |
| outputs = [ output ] |
| args = [ |
| "--package-name", |
| invoker.package_name, |
| "--input-distribution-manifest", |
| rebase_path(distribution_manifest, root_build_dir), |
| "--output-directory", |
| rebase_path(target_gen_dir, root_build_dir), |
| "--output-distribution-manifest", |
| rebase_path(output, root_build_dir), |
| "--depfile", |
| rebase_path(depfile, root_build_dir), |
| ] |
| depfile = depfile |
| if (!defined(invoker.deps)) { |
| deps = [] |
| } |
| deps += [ ":$distribution_manifest_target" ] |
| metadata = { |
| shell_binary_entries_files = [ |
| { |
| file = rebase_path(output, root_build_dir) |
| label = get_label_info(":$target_name", "label_with_toolchain") |
| }, |
| ] |
| } |
| } |
| } |