Skip to content

Commit

Permalink
Merge pull request #196 from daxpedda/pass-target
Browse files Browse the repository at this point in the history
Fix cross-compilation
  • Loading branch information
oli-obk authored Mar 20, 2024
2 parents b874810 + 50fcf47 commit 6a97ed6
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

* Passing `--target` to build command when cross-compiling.

### Changed

### Removed
Expand Down
5 changes: 5 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,11 @@ impl Config {
Ok(())
}

/// Check whether the host is the specified string
pub fn host_matches(&self, target: &str) -> bool {
self.host.as_ref().expect("host should have been filled in") == target
}

pub(crate) fn has_asm_support(&self) -> bool {
static ASM_SUPPORTED_ARCHS: &[&str] = &[
"x86", "x86_64", "arm", "aarch64", "riscv32",
Expand Down
57 changes: 49 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,18 +170,44 @@ pub fn default_any_file_filter(path: &Path, config: &Config) -> bool {

/// The default per-file config used by `run_tests`.
pub fn default_per_file_config(config: &mut Config, _path: &Path, file_contents: &[u8]) {
// Heuristic:
// * if the file contains `#[test]`, automatically pass `--cfg test`.
// * if the file does not contain `fn main()` or `#[start]`, automatically pass `--crate-type=lib`.
// This avoids having to spam `fn main() {}` in almost every test.
config.program.args.push(
match crate_type(file_contents) {
CrateType::ProcMacro => "--crate-type=proc-macro",
CrateType::Test => "--test",
CrateType::Bin => return,
CrateType::Lib => "--crate-type=lib",
}
.into(),
)
}

/// The kind of crate we're building here. Corresponds to `--crate-type` flags of rustc
pub enum CrateType {
/// A proc macro
ProcMacro,
/// A file containing unit tests
Test,
/// A binary file containing a main function or start function
Bin,
/// A library crate
Lib,
}

/// Heuristic:
/// * if the file contains `#[test]`, automatically pass `--cfg test`.
/// * if the file does not contain `fn main()` or `#[start]`, automatically pass `--crate-type=lib`.
/// This avoids having to spam `fn main() {}` in almost every test.
pub fn crate_type(file_contents: &[u8]) -> CrateType {
if file_contents.find(b"#[proc_macro").is_some() {
config.program.args.push("--crate-type=proc-macro".into())
CrateType::ProcMacro
} else if file_contents.find(b"#[test]").is_some() {
config.program.args.push("--test".into());
CrateType::Test
} else if file_contents.find(b"fn main()").is_none()
&& file_contents.find(b"#[start]").is_none()
{
config.program.args.push("--crate-type=lib".into());
CrateType::Lib
} else {
CrateType::Bin
}
}

Expand Down Expand Up @@ -520,6 +546,15 @@ fn build_command(
cmd.arg("--edition").arg(&*edition);
}

if let Some(target) = &config.target {
// Adding a `--target` arg to calls to Cargo will cause target folders
// to create a target-specific sub-folder. We can avoid that by just
// not passing a `--target` arg if its the same as the host.
if !config.host_matches(target) {
cmd.arg("--target").arg(target);
}
}

// False positive in miri, our `map` uses a ref pattern to get the references to the tuple fields instead
// of a reference to a tuple
#[allow(clippy::map_identity)]
Expand Down Expand Up @@ -574,6 +609,12 @@ fn build_aux(

default_per_file_config(&mut config, aux_file, &file_contents);

match crate_type(&file_contents) {
// Proc macros must be run on the host
CrateType::ProcMacro => config.target = config.host.clone(),
CrateType::Test | CrateType::Bin | CrateType::Lib => {}
}

// Put aux builds into a separate directory per path so that multiple aux files
// from different directories (but with the same file name) don't collide.
let relative = strip_path_prefix(aux_file.parent().unwrap(), &config.out_dir);
Expand Down Expand Up @@ -1281,7 +1322,7 @@ fn test_condition(condition: &Condition, config: &Config) -> bool {
Condition::Bitwidth(bits) => get_pointer_width(target) == *bits,
Condition::Target(t) => target.contains(t),
Condition::Host(t) => config.host.as_ref().unwrap().contains(t),
Condition::OnHost => target == config.host.as_ref().unwrap(),
Condition::OnHost => config.host_matches(target),
}
}

Expand Down
5 changes: 5 additions & 0 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ fn main() -> Result<()> {
config.filter("program not found", "No such file or directory");
config.filter(" \\(os error [0-9]+\\)", "");
config.filter("note: rustc 1\\..*", "");
// Cross compilation paths contain an additional target directory name
config.stderr_filter(
"(/target/ui/tests/integrations/[^/]+).*debug/deps",
"$1/debug/deps",
);

let text = ui_test::status_emitter::Text::from(args.format);

Expand Down
5 changes: 5 additions & 0 deletions tests/integrations/basic/tests/ui_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ fn main() -> ui_test::color_eyre::Result<()> {
config.stderr_filter(r"[^ ]*/\.?cargo/registry/.*/", "$$CARGO_REGISTRY");
config.path_stderr_filter(&std::path::Path::new(path), "$DIR");

if let Ok(target) = std::env::var("UITEST_TEST_TARGET") {
config.target = Some(target);
config.output_conflict_handling = OutputConflictHandling::Ignore;
}

// hide binaries generated for successfully passing tests
let tmp_dir = tempfile::tempdir_in(path)?;
let tmp_dir = tmp_dir.path();
Expand Down

0 comments on commit 6a97ed6

Please sign in to comment.