| # 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_test.gni") | |
| # Defines a Rust binary | |
| # | |
| # Parameters | |
| # | |
| # output_name (optional) | |
| # name (optional, deprecated) | |
| # Name of the crate as defined in its manifest file. If not specified, it is | |
| # assumed to be the same as the target name. All dashes will be replaced | |
| # with underscores in the binary name: <name_underscored> | |
| # | |
| # 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 (optional) | |
| # Edition of the Rust language to be used. | |
| # Options are "2015" and "2018". Defaults to "2018". | |
| # | |
| # 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_rust_deps (optional) | |
| # List of non-rust_library GN targets on which this crate depends. | |
| # | |
| # with_unit_tests (optional) | |
| # Builds unit tests associated with the binary. This will create a | |
| # `<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. | |
| # | |
| # 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 and mac tests, with a default value of a general linux/mac | |
| # environment (as a function of $current_os). | |
| # 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). | |
| # | |
| # force_opt (optional) | |
| # Force a particular optimization level for this target (even when building in debug mode). | |
| # Values include 0-3, s, or z. This does not change the optimization level of dependencies, | |
| # so consider combining with LTO for best results. | |
| # | |
| # 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' | |
| # | |
| # Example of usage: | |
| # | |
| # rustc_binary("foo-bar") { | |
| # deps = [ | |
| # "//garnet/public/rust/bar", | |
| # "//third_party/rust_crates:clap", | |
| # "//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") { | |
| # TODO(bwb) remove all versions from the callers | |
| # this is a hold-over. It's just noise right now. | |
| not_needed(invoker, [ "version" ]) | |
| # TODO soft-migration | |
| not_needed(invoker, [ "with_lto" ]) | |
| # 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.") | |
| package_name = target_name | |
| if (defined(invoker.output_name)) { | |
| package_name = invoker.output_name | |
| } else if (defined(invoker.name)) { | |
| package_name = invoker.name | |
| } | |
| # if "with_unit_tests" is set to true, generate an additional rust test target | |
| # TODO(bwb) deprecate this. All tests should be declared independently | |
| if (defined(invoker.with_unit_tests) && invoker.with_unit_tests == true) { | |
| rustc_test("${target_name}_test") { | |
| output_name = "${package_name}_bin_test" | |
| 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, | |
| "*", | |
| [ | |
| # Do not forward configs otherwise the defaults | |
| # for rustc_test get clobbered. | |
| "configs", | |
| "name", | |
| "output_name", | |
| "source_root", | |
| ]) | |
| } | |
| } | |
| ### 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 | |
| } | |
| # built-in gn rules do not support dashes | |
| crate_name = string_replace(package_name, "-", "_") | |
| # enable these features for the target | |
| features = [] | |
| if (defined(invoker.features)) { | |
| foreach(i, invoker.features) { | |
| features += [ "--cfg=feature=\"${i}\"" ] | |
| } | |
| } | |
| _sources = [] | |
| _deps = [] | |
| if (!defined(invoker.enforce_source_listing) || | |
| invoker.enforce_source_listing == true) { | |
| # fail early when the user forgets to list sources | |
| assert(defined(invoker.sources), "sources must be listed") | |
| _sources = invoker.sources | |
| } else { | |
| not_needed(invoker, [ "sources" ]) | |
| # This is a hack to workaround the fact that a GN `tool` invocation can't receive arbitrary input. | |
| # Add a sentinel value so that enforcement is skipped. | |
| _sources = [ "//build/rust/__SKIP_ENFORCEMENT__.rs" ] | |
| # Opting out of strict sources check requires that the package is present | |
| # in a global allow-list. | |
| _deps += [ "//build/rust:disable_strict_sources_check_allowlist" ] | |
| } | |
| executable(target_name) { | |
| crate_root = source_root | |
| output_name = crate_name | |
| crate_name = crate_name | |
| rustflags = features | |
| configs = [] | |
| configs = invoker.configs | |
| deps = _deps | |
| if (defined(invoker.deps)) { | |
| deps += invoker.deps | |
| } | |
| # TODO(bwb) remove "non_rust_deps" as a concept | |
| if (defined(invoker.non_rust_deps)) { | |
| deps += invoker.non_rust_deps | |
| } | |
| sources = _sources | |
| # in-tree default in 2018 edition | |
| if (defined(invoker.edition) && invoker.edition == "2015") { | |
| configs -= [ "//build/config:rust_edition_2018" ] | |
| configs += [ "//build/config:rust_edition_2015" ] | |
| } | |
| # some binary targets override the optimization level | |
| if (defined(invoker.force_opt)) { | |
| if (invoker.force_opt == "z") { | |
| configs += [ "//build/config:rust_opt_level_z" ] | |
| } | |
| } | |
| # pass through these variables unmodified | |
| forward_variables_from(invoker, | |
| [ | |
| "testonly", | |
| "visibility", | |
| "output_dir", | |
| "output_extension", | |
| "inputs", | |
| ]) | |
| } | |
| } |