0

[rust] Use rustc --print=cfg to emulate CARGO_CFG_TARGET_... env.

Before this CL we were trying to simulate Cargo behavior in
`rust/run_build_script.py` and the results were inaccurate and didn't
match Cargo (e.g. https://crbug.com/401427004 reported that
`CARGO_CFG_TARGET_ARCH` was set to `i686` instead of `x86`).

After this CL we instead run `rustc --print=cfg` to tell us all the
`target_foo` properties.  This matches `rustc` and `cargo` behavior.

Fixed: 401427004
Fixed: 364904747
Change-Id: I4ce8b0a988fa951974fdbf21f896a3ff9375f50d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6336767
Reviewed-by: Collin Baker <collinbaker@chromium.org>
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1430501}
This commit is contained in:
Lukasz Anforowicz
2025-03-10 14:47:39 -07:00
committed by Chromium LUCI CQ
parent 2e2c8e9e68
commit 7f88e1cb99
6 changed files with 79 additions and 48 deletions
build/rust

@ -449,20 +449,6 @@ template("cargo_crate") {
cargo_target_abi,
]
}
if (current_cpu == "arm64" || current_cpu == "x64" ||
current_cpu == "loong64" || current_cpu == "riscv64") {
args += [
"--pointer-width",
"64",
]
} else if (current_cpu == "arm" || current_cpu == "x86") {
args += [
"--pointer-width",
"32",
]
} else {
assert(false, "Architecture not supported")
}
if (defined(invoker.features)) {
args += [ "--features" ]
args += invoker.features

@ -62,6 +62,30 @@ def host_triple(rustc_path):
return known_vars["host"]
def set_cargo_cfg_target_env_variables(rustc_path, env):
""" Sets CARGO_CFG_TARGET_... based on output from rustc. """
target_triple = env["TARGET"]
assert target_triple
# TODO(lukasza): Check if command-line flags other `--target` may affect the
# output of `--print-cfg`. If so, then consider also passing extra `args`
# (derived from `rustflags` maybe?).
args = [rustc_path, "--print=cfg", f"--target={target_triple}"]
proc = subprocess.Popen(args, stdout=subprocess.PIPE)
for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"):
line = line.strip()
if "=" not in line: continue
key, value = line.split("=")
if key.startswith("target_"):
key = "CARGO_CFG_" + key.upper()
value = value.strip('"')
if key in env:
env[key] = env[key] + f",{value}"
else:
env[key] = value
# Before 1.77, the format was `cargo:rustc-cfg=`. As of 1.77 the format is now
# `cargo::rustc-cfg=`.
RUSTC_CFG_LINE = re.compile("cargo::?rustc-cfg=(.*)")
@ -77,7 +101,6 @@ def main():
help='where to write output rustc flags')
parser.add_argument('--target', help='rust target triple')
parser.add_argument('--target-abi', help='rust target_abi')
parser.add_argument('--pointer-width', help='rust target pointer width')
parser.add_argument('--features', help='features', nargs='+')
parser.add_argument('--env', help='environment variable', nargs='+')
parser.add_argument('--rustflags',
@ -108,43 +131,11 @@ def main():
env["OUT_DIR"] = tempdir
env["CARGO_MANIFEST_DIR"] = os.path.abspath(args.src_dir)
env["HOST"] = host_triple(rustc_path)
env["CARGO_CFG_TARGET_POINTER_WIDTH"] = args.pointer_width
if args.target is None:
env["TARGET"] = env["HOST"]
else:
env["TARGET"] = args.target
target_components = env["TARGET"].split("-")
if len(target_components) == 2:
env["CARGO_CFG_TARGET_ARCH"] = target_components[0]
env["CARGO_CFG_TARGET_VENDOR"] = ''
env["CARGO_CFG_TARGET_OS"] = target_components[1]
env["CARGO_CFG_TARGET_ENV"] = ''
elif len(target_components) == 3:
env["CARGO_CFG_TARGET_ARCH"] = target_components[0]
env["CARGO_CFG_TARGET_VENDOR"] = target_components[1]
env["CARGO_CFG_TARGET_OS"] = target_components[2]
env["CARGO_CFG_TARGET_ENV"] = ''
elif len(target_components) == 4:
env["CARGO_CFG_TARGET_ARCH"] = target_components[0]
env["CARGO_CFG_TARGET_VENDOR"] = target_components[1]
env["CARGO_CFG_TARGET_OS"] = target_components[2]
env["CARGO_CFG_TARGET_ENV"] = target_components[3]
else:
print(f'Invalid TARGET {env["TARGET"]}')
sys.exit(1)
# See https://crbug.com/325543500 for background.
# Cargo sets CARGO_CFG_TARGET_OS to "android" even when targeting
# *-androideabi.
if env["CARGO_CFG_TARGET_OS"].startswith("android"):
env["CARGO_CFG_TARGET_OS"] = "android"
elif env["CARGO_CFG_TARGET_OS"] == "darwin":
env["CARGO_CFG_TARGET_OS"] = "macos"
env["CARGO_CFG_TARGET_ENDIAN"] = "little"
if env["CARGO_CFG_TARGET_OS"] == "windows":
env["CARGO_CFG_TARGET_FAMILY"] = "windows"
else:
env["CARGO_CFG_TARGET_FAMILY"] = "unix"
env["CARGO_CFG_TARGET_ABI"] = args.target_abi if args.target_abi else ""
set_cargo_cfg_target_env_variables(rustc_path, env)
if args.features:
for f in args.features:
feature_name = f.upper().replace("-", "_")

@ -45,6 +45,15 @@ group("deps") {
#"test_rs_bindings_from_cc:test_rs_bindings_from_cc",
]
if (target_cpu == "x86") {
# Some `target_os`s do not support 32-bit platforms anymore. The
# selection below is _loosely_ based on `is_valid_x86_target` from
# the top-level `//BUILD.gn`.
if (is_win || is_android) {
deps += [ "//build/rust/tests/test_build_rs_target_arch_x86" ]
}
}
if (!(is_apple && is_official_build)) {
# TODO: crbug.com/372055517 - Apple lld has an ordering dependency bug
# when LTO is enabled, and this particular build target runs into that.

@ -0,0 +1,14 @@
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/rust/cargo_crate.gni")
cargo_crate("test_build_rs_target_arch_x86") {
crate_name = "test_build_rs_target_arch_x86"
crate_root = "lib.rs"
sources = [ "lib.rs" ]
build_sources = [ "build.rs" ]
build_root = "build.rs"
epoch = "0.1"
}

@ -0,0 +1,25 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::env;
// This is a regression test against https://crbug.com/401427004 which
// reported that Chromium's build infrastructure (`run_build_script.py`)
// sets `CARGO_CFG_TARGET_ARCH` environment variable incorrectly.
fn main() {
println!("cargo:rustc-cfg=build_script_ran");
// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
// documents how `CARGO_CFG_TARGET_ARCH` should be set.
let target = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
// https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch lists the
// following example values: "x86", "x86_64", "mips", "powerpc", "powerpc64",
// "arm", "aarch64".
//
// Before https://crbug.com/401427004 was fixed `run_build_script.py` would incorrectly
// take the first component of a target triple (e.g. `i686` from
// `i686-pc-windows-msvc`) and set that as `CARGO_CFG_TARGET_ARCH`.
assert_eq!(target, "x86");
}

@ -0,0 +1,6 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Empty `lib.rs` file - the real test is whether `build.rs` gets the expected
// `CARGO_CFG_TARGET_ARCH` value (it will panic otherwise).