diff --git a/src/lib.rs b/src/lib.rs index f2c419477..5b25cda89 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1598,6 +1598,12 @@ impl Build { self.assemble(lib_name, &dst.join(gnu_lib_name), &objects)?; let target = self.get_target()?; + if target.abi == "pauthtest" { + self.cargo_output.print_warning( + &"cc-rs should not be used with `pauthtest` target: it only builds \ + static libraries, while `pauthtest` requires shared objects.", + ); + } if target.env == "msvc" { let compiler = self.get_base_compiler()?; let atlmfc_lib = compiler @@ -1668,6 +1674,14 @@ impl Build { )); } } + // Pauthtest needs LLVM's libc++, libc++abi provided by the sysroot. + if target.abi == "pauthtest" { + let pauthtest_sysroot = self.pauthtest_sysroot()?; + self.cargo_output.print_metadata(&format_args!( + "cargo:rustc-flags=-L {}/lib -lc++ -lc++abi", + Path::new(&pauthtest_sysroot).display(), + )); + } } let cudart = match &self.cudart { @@ -2288,6 +2302,34 @@ impl Build { format!("--sysroot={}", Path::new(&musl_sysroot).display()).into(), ); cmd.push_cc_arg("-pthread".into()); + } else if target.abi == "pauthtest" { + let pauthtest_sysroot = self.pauthtest_sysroot()?; + let pauthtest_resource_dir = self.pauthtest_resource_dir()?; + cmd.push_cc_arg( + format!("--sysroot={}", Path::new(&pauthtest_sysroot).display()).into(), + ); + cmd.push_cc_arg( + format!( + "-resource-dir={}", + Path::new(&pauthtest_resource_dir).display() + ) + .into(), + ); + cmd.push_cc_arg("-march=armv8.3-a+pauth".into()); + if self.cpp && self.cpp_set_stdlib.is_none() { + cmd.push_cc_arg("-stdlib=libc++".into()); + cmd.push_cc_arg( + format!( + "-I{}/include/c++/v1", + Path::new(&pauthtest_sysroot).display() + ) + .into(), + ); + + cmd.push_cc_arg( + format!("-L{}/lib", Path::new(&pauthtest_sysroot).display()).into(), + ); + } } // Pass `--target` with the LLVM target to configure Clang for cross-compiling. // @@ -2965,7 +3007,7 @@ impl Build { // and many modern illumos distributions today ship GCC as "gcc" without // also making it available as "cc". Cow::Borrowed(Path::new(gnu)) - } else if self.prefer_clang() { + } else if self.prefer_clang() || target.abi == "pauthtest" { self.which(Path::new(clang), None) .map(Cow::Owned) .unwrap_or(fallback) @@ -3196,6 +3238,23 @@ impl Build { .print_warning(&"GNU compiler is not supported for this target"); } + if target.abi == "pauthtest" { + match tool.family { + ToolFamily::Clang { .. } => {} + _ => { + return Err(Error::new( + ErrorKind::ToolNotFound, + format!( + "target '{}' requires a Clang-based toolchain, but found {:?} ({})", + raw_target, + tool.family, + tool.path.display() + ), + )); + } + } + } + Ok(tool) } @@ -3313,6 +3372,7 @@ impl Build { || target.os == "aix" || (target.os == "linux" && target.env == "ohos") || target.os == "wasi" + || target.abi == "pauthtest" { Ok(Some(Cow::Borrowed(Path::new("c++")))) } else if target.os == "android" { @@ -4328,6 +4388,36 @@ impl Build { clang.into() } + + fn pauthtest_sysroot(&self) -> Result { + if let Some(pauthtest_sysroot) = self.get_env("PAUTHTEST_SYSROOT") { + Ok(pauthtest_sysroot) + } else { + let target = self.get_raw_target()?; + Err(Error::new( + ErrorKind::EnvVarNotFound, + format!( + "Environment variable PAUTHTEST_SYSROOT not defined for the {} target. Please consult target's platform support document for instructions on how to obtain the sysroot and then setup the environment variable PAUTHTEST_SYSROOT.", + target + ), + )) + } + } + + fn pauthtest_resource_dir(&self) -> Result { + if let Some(pauthtest_resource_dir) = self.get_env("PAUTHTEST_RESOURCE_DIR") { + Ok(pauthtest_resource_dir) + } else { + let target = self.get_raw_target()?; + Err(Error::new( + ErrorKind::EnvVarNotFound, + format!( + "Environment variable PAUTHTEST_RESOURCE_DIR not defined for the {} target. Please consult target's platform support document for instructions on how to obtain the sysroot and then setup the environment variable PAUTHTEST_RESOURCE_DIR.", + target + ), + )) + } + } } impl Default for Build { diff --git a/src/target/llvm.rs b/src/target/llvm.rs index cff099596..a3895e237 100644 --- a/src/target/llvm.rs +++ b/src/target/llvm.rs @@ -21,6 +21,13 @@ impl TargetInfo<'_> { if rustc_target == "armv7-apple-ios" { // FIXME(madsmtm): Unnecessary once we bump MSRV to Rust 1.74 return Cow::Borrowed("armv7-apple-ios"); + } else if rustc_target == "aarch64-unknown-linux-pauthtest" { + // `aarch64-unknown-linux-pauthtest` rustc target sets both + // environment and abi (to `musl` and `pauthtest` respectively`). + // However, the abi field exists mainly for `cfg(...)` evaluation in + // Rust, not for generating the actual LLVM triple. The logic of: + // `arch-vendor-os-env+abi` does not applay here. + return Cow::Borrowed("aarch64-unknown-linux-pauthtest"); } else if self.os == "uefi" { // Override the UEFI LLVM targets. // diff --git a/src/target/parser.rs b/src/target/parser.rs index c144beda7..0c94847a2 100644 --- a/src/target/parser.rs +++ b/src/target/parser.rs @@ -225,6 +225,7 @@ fn parse_envabi(last_component: &str) -> Option<(&str, &str)> { // Environments "msvc" => ("msvc", ""), "ohos" => ("ohos", ""), + "pauthtest" => ("musl", "pauthtest"), "qnx700" => ("nto70", ""), "qnx710_iosock" => ("nto71_iosock", ""), "qnx710" => ("nto71", ""),