| # 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. |
| # |
| # public_deps |
| # List of GN targets on which this crate depends publicly. |
| # |
| # 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`. |
| # |
| # link_args (optional) |
| # List of arguments to pass to the linker via "-Clink-args=...". |
| # |
| # disable_clippy (optional) |
| # Don't run clippy on this target. |
| # |
| # quiet_clippy (boolean, optional) |
| # Run clippy on this target, producing a JSON output but do not print the output or fail the |
| # target based on clippy's success. Intended for use when testing clippy itself, use in normal |
| # build targets will hide lint warnings from developers and tools while still paying the |
| # overhead of running clippy. |
| # |
| # 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. |
| # |
| # 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) |
| # |
| # applicable_licenses (optional) |
| # The usual GN meaning. |
| 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 |
| |
| # Compute the metadata used to uniquely identify this target within rustc. |
| # In particular, it is used as a key in the incremental cache to prevent |
| # builds of the same crate name from clobbering each others' cache entries. |
| # It is also used in symbol mangling. |
| # |
| # This is a space-separated list. |
| _codegen_metadata = |
| rebase_path(target_out_dir, root_build_dir) + " " + target_name |
| _rustflags = [ "-Cmetadata=${_codegen_metadata}" ] |
| |
| _flag_deps = [ "//build/rust:api_level_cfg_flags" ] |
| _flag_inputs = [ "$root_build_dir/rust_api_level_cfg_flags.txt" ] |
| _rustflags += [ "@rust_api_level_cfg_flags.txt" ] |
| |
| 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 = [] |
| if (defined(invoker.configs)) { |
| _configs += invoker.configs |
| } |
| _edition = invoker.edition |
| _configs += [ "//build/config/rust:edition_${_edition}" ] |
| |
| _group_name = target_name |
| _target_name = "$target_name.actual" |
| _clippy_name = "$target_name.clippy" |
| |
| _disable_clippy = defined(invoker.disable_clippy) && invoker.disable_clippy |
| if (!_disable_clippy) { |
| _quiet_clippy = defined(invoker.quiet_clippy) && invoker.quiet_clippy |
| clippy(_clippy_name) { |
| forward_variables_from(invoker, |
| [ |
| "applicable_licenses", |
| "testonly", |
| "rustenv", |
| "public_deps", |
| "visibility", |
| ]) |
| if (defined(visibility)) { |
| visibility += [ ":${_group_name}" ] |
| } |
| clippy_crate_type = invoker.clippy_crate_type |
| configs = _configs |
| crate_root = _crate_root |
| deps = invoker.deps + _flag_deps |
| rustflags = _rustflags |
| sources = invoker.sources |
| quiet = _quiet_clippy |
| |
| # Additional metadata to differentiate the clippy target from the actual target. |
| rustflags += [ "-Cmetadata=clippy" ] |
| } |
| } else { |
| if (defined(invoker.clippy_crate_type)) { |
| not_needed(invoker, [ "clippy_crate_type" ]) |
| } |
| if (defined(invoker.rustenv)) { |
| not_needed(invoker, [ "rustenv" ]) |
| } |
| if (defined(invoker.quiet_clippy)) { |
| not_needed(invoker, [ "quiet_clippy" ]) |
| } |
| 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(_group_name) { |
| forward_variables_from(invoker, |
| [ |
| "applicable_licenses", |
| "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 |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "public_deps", |
| ]) |
| inputs = _local_inputs + _flag_inputs |
| deps += _flag_deps |
| |
| if (!defined(invoker.enforce_source_listing) || |
| invoker.enforce_source_listing) { |
| # 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" ] |
| } |
| |
| if (defined(invoker.link_args)) { |
| foreach(link_arg, invoker.link_args) { |
| rustflags += [ "-Clink-args=" + link_arg ] |
| } |
| } |
| |
| 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, |
| [ |
| "applicable_licenses", |
| "assert_no_deps", |
| "pool", |
| "testonly", |
| "visibility", |
| ]) |
| if (defined(visibility)) { |
| visibility += [ ":${_group_name}" ] |
| } |
| } |
| } |