summaryrefslogtreecommitdiffstats
path: root/src/tools/cargo/tests/testsuite/build_script_extra_link_arg.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/cargo/tests/testsuite/build_script_extra_link_arg.rs')
-rw-r--r--src/tools/cargo/tests/testsuite/build_script_extra_link_arg.rs376
1 files changed, 376 insertions, 0 deletions
diff --git a/src/tools/cargo/tests/testsuite/build_script_extra_link_arg.rs b/src/tools/cargo/tests/testsuite/build_script_extra_link_arg.rs
new file mode 100644
index 000000000..ade262fec
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/build_script_extra_link_arg.rs
@@ -0,0 +1,376 @@
+//! Tests for additional link arguments.
+
+// NOTE: Many of these tests use `without_status()` when passing bogus flags
+// because MSVC link.exe just gives a warning on unknown flags (how helpful!),
+// and other linkers will return an error.
+
+use cargo_test_support::registry::Package;
+use cargo_test_support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, project};
+
+#[cargo_test]
+fn build_script_extra_link_arg_bin() {
+ let p = project()
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/main.rs", "fn main() {}")
+ .file(
+ "build.rs",
+ r#"
+ fn main() {
+ println!("cargo:rustc-link-arg-bins=--this-is-a-bogus-flag");
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("build -v")
+ .without_status()
+ .with_stderr_contains(
+ "[RUNNING] `rustc --crate-name foo [..]-C link-arg=--this-is-a-bogus-flag[..]",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_script_extra_link_arg_bin_single() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+
+ name = "foobar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [[bin]]
+ name = "foo"
+ [[bin]]
+ name = "bar"
+ "#,
+ )
+ .file("src/main.rs", "fn main() {}")
+ .file(
+ "build.rs",
+ r#"
+ fn main() {
+ println!("cargo:rustc-link-arg-bins=--bogus-flag-all");
+ println!("cargo:rustc-link-arg-bin=foo=--bogus-flag-foo");
+ println!("cargo:rustc-link-arg-bin=bar=--bogus-flag-bar");
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("build -v")
+ .without_status()
+ .with_stderr_contains(
+ "[RUNNING] `rustc --crate-name foo [..]-C link-arg=--bogus-flag-all -C link-arg=--bogus-flag-foo[..]",
+ )
+ .with_stderr_contains(
+ "[RUNNING] `rustc --crate-name bar [..]-C link-arg=--bogus-flag-all -C link-arg=--bogus-flag-bar[..]",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_script_extra_link_arg() {
+ let p = project()
+ .file("Cargo.toml", &basic_bin_manifest("foo"))
+ .file("src/main.rs", "fn main() {}")
+ .file(
+ "build.rs",
+ r#"
+ fn main() {
+ println!("cargo:rustc-link-arg=--this-is-a-bogus-flag");
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("build -v")
+ .without_status()
+ .with_stderr_contains(
+ "[RUNNING] `rustc --crate-name foo [..]-C link-arg=--this-is-a-bogus-flag[..]",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn link_arg_missing_target() {
+ // Errors when a given target doesn't exist.
+ let p = project()
+ .file("src/lib.rs", "")
+ .file(
+ "build.rs",
+ r#"fn main() { println!("cargo:rustc-link-arg-cdylib=--bogus"); }"#,
+ )
+ .build();
+
+ // TODO: Uncomment this if cdylib restriction is re-added (see
+ // cdylib_link_arg_transitive below).
+ // p.cargo("check")
+ // .with_status(101)
+ // .with_stderr("\
+ // [COMPILING] foo [..]
+ // error: invalid instruction `cargo:rustc-link-arg-cdylib` from build script of `foo v0.0.1 ([ROOT]/foo)`
+ // The package foo v0.0.1 ([ROOT]/foo) does not have a cdylib target.
+ // ")
+ // .run();
+
+ p.change_file(
+ "build.rs",
+ r#"fn main() { println!("cargo:rustc-link-arg-bins=--bogus"); }"#,
+ );
+
+ p.cargo("check")
+ .with_status(101)
+ .with_stderr("\
+[COMPILING] foo [..]
+error: invalid instruction `cargo:rustc-link-arg-bins` from build script of `foo v0.0.1 ([ROOT]/foo)`
+The package foo v0.0.1 ([ROOT]/foo) does not have a bin target.
+")
+ .run();
+
+ p.change_file(
+ "build.rs",
+ r#"fn main() { println!("cargo:rustc-link-arg-bin=abc=--bogus"); }"#,
+ );
+
+ p.cargo("check")
+ .with_status(101)
+ .with_stderr(
+ "\
+[COMPILING] foo [..]
+error: invalid instruction `cargo:rustc-link-arg-bin` from build script of `foo v0.0.1 ([ROOT]/foo)`
+The package foo v0.0.1 ([ROOT]/foo) does not have a bin target with the name `abc`.
+",
+ )
+ .run();
+
+ p.change_file(
+ "build.rs",
+ r#"fn main() { println!("cargo:rustc-link-arg-bin=abc"); }"#,
+ );
+
+ p.cargo("check")
+ .with_status(101)
+ .with_stderr(
+ "\
+[COMPILING] foo [..]
+error: invalid instruction `cargo:rustc-link-arg-bin=abc` from build script of `foo v0.0.1 ([ROOT]/foo)`
+The instruction should have the form cargo:rustc-link-arg-bin=BIN=ARG
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn cdylib_link_arg_transitive() {
+ // There was an unintended regression in 1.50 where rustc-link-arg-cdylib
+ // arguments from dependencies were being applied in the parent package.
+ // Previously it was silently ignored.
+ // See https://github.com/rust-lang/cargo/issues/9562
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [lib]
+ crate-type = ["cdylib"]
+
+ [dependencies]
+ bar = {path="bar"}
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("bar/Cargo.toml", &basic_manifest("bar", "1.0.0"))
+ .file("bar/src/lib.rs", "")
+ .file(
+ "bar/build.rs",
+ r#"
+ fn main() {
+ println!("cargo:rustc-link-arg-cdylib=--bogus");
+ }
+ "#,
+ )
+ .build();
+ p.cargo("build -v")
+ .without_status()
+ .with_stderr_contains(
+ "\
+[COMPILING] bar v1.0.0 [..]
+[RUNNING] `rustc --crate-name build_script_build bar/build.rs [..]
+[RUNNING] `[..]build-script-build[..]
+warning: cargo:rustc-link-arg-cdylib was specified in the build script of bar v1.0.0 \
+([ROOT]/foo/bar), but that package does not contain a cdylib target
+
+Allowing this was an unintended change in the 1.50 release, and may become an error in \
+the future. For more information, see <https://github.com/rust-lang/cargo/issues/9562>.
+[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]
+[COMPILING] foo v0.1.0 [..]
+[RUNNING] `rustc --crate-name foo src/lib.rs [..]-C link-arg=--bogus[..]`
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn link_arg_transitive_not_allowed() {
+ // Verify that transitive dependencies don't pass link args.
+ //
+ // Note that rustc-link-arg doesn't have any errors or warnings when it is
+ // unused. Perhaps that could be more aggressive, but it is difficult
+ // since it could be used for test binaries.
+ Package::new("bar", "1.0.0")
+ .file("src/lib.rs", "")
+ .file(
+ "build.rs",
+ r#"
+ fn main() {
+ println!("cargo:rustc-link-arg=--bogus");
+ }
+ "#,
+ )
+ .publish();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [lib]
+ crate-type = ["cdylib"]
+
+ [dependencies]
+ bar = "1.0"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("build -v")
+ .with_stderr(
+ "\
+[UPDATING] [..]
+[DOWNLOADING] [..]
+[DOWNLOADED] [..]
+[COMPILING] bar v1.0.0
+[RUNNING] `rustc --crate-name build_script_build [..]
+[RUNNING] `[..]/build-script-build[..]
+[RUNNING] `rustc --crate-name bar [..]
+[COMPILING] foo v0.1.0 [..]
+[RUNNING] `rustc --crate-name foo src/lib.rs [..]
+[FINISHED] dev [..]
+",
+ )
+ .with_stderr_does_not_contain("--bogus")
+ .run();
+}
+
+#[cargo_test]
+fn link_arg_with_doctest() {
+ let p = project()
+ .file(
+ "src/lib.rs",
+ r#"
+ //! ```
+ //! let x = 5;
+ //! assert_eq!(x, 5);
+ //! ```
+ "#,
+ )
+ .file(
+ "build.rs",
+ r#"
+ fn main() {
+ println!("cargo:rustc-link-arg=--this-is-a-bogus-flag");
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("test --doc -v")
+ .without_status()
+ .with_stderr_contains(
+ "[RUNNING] `rustdoc [..]--crate-name foo [..]-C link-arg=--this-is-a-bogus-flag[..]",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_script_extra_link_arg_tests() {
+ let p = project()
+ .file("Cargo.toml", &basic_lib_manifest("foo"))
+ .file("src/lib.rs", "")
+ .file("tests/test_foo.rs", "")
+ .file(
+ "build.rs",
+ r#"
+ fn main() {
+ println!("cargo:rustc-link-arg-tests=--this-is-a-bogus-flag");
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("test -v")
+ .without_status()
+ .with_stderr_contains(
+ "[RUNNING] `rustc --crate-name test_foo [..]-C link-arg=--this-is-a-bogus-flag[..]",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_script_extra_link_arg_benches() {
+ let p = project()
+ .file("Cargo.toml", &basic_lib_manifest("foo"))
+ .file("src/lib.rs", "")
+ .file("benches/bench_foo.rs", "")
+ .file(
+ "build.rs",
+ r#"
+ fn main() {
+ println!("cargo:rustc-link-arg-benches=--this-is-a-bogus-flag");
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("bench -v")
+ .without_status()
+ .with_stderr_contains(
+ "[RUNNING] `rustc --crate-name bench_foo [..]-C link-arg=--this-is-a-bogus-flag[..]",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_script_extra_link_arg_examples() {
+ let p = project()
+ .file("Cargo.toml", &basic_lib_manifest("foo"))
+ .file("src/lib.rs", "")
+ .file("examples/example_foo.rs", "fn main() {}")
+ .file(
+ "build.rs",
+ r#"
+ fn main() {
+ println!("cargo:rustc-link-arg-examples=--this-is-a-bogus-flag");
+ }
+ "#,
+ )
+ .build();
+
+ p.cargo("build -v --examples")
+ .without_status()
+ .with_stderr_contains(
+ "[RUNNING] `rustc --crate-name example_foo [..]-C link-arg=--this-is-a-bogus-flag[..]",
+ )
+ .run();
+}