| # Copyright 2018 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/rust/rustc_artifact.gni") | |
| import("//build/rust/rustc_test.gni") | |
| import("//build/toolchain/rbe.gni") | |
| # Defines a Rust binary | |
| # | |
| # Parameters | |
| # | |
| # output_name (optional) | |
| # Name of the output file. Also used as the crate name of the binary, | |
| # except the crate name has dashes replaced with underscores. If not | |
| # specified, it defaults to the target name. | |
| # | |
| # name (optional, deprecated) | |
| # Deprecated version of output_name. | |
| # | |
| # output_dir (optional) | |
| # Directory that the resulting binary should be placed in. | |
| # See: `gn help output_dir` | |
| # | |
| # output_extension (optional) | |
| # The file extension for the binary. | |
| # See: `gn help output_extension` | |
| # | |
| # version (optional) | |
| # Semver version of the crate as seen on crates.io. | |
| # | |
| # edition | |
| # Edition of the Rust language to be used. See | |
| # https://doc.rust-lang.org/edition-guide/editions/index.html for more info on rust editions. | |
| # | |
| # configs (optional) | |
| # A list of config labels applying to this target. | |
| # | |
| # enforce_source_listing (optional) | |
| # When true, enforces that any source files used by the Rust compiler are | |
| # listed in `sources`. Defaults to true. | |
| # | |
| # sources (optional) | |
| # List of source files which this crate is allowed to compile. Only | |
| # allowed when `enforce_source_listing = true`. | |
| # The Rust compiler discovers source files by following `mod` declarations | |
| # starting at the `source_root`. The discovered source files must match this | |
| # list. | |
| # | |
| # inputs (optional) | |
| # List of additional non-source files read by the compiler. These are typically | |
| # configuration or test-data files included in the build with the `include_str!` | |
| # macro. Only allowed when `enforce_source_listing = true`. | |
| # | |
| # deps (optional) | |
| # List of rust_library GN targets on which this crate depends. | |
| # Third party crates can be included through paths like | |
| # "//third_party/rust_crates:<cratename>", | |
| # | |
| # test_deps (optional) | |
| # List of rust_library GN targets on which this crate's tests depend. | |
| # | |
| # non_test_deps (optional) | |
| # List of rust_library GN targets on which this crate depends but not its | |
| # tests. This can be used to replace a dependency between the test and | |
| # library targets. It's an error to provide this when with_unit_tests is | |
| # false. | |
| # | |
| # non_rust_deps (optional) | |
| # List of non-rust_library GN targets on which this crate depends. | |
| # Obsolete. Please use deps instead. | |
| # | |
| # data_deps (optional) | |
| # List of GN targets that are only needed at runtime. | |
| # | |
| # with_unit_tests (optional) | |
| # Builds unit tests associated with the binary. This will create a | |
| # `<output_name_underscored>_bin_test` test file in the output directory, | |
| # and a new GN target called <name>_test. | |
| # Equivalent to adding a `rustc_test` target with that name and the same | |
| # source_root. | |
| # Accepts a boolean or one of the following strings: | |
| # "host": only define the test target in host toolchains (is_host). | |
| # "fuchsia": only define the test target in Fuchsia toolchains | |
| # (is_fuchsia). | |
| # "both": define the test target in host and Fuchsia toolchains | |
| # (is_host || is_fuchsia). | |
| # `true` defines the test target in all toolchains. | |
| # | |
| # test_args (optional) | |
| # List of flags to pass directly to the test binary, e.g. | |
| # ["--nocapture"]. | |
| # | |
| # test_environments (optional) | |
| # What environments unit tests, if provided, should target. Only used here | |
| # for linux host tests, with a default value of a general linux | |
| # environment. | |
| # See environments parameter //build/testing/test_spec.gni for more | |
| # details. | |
| # | |
| # sdk_category (optional) | |
| # If this field is set, this rust binary will be included in SDK builds for | |
| # the provided category. See //build/sdk/sdk_atom.gni for available | |
| # categories. | |
| # | |
| # source_root (optional) | |
| # Location of the crate root (e.g. `src/main.rs` or `src/lib.rs`). | |
| # This defaults to `./src/main.rs` for binaries and `./src/lib.rs` for libraries, | |
| # and should only be changed when absolutely necessary | |
| # (such as in the case of generated code). | |
| # | |
| # features (optional) | |
| # A list of conditional compilation flags to enable. This can be used to set features for crates | |
| # built in-tree which are also published to crates.io. This would be passed to rustc as | |
| # '--cfg feature="XXX"' | |
| # | |
| # check_cfgs (optional) | |
| # A list of valid configurations for the target. | |
| # Passed to rustc as '--check-cfg=cfg(###)'. | |
| # Not specifying or using an empty list disables configuration checking. | |
| # See https://doc.rust-lang.org/nightly/rustc/check-cfg.html for the syntax. | |
| # | |
| # rustenv (optional) | |
| # A list of environment variables that will be set when running the rust | |
| # compiler. These can be accessed at compile time with | |
| # [`std::env!`](https://doc.rust-lang.org/stable/std/macro.env.html) | |
| # | |
| # disable_rbe (optional) | |
| # Set to true to force this target to build locally, overriding the global | |
| # `rust_rbe_enable`. This applies to the unit-test as well, unless | |
| # `test_disable_rbe` is specified. | |
| # | |
| # test_disable_rbe (optional) | |
| # Set to true to build only the unit-test locally. | |
| # | |
| # disable_clippy (optional) | |
| # Don't run clippy on this target. | |
| # | |
| # emit_tool_path (optional) | |
| # Exclude this target from tool_paths.json. | |
| # | |
| # quiet_clippy (boolean, optional) | |
| # Passed through to rustc_artifact(), see that template for documentation. | |
| # | |
| # disable_rustdoc (optional) | |
| # Don't add this target to https://fuchsia.dev/go/rustdoc | |
| # NOTE: for binaries this is enabled by default | |
| # | |
| # original_target_name (optional) | |
| # The name of the target as it appears in the BUILD file. Enables tooling | |
| # to find the template invocation in a BUILD file where this target was defined. | |
| # | |
| # exclude_toolchain_tags (optional) | |
| # List of toolchain or variant tags to exclude this target from. This can be | |
| # useful if the target is incompatible with a certain toolchain or variant. | |
| # See build/toolchain/toolchain_tags.gni and build/toolchain/variant_tags.gni | |
| # for a list of common tags. | |
| # | |
| # link_args (optional) | |
| # List of arguments to pass to the linker via "-Clink-args=...". | |
| # | |
| # assert_no_deps (optional) | |
| # Ensure no deps on these targets, see [assert_no_deps](https://gn.googlesource.com/gn/+/main/docs/reference.md#var_assert_no_deps) | |
| # | |
| # The following fields are only used by Bazel-converted targets. | |
| # See //build/tools/bazel2gn/README.md for details. | |
| # | |
| # proc_macro_deps (optional) | |
| # For proc_macro dependencies, has the same semantics as deps in GN, | |
| # except that these are always built in `$host_toolchain`, since | |
| # procedural macros run as compiler plugins on the build machine. | |
| # Entries must not specify a toolchain. | |
| # | |
| # link_deps (optional) | |
| # Native (e.g. C/C++) libraries to link against, has the same semantics | |
| # as deps in GN. | |
| # | |
| # Example of usage: | |
| # | |
| # rustc_binary("foo-bar") { | |
| # deps = [ | |
| # "//garnet/public/rust/bar", | |
| # "//third_party/rust_crates:argh", | |
| # "//third_party/rust_crates:serde", | |
| # "//third_party/rust_crates:slab", | |
| # ] | |
| # with_unit_tests = true | |
| # sources = [ "src/main.rs" ] | |
| # } | |
| # | |
| # Example of using the outputs of the above: | |
| # | |
| # package("foo") { | |
| # deps = [ | |
| # ":foo-bar", | |
| # ] | |
| # | |
| # binaries = [ | |
| # { | |
| # name = "foo_bar" | |
| # dest = "foo-bar" | |
| # } | |
| # } | |
| # | |
| # test_package("foo-bar-tests") { | |
| # deps = [ | |
| # ":foo-bar_test", | |
| # ] | |
| # | |
| # tests = [ | |
| # { | |
| # name = "foo_bar_bin_test" | |
| # } | |
| # ] | |
| # | |
| template("rustc_binary") { | |
| not_needed(invoker, [ "version" ]) | |
| # If I delete this block, GN complains about pool being unused, | |
| # even though the generated ninja files look correct. | |
| if (defined(invoker.pool)) { | |
| assert(invoker.pool != "") | |
| } | |
| if (defined(invoker.original_target_name)) { | |
| _original_target_name = invoker.original_target_name | |
| } else { | |
| _original_target_name = target_name | |
| } | |
| # use the target name unless another name is specified | |
| assert(!(defined(invoker.output_name) && defined(invoker.name)), | |
| "Only one of output_name and name may be specified.") | |
| _output_name = target_name | |
| if (defined(invoker.output_name)) { | |
| _output_name = invoker.output_name | |
| } else if (defined(invoker.name)) { | |
| _output_name = invoker.name | |
| } | |
| if (defined(invoker.crate_name)) { | |
| _crate_name = invoker.crate_name | |
| } else { | |
| _crate_name = _output_name | |
| } | |
| # rustc does not support dashes in crate names | |
| _crate_name = string_replace(_crate_name, "-", "_") | |
| deps = [] | |
| if (defined(invoker.deps)) { | |
| deps += invoker.deps | |
| } | |
| # Resolve `with_unit_tests`, which may be a boolean or one of "host", | |
| # "fuchsia", or "both". See https://fxbug.dev/515405864. | |
| # | |
| # _with_unit_tests: whether unit tests are requested in any toolchain. | |
| # _generate_unit_tests: whether to define the test target in this toolchain. | |
| _with_unit_tests = false | |
| _generate_unit_tests = false | |
| if (defined(invoker.with_unit_tests)) { | |
| _with_unit_tests_value = invoker.with_unit_tests | |
| if (_with_unit_tests_value == true) { | |
| # Legacy boolean: define the test target in all toolchains. | |
| _with_unit_tests = true | |
| _generate_unit_tests = true | |
| } else if (_with_unit_tests_value == "both") { | |
| _with_unit_tests = true | |
| _generate_unit_tests = is_host || is_fuchsia | |
| } else if (_with_unit_tests_value == "host") { | |
| _with_unit_tests = true | |
| _generate_unit_tests = is_host | |
| } else if (_with_unit_tests_value == "fuchsia") { | |
| _with_unit_tests = true | |
| _generate_unit_tests = is_fuchsia | |
| } else { | |
| assert(_with_unit_tests_value == false, | |
| "with_unit_tests must be a boolean or one of \"host\", " + | |
| "\"fuchsia\", \"both\", got: ${_with_unit_tests_value}") | |
| } | |
| } | |
| # If requested for the current toolchain, generate an additional rust test | |
| # target. | |
| if (_generate_unit_tests) { | |
| rustc_test_internal("${target_name}_test") { | |
| output_name = "${_output_name}_bin_test" | |
| original_target_name = target_name | |
| if (defined(invoker.test_args)) { | |
| args = invoker.test_args | |
| } | |
| configs = [] | |
| configs = invoker.configs | |
| # rustc_test defaults to assuming the input is a binary. | |
| # specify the source_root here to avoid this. | |
| source_root = "src/main.rs" | |
| if (defined(invoker.source_root)) { | |
| source_root = invoker.source_root | |
| } | |
| forward_variables_from(invoker, | |
| "*", | |
| [ | |
| "crate_name", | |
| "name", | |
| "disable_rustdoc", | |
| "define_rustdoc_test_override", | |
| "assert_no_deps", | |
| "link_args", | |
| "output_name", | |
| "source_root", | |
| "test_disable_rbe", | |
| "non_test_deps", | |
| "validations", | |
| ]) | |
| if (defined(invoker.test_disable_rbe)) { | |
| disable_rbe = invoker.test_disable_rbe | |
| } | |
| } | |
| } else if (_with_unit_tests) { | |
| # Unit tests are requested, but not for the current toolchain. | |
| not_needed(invoker, | |
| [ | |
| "package_deps", | |
| "test_args", | |
| "test_build_only", | |
| "test_configs", | |
| "test_deps", | |
| "test_disable_rbe", | |
| "test_environments", | |
| "test_vars", | |
| ]) | |
| } | |
| ### Shim that converts rustc_binary to a default GN executable pattern ### | |
| # default location for rust binaries | |
| source_root = "src/main.rs" | |
| if (defined(invoker.source_root)) { | |
| source_root = invoker.source_root | |
| } | |
| rustc_artifact(target_name) { | |
| forward_variables_from(invoker, | |
| [ | |
| "allow_legacy_edition", | |
| "applicable_licenses", | |
| "assert_no_deps", | |
| "check_cfgs", | |
| "data_deps", | |
| "disable_clippy", | |
| "edition", | |
| "emit_tool_path", | |
| "enforce_source_listing", | |
| "exclude_toolchain_tags", | |
| "features", | |
| "inputs", | |
| "link_args", | |
| "link_deps", | |
| "lint_config", | |
| "output_dir", | |
| "output_extension", | |
| "pool", | |
| "proc_macro_deps", | |
| "quiet_clippy", | |
| "rustenv", | |
| "rustflags", | |
| "sources", | |
| "testonly", | |
| "validations", | |
| "visibility", | |
| "define_rustdoc_test_override", | |
| ]) | |
| target_type = "executable" | |
| crate_root = source_root | |
| crate_type = "bin" | |
| crate_name = _crate_name | |
| original_target_name = _original_target_name | |
| output_name = _output_name | |
| disable_rbe = !rust_rbe_enable | |
| if (defined(invoker.disable_rbe)) { | |
| disable_rbe = invoker.disable_rbe | |
| } | |
| inputs = [] | |
| if (defined(invoker.inputs)) { | |
| inputs = invoker.inputs | |
| } | |
| configs = [] | |
| configs = invoker.configs | |
| # Unstripped binaries can be massive compared to stripped binaries. | |
| # When skipping downloads, artifacts can be retrieved from RBE later using | |
| # `build/rbe/dlwrap.py --download ...`. | |
| if (!disable_rbe && !rust_rbe_download_unstripped_binaries) { | |
| configs += [ "//build/config/rust:no_download" ] | |
| } | |
| if (defined(invoker.non_test_deps)) { | |
| assert(_with_unit_tests, "use deps if not generating unit tests") | |
| deps += invoker.non_test_deps | |
| } | |
| # TODO(https://fxbug.dev/42120123) remove "non_rust_deps" as a concept | |
| if (defined(invoker.non_rust_deps)) { | |
| deps += invoker.non_rust_deps | |
| } | |
| metadata = { | |
| if (defined(invoker.disable_rustdoc)) { | |
| disable_rustdoc = [ invoker.disable_rustdoc ] | |
| } else { | |
| disable_rustdoc = [ true ] | |
| } | |
| } | |
| } | |
| } |