| # Copyright 2022 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/clippy.gni") |
| import("//build/toolchain/rbe.gni") |
| |
| # Common logic for implementing the other rustc_* templates in this directory. |
| # Should not be called directly outside of //build/rust. |
| # |
| # Parameters |
| # |
| # target_type |
| # Name of the template or rule to wrap, as a string. |
| # |
| # crate_name |
| # Name of the crate as passed to rustc. All dashes will be replaced |
| # with underscores in the crate name: <name_underscored> |
| # |
| # crate_root |
| # Location of the crate root (e.g. `src/main.rs` or `src/lib.rs`). |
| # |
| # 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. |
| # |
| # 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. |
| # |
| # rustflags |
| # Extra rust compiler flags passed directly to rustc. |
| # |
| # 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"' |
| # |
| # 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) |
| # |
| # configs (optional) |
| # A list of config labels applying to this target. |
| # |
| # deps |
| # List of GN targets on which this crate depends. |
| # |
| # pass_through |
| # A scope of arguments to pass directly to the underlying wrapped target. |
| # Only the primary target generated will receive these arguments. |
| # |
| # metadata (optional) |
| # Metadata to apply to the primary wrapped target. |
| # |
| # 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. |
| # |
| # sources |
| # List of source files which this crate is allowed to compile. |
| # The Rust compiler discovers source files by following `mod` declarations |
| # starting at the `crate_root`. The discovered source files must match this |
| # list. |
| # |
| # disable_rbe (optional) |
| # Set to true to force this target to build locally, overriding the global |
| # `rust_rbe_enable`. |
| # |
| # disable_clippy (optional) |
| # Don't run clippy on this target. |
| # |
| # clippy_crate_type |
| # Usually GN handles this internally for rust targets, but we have to set it explicitly |
| # for targets that generate a corresponding clippy target so that clippy has access to it. |
| # See https://doc.rust-lang.org/reference/linkage.html for possible values |
| # |
| # original_target_name |
| # 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. |
| # |
| # testonly (optional) |
| # Standard GN meaning. Testonly option for the generated targets. |
| # |
| # visibility (optional) |
| # Standard GN meaning. The visibility option for the generated targets. |
| # |
| template("rustc_artifact") { |
| # rustc does not support dashes in crate names |
| _crate_name = string_replace(invoker.crate_name, "-", "_") |
| _crate_root = invoker.crate_root |
| |
| _remote_inputs = [] |
| if (defined(invoker.inputs)) { |
| _remote_inputs = invoker.inputs |
| } |
| _local_inputs = _remote_inputs |
| |
| # enable these features for the target |
| _rustflags = [] |
| if (defined(invoker.features)) { |
| foreach(i, invoker.features) { |
| _rustflags += [ "--cfg=feature=\"${i}\"" ] |
| } |
| } |
| if (defined(invoker.rustflags)) { |
| _rustflags += invoker.rustflags |
| } |
| |
| assert( |
| defined(invoker.edition), |
| "Rust targets must set an edition. For new rust targets use: `edition = \"2021\"`") |
| _configs = invoker.configs |
| _edition = invoker.edition |
| _configs += [ "//build/config/rust:edition_${_edition}" ] |
| |
| _target_name = "$target_name.actual" |
| _clippy_name = "$target_name.clippy" |
| |
| _disable_clippy = defined(invoker.disable_clippy) && invoker.disable_clippy |
| if (!_disable_clippy) { |
| clippy(_clippy_name) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "rustenv", |
| ]) |
| clippy_crate_type = invoker.clippy_crate_type |
| configs = _configs |
| crate_root = _crate_root |
| deps = invoker.deps |
| rustflags = _rustflags |
| sources = invoker.sources |
| } |
| } else { |
| if (defined(invoker.clippy_crate_type)) { |
| not_needed(invoker, [ "clippy_crate_type" ]) |
| } |
| if (defined(invoker.rustenv)) { |
| not_needed(invoker, [ "rustenv" ]) |
| } |
| not_needed([ "_clippy_name" ]) |
| } |
| |
| _use_rbe = rust_rbe_enable |
| if (defined(invoker.disable_rbe) && invoker.disable_rbe) { |
| _use_rbe = false |
| } |
| if (rust_rbe_enable && !_use_rbe) { |
| # Disable RBE for this target through a fake rustflag, |
| # that is intercepted by rustc-remote-wrapper.sh. |
| _rustflags += [ "--remote-disable" ] |
| } |
| if (_use_rbe) { |
| # Depend on Rust/RBE scripts and tools |
| _local_inputs += rust_rbe_deps |
| } |
| |
| # Every rust target is actually a group of both target_name.actual and |
| # optionally target_name.clippy (if include_clippy is set) |
| group(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| public_deps = [ ":$_target_name" ] |
| metadata = { |
| test_component_manifest_program_barrier = [ ":$_target_name" ] |
| link_output_barrier = [ ":$_target_name" ] |
| } |
| if (!_disable_clippy) { |
| _outputs = get_target_outputs(":$_clippy_name") |
| _original = get_label_info(":${invoker.original_target_name}", |
| "label_with_toolchain") |
| metadata.rust_source_map = [ |
| { |
| clippy = get_label_info(":$_clippy_name", "label_with_toolchain") |
| original = _original |
| output = rebase_path(_outputs[0], root_build_dir) |
| src = [] |
| foreach(s, invoker.sources) { |
| src += [ rebase_path(s, root_build_dir) ] |
| } |
| }, |
| ] |
| |
| if (include_clippy) { |
| data_deps = [ ":$_clippy_name" ] |
| } |
| } else { |
| not_needed(invoker, [ "original_target_name" ]) |
| } |
| } |
| |
| target(invoker.target_type, _target_name) { |
| crate_root = _crate_root |
| crate_name = _crate_name |
| |
| rustflags = [] |
| if (rust_rbe_enable) { |
| rustflags += |
| [ "--remote-flag=--label='" + |
| get_label_info(":$_target_name", "label_with_toolchain") + "'" ] |
| } |
| if (_use_rbe && _remote_inputs != []) { |
| # Signal to rustc-remote-wrapper.sh that there are additional |
| # inputs to upload. This flag is stripped away from the eventual |
| # rustc command. |
| rustflags += [ |
| "--remote-inputs", |
| string_join(",", rebase_path(_remote_inputs, root_build_dir)), |
| ] |
| } |
| rustflags += _rustflags |
| |
| configs = [] |
| configs = _configs |
| deps = invoker.deps |
| inputs = _local_inputs |
| |
| 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" ] |
| } |
| |
| rustenv = [] |
| if (defined(invoker.rustenv)) { |
| rustenv += invoker.rustenv |
| } |
| |
| # Clippy target is a gen dep if it's not included in the group |
| if (!_disable_clippy && !include_clippy) { |
| gen_deps = [ ":$_clippy_name" ] |
| } |
| |
| # _pass_through and not_needed are to workaround https://crbug.com/gn/10 |
| _pass_through = invoker.pass_through |
| assert(!defined(_pass_through.metadata)) |
| not_needed([ "_pass_through" ]) |
| |
| metadata = { |
| if (defined(invoker.metadata)) { |
| forward_variables_from(invoker.metadata, "*") |
| } |
| } |
| |
| # pass through these variables unmodified |
| forward_variables_from(invoker.pass_through, "*") |
| |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| } |
| } |