]>
Commit | Line | Data |
---|---|---|
0a29b90c FG |
1 | //! Tests for additional link arguments. |
2 | ||
3 | // NOTE: Many of these tests use `without_status()` when passing bogus flags | |
4 | // because MSVC link.exe just gives a warning on unknown flags (how helpful!), | |
5 | // and other linkers will return an error. | |
6 | ||
7 | use cargo_test_support::registry::Package; | |
8 | use cargo_test_support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, project}; | |
9 | ||
10 | #[cargo_test] | |
11 | fn build_script_extra_link_arg_bin() { | |
12 | let p = project() | |
13 | .file("Cargo.toml", &basic_bin_manifest("foo")) | |
14 | .file("src/main.rs", "fn main() {}") | |
15 | .file( | |
16 | "build.rs", | |
17 | r#" | |
18 | fn main() { | |
19 | println!("cargo:rustc-link-arg-bins=--this-is-a-bogus-flag"); | |
20 | } | |
21 | "#, | |
22 | ) | |
23 | .build(); | |
24 | ||
25 | p.cargo("build -v") | |
26 | .without_status() | |
27 | .with_stderr_contains( | |
28 | "[RUNNING] `rustc --crate-name foo [..]-C link-arg=--this-is-a-bogus-flag[..]", | |
29 | ) | |
30 | .run(); | |
31 | } | |
32 | ||
33 | #[cargo_test] | |
34 | fn build_script_extra_link_arg_bin_single() { | |
35 | let p = project() | |
36 | .file( | |
37 | "Cargo.toml", | |
38 | r#" | |
39 | [package] | |
40 | ||
41 | name = "foobar" | |
42 | version = "0.5.0" | |
43 | authors = ["wycats@example.com"] | |
44 | ||
45 | [[bin]] | |
46 | name = "foo" | |
47 | [[bin]] | |
48 | name = "bar" | |
49 | "#, | |
50 | ) | |
51 | .file("src/main.rs", "fn main() {}") | |
52 | .file( | |
53 | "build.rs", | |
54 | r#" | |
55 | fn main() { | |
56 | println!("cargo:rustc-link-arg-bins=--bogus-flag-all"); | |
57 | println!("cargo:rustc-link-arg-bin=foo=--bogus-flag-foo"); | |
58 | println!("cargo:rustc-link-arg-bin=bar=--bogus-flag-bar"); | |
59 | } | |
60 | "#, | |
61 | ) | |
62 | .build(); | |
63 | ||
64 | p.cargo("build -v") | |
65 | .without_status() | |
66 | .with_stderr_contains( | |
67 | "[RUNNING] `rustc --crate-name foo [..]-C link-arg=--bogus-flag-all -C link-arg=--bogus-flag-foo[..]", | |
68 | ) | |
69 | .with_stderr_contains( | |
70 | "[RUNNING] `rustc --crate-name bar [..]-C link-arg=--bogus-flag-all -C link-arg=--bogus-flag-bar[..]", | |
71 | ) | |
72 | .run(); | |
73 | } | |
74 | ||
75 | #[cargo_test] | |
76 | fn build_script_extra_link_arg() { | |
77 | let p = project() | |
78 | .file("Cargo.toml", &basic_bin_manifest("foo")) | |
79 | .file("src/main.rs", "fn main() {}") | |
80 | .file( | |
81 | "build.rs", | |
82 | r#" | |
83 | fn main() { | |
84 | println!("cargo:rustc-link-arg=--this-is-a-bogus-flag"); | |
85 | } | |
86 | "#, | |
87 | ) | |
88 | .build(); | |
89 | ||
90 | p.cargo("build -v") | |
91 | .without_status() | |
92 | .with_stderr_contains( | |
93 | "[RUNNING] `rustc --crate-name foo [..]-C link-arg=--this-is-a-bogus-flag[..]", | |
94 | ) | |
95 | .run(); | |
96 | } | |
97 | ||
98 | #[cargo_test] | |
99 | fn link_arg_missing_target() { | |
100 | // Errors when a given target doesn't exist. | |
101 | let p = project() | |
102 | .file("src/lib.rs", "") | |
103 | .file( | |
104 | "build.rs", | |
105 | r#"fn main() { println!("cargo:rustc-link-arg-cdylib=--bogus"); }"#, | |
106 | ) | |
107 | .build(); | |
108 | ||
109 | // TODO: Uncomment this if cdylib restriction is re-added (see | |
110 | // cdylib_link_arg_transitive below). | |
111 | // p.cargo("check") | |
112 | // .with_status(101) | |
113 | // .with_stderr("\ | |
114 | // [COMPILING] foo [..] | |
115 | // error: invalid instruction `cargo:rustc-link-arg-cdylib` from build script of `foo v0.0.1 ([ROOT]/foo)` | |
116 | // The package foo v0.0.1 ([ROOT]/foo) does not have a cdylib target. | |
117 | // ") | |
118 | // .run(); | |
119 | ||
120 | p.change_file( | |
121 | "build.rs", | |
122 | r#"fn main() { println!("cargo:rustc-link-arg-bins=--bogus"); }"#, | |
123 | ); | |
124 | ||
125 | p.cargo("check") | |
126 | .with_status(101) | |
127 | .with_stderr("\ | |
128 | [COMPILING] foo [..] | |
129 | error: invalid instruction `cargo:rustc-link-arg-bins` from build script of `foo v0.0.1 ([ROOT]/foo)` | |
130 | The package foo v0.0.1 ([ROOT]/foo) does not have a bin target. | |
131 | ") | |
132 | .run(); | |
133 | ||
134 | p.change_file( | |
135 | "build.rs", | |
136 | r#"fn main() { println!("cargo:rustc-link-arg-bin=abc=--bogus"); }"#, | |
137 | ); | |
138 | ||
139 | p.cargo("check") | |
140 | .with_status(101) | |
141 | .with_stderr( | |
142 | "\ | |
143 | [COMPILING] foo [..] | |
144 | error: invalid instruction `cargo:rustc-link-arg-bin` from build script of `foo v0.0.1 ([ROOT]/foo)` | |
145 | The package foo v0.0.1 ([ROOT]/foo) does not have a bin target with the name `abc`. | |
146 | ", | |
147 | ) | |
148 | .run(); | |
149 | ||
150 | p.change_file( | |
151 | "build.rs", | |
152 | r#"fn main() { println!("cargo:rustc-link-arg-bin=abc"); }"#, | |
153 | ); | |
154 | ||
155 | p.cargo("check") | |
156 | .with_status(101) | |
157 | .with_stderr( | |
158 | "\ | |
159 | [COMPILING] foo [..] | |
160 | error: invalid instruction `cargo:rustc-link-arg-bin=abc` from build script of `foo v0.0.1 ([ROOT]/foo)` | |
161 | The instruction should have the form cargo:rustc-link-arg-bin=BIN=ARG | |
162 | ", | |
163 | ) | |
164 | .run(); | |
165 | } | |
166 | ||
167 | #[cargo_test] | |
168 | fn cdylib_link_arg_transitive() { | |
169 | // There was an unintended regression in 1.50 where rustc-link-arg-cdylib | |
170 | // arguments from dependencies were being applied in the parent package. | |
171 | // Previously it was silently ignored. | |
172 | // See https://github.com/rust-lang/cargo/issues/9562 | |
173 | let p = project() | |
174 | .file( | |
175 | "Cargo.toml", | |
176 | r#" | |
177 | [package] | |
178 | name = "foo" | |
179 | version = "0.1.0" | |
180 | ||
181 | [lib] | |
182 | crate-type = ["cdylib"] | |
183 | ||
184 | [dependencies] | |
185 | bar = {path="bar"} | |
186 | "#, | |
187 | ) | |
188 | .file("src/lib.rs", "") | |
189 | .file("bar/Cargo.toml", &basic_manifest("bar", "1.0.0")) | |
190 | .file("bar/src/lib.rs", "") | |
191 | .file( | |
192 | "bar/build.rs", | |
193 | r#" | |
194 | fn main() { | |
195 | println!("cargo:rustc-link-arg-cdylib=--bogus"); | |
196 | } | |
197 | "#, | |
198 | ) | |
199 | .build(); | |
200 | p.cargo("build -v") | |
201 | .without_status() | |
202 | .with_stderr_contains( | |
203 | "\ | |
204 | [COMPILING] bar v1.0.0 [..] | |
205 | [RUNNING] `rustc --crate-name build_script_build bar/build.rs [..] | |
206 | [RUNNING] `[..]build-script-build[..] | |
ed00b5ec | 207 | warning: bar@1.0.0: cargo:rustc-link-arg-cdylib was specified in the build script of bar v1.0.0 \ |
0a29b90c FG |
208 | ([ROOT]/foo/bar), but that package does not contain a cdylib target |
209 | ||
210 | Allowing this was an unintended change in the 1.50 release, and may become an error in \ | |
211 | the future. For more information, see <https://github.com/rust-lang/cargo/issues/9562>. | |
212 | [RUNNING] `rustc --crate-name bar bar/src/lib.rs [..] | |
213 | [COMPILING] foo v0.1.0 [..] | |
214 | [RUNNING] `rustc --crate-name foo src/lib.rs [..]-C link-arg=--bogus[..]` | |
215 | ", | |
216 | ) | |
217 | .run(); | |
218 | } | |
219 | ||
220 | #[cargo_test] | |
221 | fn link_arg_transitive_not_allowed() { | |
222 | // Verify that transitive dependencies don't pass link args. | |
223 | // | |
224 | // Note that rustc-link-arg doesn't have any errors or warnings when it is | |
225 | // unused. Perhaps that could be more aggressive, but it is difficult | |
226 | // since it could be used for test binaries. | |
227 | Package::new("bar", "1.0.0") | |
228 | .file("src/lib.rs", "") | |
229 | .file( | |
230 | "build.rs", | |
231 | r#" | |
232 | fn main() { | |
233 | println!("cargo:rustc-link-arg=--bogus"); | |
234 | } | |
235 | "#, | |
236 | ) | |
237 | .publish(); | |
238 | ||
239 | let p = project() | |
240 | .file( | |
241 | "Cargo.toml", | |
242 | r#" | |
243 | [package] | |
244 | name = "foo" | |
245 | version = "0.1.0" | |
246 | ||
247 | [lib] | |
248 | crate-type = ["cdylib"] | |
249 | ||
250 | [dependencies] | |
251 | bar = "1.0" | |
252 | "#, | |
253 | ) | |
254 | .file("src/lib.rs", "") | |
255 | .build(); | |
256 | ||
257 | p.cargo("build -v") | |
258 | .with_stderr( | |
259 | "\ | |
260 | [UPDATING] [..] | |
261 | [DOWNLOADING] [..] | |
262 | [DOWNLOADED] [..] | |
263 | [COMPILING] bar v1.0.0 | |
264 | [RUNNING] `rustc --crate-name build_script_build [..] | |
265 | [RUNNING] `[..]/build-script-build[..] | |
266 | [RUNNING] `rustc --crate-name bar [..] | |
267 | [COMPILING] foo v0.1.0 [..] | |
268 | [RUNNING] `rustc --crate-name foo src/lib.rs [..] | |
269 | [FINISHED] dev [..] | |
270 | ", | |
271 | ) | |
272 | .with_stderr_does_not_contain("--bogus") | |
273 | .run(); | |
274 | } | |
275 | ||
276 | #[cargo_test] | |
277 | fn link_arg_with_doctest() { | |
278 | let p = project() | |
279 | .file( | |
280 | "src/lib.rs", | |
281 | r#" | |
282 | //! ``` | |
283 | //! let x = 5; | |
284 | //! assert_eq!(x, 5); | |
285 | //! ``` | |
286 | "#, | |
287 | ) | |
288 | .file( | |
289 | "build.rs", | |
290 | r#" | |
291 | fn main() { | |
292 | println!("cargo:rustc-link-arg=--this-is-a-bogus-flag"); | |
293 | } | |
294 | "#, | |
295 | ) | |
296 | .build(); | |
297 | ||
298 | p.cargo("test --doc -v") | |
299 | .without_status() | |
300 | .with_stderr_contains( | |
301 | "[RUNNING] `rustdoc [..]--crate-name foo [..]-C link-arg=--this-is-a-bogus-flag[..]", | |
302 | ) | |
303 | .run(); | |
304 | } | |
305 | ||
306 | #[cargo_test] | |
307 | fn build_script_extra_link_arg_tests() { | |
308 | let p = project() | |
309 | .file("Cargo.toml", &basic_lib_manifest("foo")) | |
310 | .file("src/lib.rs", "") | |
311 | .file("tests/test_foo.rs", "") | |
312 | .file( | |
313 | "build.rs", | |
314 | r#" | |
315 | fn main() { | |
316 | println!("cargo:rustc-link-arg-tests=--this-is-a-bogus-flag"); | |
317 | } | |
318 | "#, | |
319 | ) | |
320 | .build(); | |
321 | ||
322 | p.cargo("test -v") | |
323 | .without_status() | |
324 | .with_stderr_contains( | |
325 | "[RUNNING] `rustc --crate-name test_foo [..]-C link-arg=--this-is-a-bogus-flag[..]", | |
326 | ) | |
327 | .run(); | |
328 | } | |
329 | ||
330 | #[cargo_test] | |
331 | fn build_script_extra_link_arg_benches() { | |
332 | let p = project() | |
333 | .file("Cargo.toml", &basic_lib_manifest("foo")) | |
334 | .file("src/lib.rs", "") | |
335 | .file("benches/bench_foo.rs", "") | |
336 | .file( | |
337 | "build.rs", | |
338 | r#" | |
339 | fn main() { | |
340 | println!("cargo:rustc-link-arg-benches=--this-is-a-bogus-flag"); | |
341 | } | |
342 | "#, | |
343 | ) | |
344 | .build(); | |
345 | ||
346 | p.cargo("bench -v") | |
347 | .without_status() | |
348 | .with_stderr_contains( | |
349 | "[RUNNING] `rustc --crate-name bench_foo [..]-C link-arg=--this-is-a-bogus-flag[..]", | |
350 | ) | |
351 | .run(); | |
352 | } | |
353 | ||
354 | #[cargo_test] | |
355 | fn build_script_extra_link_arg_examples() { | |
356 | let p = project() | |
357 | .file("Cargo.toml", &basic_lib_manifest("foo")) | |
358 | .file("src/lib.rs", "") | |
359 | .file("examples/example_foo.rs", "fn main() {}") | |
360 | .file( | |
361 | "build.rs", | |
362 | r#" | |
363 | fn main() { | |
364 | println!("cargo:rustc-link-arg-examples=--this-is-a-bogus-flag"); | |
365 | } | |
366 | "#, | |
367 | ) | |
368 | .build(); | |
369 | ||
370 | p.cargo("build -v --examples") | |
371 | .without_status() | |
372 | .with_stderr_contains( | |
373 | "[RUNNING] `rustc --crate-name example_foo [..]-C link-arg=--this-is-a-bogus-flag[..]", | |
374 | ) | |
375 | .run(); | |
376 | } |