diff options
Diffstat (limited to 'src/tools/cargo/tests/testsuite/custom_target.rs')
-rw-r--r-- | src/tools/cargo/tests/testsuite/custom_target.rs | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/src/tools/cargo/tests/testsuite/custom_target.rs b/src/tools/cargo/tests/testsuite/custom_target.rs new file mode 100644 index 000000000..b7ad4d835 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/custom_target.rs @@ -0,0 +1,250 @@ +//! Tests for custom json target specifications. + +use cargo_test_support::{basic_manifest, project}; +use std::fs; + +const MINIMAL_LIB: &str = r#" +#![feature(no_core)] +#![feature(lang_items)] +#![no_core] + +#[lang = "sized"] +pub trait Sized { + // Empty. +} +#[lang = "copy"] +pub trait Copy { + // Empty. +} +"#; + +const SIMPLE_SPEC: &str = r#" +{ + "llvm-target": "x86_64-unknown-none-gnu", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "executables": true +} +"#; + +#[cargo_test(nightly, reason = "requires features no_core, lang_items")] +fn custom_target_minimal() { + let p = project() + .file( + "src/lib.rs", + &" + __MINIMAL_LIB__ + + pub fn foo() -> u32 { + 42 + } + " + .replace("__MINIMAL_LIB__", MINIMAL_LIB), + ) + .file("custom-target.json", SIMPLE_SPEC) + .build(); + + p.cargo("build --lib --target custom-target.json -v").run(); + p.cargo("build --lib --target src/../custom-target.json -v") + .run(); + + // Ensure that the correct style of flag is passed to --target with doc tests. + p.cargo("test --doc --target src/../custom-target.json -v -Zdoctest-xcompile") + .masquerade_as_nightly_cargo(&["doctest-xcompile", "no_core", "lang_items"]) + .with_stderr_contains("[RUNNING] `rustdoc [..]--target [..]foo/custom-target.json[..]") + .run(); +} + +#[cargo_test(nightly, reason = "requires features no_core, lang_items, auto_traits")] +fn custom_target_dependency() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.0.1" + authors = ["author@example.com"] + + [dependencies] + bar = { path = "bar" } + "#, + ) + .file( + "src/lib.rs", + r#" + #![feature(no_core)] + #![feature(lang_items)] + #![feature(auto_traits)] + #![no_core] + + extern crate bar; + + pub fn foo() -> u32 { + bar::bar() + } + + #[lang = "freeze"] + unsafe auto trait Freeze {} + "#, + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + .file( + "bar/src/lib.rs", + &" + __MINIMAL_LIB__ + + pub fn bar() -> u32 { + 42 + } + " + .replace("__MINIMAL_LIB__", MINIMAL_LIB), + ) + .file("custom-target.json", SIMPLE_SPEC) + .build(); + + p.cargo("build --lib --target custom-target.json -v").run(); +} + +#[cargo_test(nightly, reason = "requires features no_core, lang_items")] +fn custom_bin_target() { + let p = project() + .file( + "src/main.rs", + &" + #![no_main] + __MINIMAL_LIB__ + " + .replace("__MINIMAL_LIB__", MINIMAL_LIB), + ) + .file("custom-bin-target.json", SIMPLE_SPEC) + .build(); + + p.cargo("build --target custom-bin-target.json -v").run(); +} + +#[cargo_test(nightly, reason = "requires features no_core, lang_items")] +fn changing_spec_rebuilds() { + // Changing the .json file will trigger a rebuild. + let p = project() + .file( + "src/lib.rs", + &" + __MINIMAL_LIB__ + + pub fn foo() -> u32 { + 42 + } + " + .replace("__MINIMAL_LIB__", MINIMAL_LIB), + ) + .file("custom-target.json", SIMPLE_SPEC) + .build(); + + p.cargo("build --lib --target custom-target.json -v").run(); + p.cargo("build --lib --target custom-target.json -v") + .with_stderr( + "\ +[FRESH] foo [..] +[FINISHED] [..] +", + ) + .run(); + let spec_path = p.root().join("custom-target.json"); + let spec = fs::read_to_string(&spec_path).unwrap(); + // Some arbitrary change that I hope is safe. + let spec = spec.replace('{', "{\n\"vendor\": \"unknown\",\n"); + fs::write(&spec_path, spec).unwrap(); + p.cargo("build --lib --target custom-target.json -v") + .with_stderr( + "\ +[COMPILING] foo v0.0.1 [..] +[RUNNING] `rustc [..] +[FINISHED] [..] +", + ) + .run(); +} + +#[cargo_test(nightly, reason = "requires features no_core, lang_items")] +fn changing_spec_relearns_crate_types() { + // Changing the .json file will invalidate the cache of crate types. + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [lib] + crate-type = ["cdylib"] + "#, + ) + .file("src/lib.rs", MINIMAL_LIB) + .file("custom-target.json", SIMPLE_SPEC) + .build(); + + p.cargo("build --lib --target custom-target.json -v") + .with_status(101) + .with_stderr("error: cannot produce cdylib for `foo [..]") + .run(); + + // Enable dynamic linking. + let spec_path = p.root().join("custom-target.json"); + let spec = fs::read_to_string(&spec_path).unwrap(); + let spec = spec.replace('{', "{\n\"dynamic-linking\": true,\n"); + fs::write(&spec_path, spec).unwrap(); + + p.cargo("build --lib --target custom-target.json -v") + .with_stderr( + "\ +[COMPILING] foo [..] +[RUNNING] `rustc [..] +[FINISHED] [..] +", + ) + .run(); +} + +#[cargo_test(nightly, reason = "requires features no_core, lang_items")] +fn custom_target_ignores_filepath() { + // Changing the path of the .json file will not trigger a rebuild. + let p = project() + .file( + "src/lib.rs", + &" + __MINIMAL_LIB__ + + pub fn foo() -> u32 { + 42 + } + " + .replace("__MINIMAL_LIB__", MINIMAL_LIB), + ) + .file("b/custom-target.json", SIMPLE_SPEC) + .file("a/custom-target.json", SIMPLE_SPEC) + .build(); + + // Should build the library the first time. + p.cargo("build --lib --target a/custom-target.json") + .with_stderr( + "\ +[..]Compiling foo v0.0.1 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run(); + + // But not the second time, even though the path to the custom target is dfferent. + p.cargo("build --lib --target b/custom-target.json") + .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") + .run(); +} |