|  | # 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 | 
|  | # | 
|  | #   name | 
|  | #     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> | 
|  | # | 
|  | #   version (optional) | 
|  | #     Semver version of the crate as seen on crates.io. | 
|  | # | 
|  | #   edition | 
|  | #     Edition of the Rust language to be used. | 
|  | #     Options are "2015" and "2018". If unsure, choose "2018". | 
|  | # | 
|  | #   configs (optional) | 
|  | #     A list of config labels applying to this target. | 
|  | # | 
|  | #   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_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 | 
|  | #   } | 
|  | # | 
|  | # 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" ]) | 
|  |  | 
|  | # 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") { | 
|  | name = invoker.target_name + "_bin_test" | 
|  | if (defined(invoker.name)) { | 
|  | name = invoker.name + "_bin_test" | 
|  | } | 
|  |  | 
|  | 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, | 
|  | "*", | 
|  | [ | 
|  | "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 | 
|  | } | 
|  |  | 
|  | # use the target name unless another name is specified | 
|  | package_name = target_name | 
|  | if (defined(invoker.name)) { | 
|  | package_name = invoker.name | 
|  | } | 
|  |  | 
|  | # 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}\"" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | executable(target_name) { | 
|  | crate_root = source_root | 
|  | output_name = crate_name | 
|  | crate_name = crate_name | 
|  | rustflags = features | 
|  |  | 
|  | configs = [] | 
|  | configs = invoker.configs | 
|  |  | 
|  | 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 | 
|  | } | 
|  |  | 
|  | # 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", | 
|  | ]) | 
|  | } | 
|  | } |