diff --git a/ctest/src/generator.rs b/ctest/src/generator.rs index 41cf6f0a691b7..a09f80fbc30d7 100644 --- a/ctest/src/generator.rs +++ b/ctest/src/generator.rs @@ -14,7 +14,7 @@ use crate::template::{CTestTemplate, RustTestTemplate}; use crate::translator::translate_primitive_type; use crate::{ Const, Field, MapInput, Parameter, Result, Static, Struct, TranslationError, Type, Union, - VolatileItemKind, expand, + VolatileItemKind, expand, get_build_target, }; /// A function that takes a mappable input and returns its mapping as `Some`, otherwise @@ -961,7 +961,7 @@ impl TestGenerator { crate_path: impl AsRef, output_file_path: impl AsRef, ) -> Result { - let expanded = expand(&crate_path, &self.cfg).map_err(|e| { + let expanded = expand(&crate_path, &self.cfg, get_build_target(self)?).map_err(|e| { GenerationError::MacroExpansion(crate_path.as_ref().to_path_buf(), e.to_string()) })?; let ast = syn::parse_file(&expanded) diff --git a/ctest/src/lib.rs b/ctest/src/lib.rs index 989ec5234b4c0..133b31e7fbf8d 100644 --- a/ctest/src/lib.rs +++ b/ctest/src/lib.rs @@ -20,12 +20,16 @@ mod runner; mod template; mod translator; +use std::env; + pub use ast::{Abi, Const, Field, Fn, Parameter, Static, Struct, Type, Union}; pub use generator::TestGenerator; pub use macro_expansion::expand; pub use runner::{__compile_test, __run_test, generate_test}; pub use translator::TranslationError; +use crate::generator::GenerationError; + /// A possible error that can be encountered in our library. pub type Error = Box; /// A type alias for `std::result::Result` that defaults to our error type. @@ -74,6 +78,23 @@ pub(crate) enum MapInput<'a> { UnionFieldType(&'a Union, &'a Field), } +/// Search for the target to build for, specified manually or through an environment variable. +/// +/// This function will check the following places for the target name: +/// - TestGenerator.target +/// - TARGET environment variable. +/// - TARGET_PLATFORM environment variable. +fn get_build_target(generator: &TestGenerator) -> Result { + generator + .target + .clone() + .or_else(|| env::var("TARGET").ok()) + .or_else(|| env::var("TARGET_PLATFORM").ok()) + .ok_or(GenerationError::EnvVarNotFound( + "TARGET, TARGET_PLATFORM".to_string(), + )) +} + /* The From impls make it easier to write code in the test templates. */ impl<'a> From<&'a Const> for MapInput<'a> { diff --git a/ctest/src/macro_expansion.rs b/ctest/src/macro_expansion.rs index d4209f48210b8..9c46e047e903e 100644 --- a/ctest/src/macro_expansion.rs +++ b/ctest/src/macro_expansion.rs @@ -6,7 +6,11 @@ use std::process::Command; use crate::{EDITION, Result}; /// Use rustc to expand all macros and pretty print the crate into a single file. -pub fn expand>(crate_path: P, cfg: &[(String, Option)]) -> Result { +pub fn expand>( + crate_path: P, + cfg: &[(String, Option)], + target: String, +) -> Result { let rustc = env::var("RUSTC").unwrap_or_else(|_| String::from("rustc")); let mut cmd = Command::new(rustc); @@ -16,6 +20,10 @@ pub fn expand>(crate_path: P, cfg: &[(String, Option)]) - .arg(EDITION) // By default, -Zunpretty=expanded uses 2015 edition. .arg(canonicalize(crate_path)?); + if !target.is_empty() { + cmd.arg("--target").arg(target); + } + // `libc` uses non standard cfg flags as well, which have to be manually expanded. for (k, v) in cfg { match v { diff --git a/ctest/src/runner.rs b/ctest/src/runner.rs index 0bfb56826af2b..9d2430345d17a 100644 --- a/ctest/src/runner.rs +++ b/ctest/src/runner.rs @@ -7,7 +7,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use crate::generator::GenerationError; -use crate::{EDITION, Result, TestGenerator}; +use crate::{EDITION, Result, TestGenerator, get_build_target}; /// Generate all tests for the given crate and output the Rust side to a file. #[doc(hidden)] @@ -18,17 +18,7 @@ pub fn generate_test( ) -> Result { let output_file_path = generator.generate_files(crate_path, output_file_path)?; - // Search for the target and host to build for if specified manually - // (generator.target, generator.host), - // via build script (TARGET, HOST), or for internal testing (TARGET_PLATFORM, HOST_PLATFORM). - let target = generator - .target - .clone() - .or_else(|| env::var("TARGET").ok()) - .or_else(|| env::var("TARGET_PLATFORM").ok()) - .ok_or(GenerationError::EnvVarNotFound( - "TARGET, TARGET_PLATFORM".to_string(), - ))?; + let target = get_build_target(generator)?; let host = env::var("HOST") .or_else(|_| env::var("HOST_PLATFORM")) .map_err(|_| GenerationError::EnvVarNotFound("HOST, HOST_PLATFORM".to_string()))?;