1 use crate::support::Test;
2 
3 mod support;
4 
5 // Some tests check that a flag is *not* present.  These tests might fail if the flag is set in the
6 // CFLAGS or CXXFLAGS environment variables.  This function clears the CFLAGS and CXXFLAGS
7 // variables to make sure that the tests can run correctly.
reset_env()8 fn reset_env() {
9     std::env::set_var("CFLAGS", "");
10     std::env::set_var("CXXFLAGS", "");
11 }
12 
13 #[test]
gnu_smoke()14 fn gnu_smoke() {
15     reset_env();
16 
17     let test = Test::gnu();
18     test.gcc().file("foo.c").compile("foo");
19 
20     test.cmd(0)
21         .must_have("-O2")
22         .must_have("foo.c")
23         .must_not_have("-g")
24         .must_have("-c")
25         .must_have("-ffunction-sections")
26         .must_have("-fdata-sections");
27     test.cmd(1).must_have(test.td.path().join("foo.o"));
28 }
29 
30 #[test]
gnu_opt_level_1()31 fn gnu_opt_level_1() {
32     reset_env();
33 
34     let test = Test::gnu();
35     test.gcc().opt_level(1).file("foo.c").compile("foo");
36 
37     test.cmd(0).must_have("-O1").must_not_have("-O2");
38 }
39 
40 #[test]
gnu_opt_level_s()41 fn gnu_opt_level_s() {
42     reset_env();
43 
44     let test = Test::gnu();
45     test.gcc().opt_level_str("s").file("foo.c").compile("foo");
46 
47     test.cmd(0)
48         .must_have("-Os")
49         .must_not_have("-O1")
50         .must_not_have("-O2")
51         .must_not_have("-O3")
52         .must_not_have("-Oz");
53 }
54 
55 #[test]
gnu_debug_fp_auto()56 fn gnu_debug_fp_auto() {
57     let test = Test::gnu();
58     test.gcc().debug(true).file("foo.c").compile("foo");
59     test.cmd(0).must_have("-g");
60     test.cmd(0).must_have("-fno-omit-frame-pointer");
61 }
62 
63 #[test]
gnu_debug_fp()64 fn gnu_debug_fp() {
65     let test = Test::gnu();
66     test.gcc().debug(true).file("foo.c").compile("foo");
67     test.cmd(0).must_have("-g");
68     test.cmd(0).must_have("-fno-omit-frame-pointer");
69 }
70 
71 #[test]
gnu_debug_nofp()72 fn gnu_debug_nofp() {
73     reset_env();
74 
75     let test = Test::gnu();
76     test.gcc()
77         .debug(true)
78         .force_frame_pointer(false)
79         .file("foo.c")
80         .compile("foo");
81     test.cmd(0).must_have("-g");
82     test.cmd(0).must_not_have("-fno-omit-frame-pointer");
83 
84     let test = Test::gnu();
85     test.gcc()
86         .force_frame_pointer(false)
87         .debug(true)
88         .file("foo.c")
89         .compile("foo");
90     test.cmd(0).must_have("-g");
91     test.cmd(0).must_not_have("-fno-omit-frame-pointer");
92 }
93 
94 #[test]
gnu_warnings_into_errors()95 fn gnu_warnings_into_errors() {
96     let test = Test::gnu();
97     test.gcc()
98         .warnings_into_errors(true)
99         .file("foo.c")
100         .compile("foo");
101 
102     test.cmd(0).must_have("-Werror");
103 }
104 
105 #[test]
gnu_warnings()106 fn gnu_warnings() {
107     let test = Test::gnu();
108     test.gcc()
109         .warnings(true)
110         .flag("-Wno-missing-field-initializers")
111         .file("foo.c")
112         .compile("foo");
113 
114     test.cmd(0).must_have("-Wall").must_have("-Wextra");
115 }
116 
117 #[test]
gnu_extra_warnings0()118 fn gnu_extra_warnings0() {
119     reset_env();
120 
121     let test = Test::gnu();
122     test.gcc()
123         .warnings(true)
124         .extra_warnings(false)
125         .flag("-Wno-missing-field-initializers")
126         .file("foo.c")
127         .compile("foo");
128 
129     test.cmd(0).must_have("-Wall").must_not_have("-Wextra");
130 }
131 
132 #[test]
gnu_extra_warnings1()133 fn gnu_extra_warnings1() {
134     reset_env();
135 
136     let test = Test::gnu();
137     test.gcc()
138         .warnings(false)
139         .extra_warnings(true)
140         .flag("-Wno-missing-field-initializers")
141         .file("foo.c")
142         .compile("foo");
143 
144     test.cmd(0).must_not_have("-Wall").must_have("-Wextra");
145 }
146 
147 #[test]
gnu_warnings_overridable()148 fn gnu_warnings_overridable() {
149     reset_env();
150 
151     let test = Test::gnu();
152     test.gcc()
153         .warnings(true)
154         .flag("-Wno-missing-field-initializers")
155         .file("foo.c")
156         .compile("foo");
157 
158     test.cmd(0)
159         .must_have_in_order("-Wall", "-Wno-missing-field-initializers");
160 }
161 
162 #[test]
gnu_x86_64()163 fn gnu_x86_64() {
164     for vendor in &["unknown-linux-gnu", "apple-darwin"] {
165         let target = format!("x86_64-{}", vendor);
166         let test = Test::gnu();
167         test.gcc()
168             .target(&target)
169             .host(&target)
170             .file("foo.c")
171             .compile("foo");
172 
173         test.cmd(0).must_have("-fPIC").must_have("-m64");
174     }
175 }
176 
177 #[test]
gnu_x86_64_no_pic()178 fn gnu_x86_64_no_pic() {
179     reset_env();
180 
181     for vendor in &["unknown-linux-gnu", "apple-darwin"] {
182         let target = format!("x86_64-{}", vendor);
183         let test = Test::gnu();
184         test.gcc()
185             .pic(false)
186             .target(&target)
187             .host(&target)
188             .file("foo.c")
189             .compile("foo");
190 
191         test.cmd(0).must_not_have("-fPIC");
192     }
193 }
194 
195 #[test]
gnu_i686()196 fn gnu_i686() {
197     for vendor in &["unknown-linux-gnu", "apple-darwin"] {
198         let target = format!("i686-{}", vendor);
199         let test = Test::gnu();
200         test.gcc()
201             .target(&target)
202             .host(&target)
203             .file("foo.c")
204             .compile("foo");
205 
206         test.cmd(0).must_have("-m32");
207     }
208 }
209 
210 #[test]
gnu_i686_pic()211 fn gnu_i686_pic() {
212     for vendor in &["unknown-linux-gnu", "apple-darwin"] {
213         let target = format!("i686-{}", vendor);
214         let test = Test::gnu();
215         test.gcc()
216             .pic(true)
217             .target(&target)
218             .host(&target)
219             .file("foo.c")
220             .compile("foo");
221 
222         test.cmd(0).must_have("-fPIC");
223     }
224 }
225 
226 #[test]
gnu_x86_64_no_plt()227 fn gnu_x86_64_no_plt() {
228     let target = "x86_64-unknown-linux-gnu";
229     let test = Test::gnu();
230     test.gcc()
231         .pic(true)
232         .use_plt(false)
233         .target(&target)
234         .host(&target)
235         .file("foo.c")
236         .compile("foo");
237     test.cmd(0).must_have("-fno-plt");
238 }
239 
240 #[test]
gnu_set_stdlib()241 fn gnu_set_stdlib() {
242     reset_env();
243 
244     let test = Test::gnu();
245     test.gcc()
246         .cpp_set_stdlib(Some("foo"))
247         .file("foo.c")
248         .compile("foo");
249 
250     test.cmd(0).must_not_have("-stdlib=foo");
251 }
252 
253 #[test]
gnu_include()254 fn gnu_include() {
255     let test = Test::gnu();
256     test.gcc().include("foo/bar").file("foo.c").compile("foo");
257 
258     test.cmd(0).must_have("-I").must_have("foo/bar");
259 }
260 
261 #[test]
gnu_define()262 fn gnu_define() {
263     let test = Test::gnu();
264     test.gcc()
265         .define("FOO", "bar")
266         .define("BAR", None)
267         .file("foo.c")
268         .compile("foo");
269 
270     test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
271 }
272 
273 #[test]
gnu_compile_assembly()274 fn gnu_compile_assembly() {
275     let test = Test::gnu();
276     test.gcc().file("foo.S").compile("foo");
277     test.cmd(0).must_have("foo.S");
278 }
279 
280 #[test]
gnu_shared()281 fn gnu_shared() {
282     reset_env();
283 
284     let test = Test::gnu();
285     test.gcc()
286         .file("foo.c")
287         .shared_flag(true)
288         .static_flag(false)
289         .compile("foo");
290 
291     test.cmd(0).must_have("-shared").must_not_have("-static");
292 }
293 
294 #[test]
gnu_flag_if_supported()295 fn gnu_flag_if_supported() {
296     reset_env();
297 
298     if cfg!(windows) {
299         return;
300     }
301     let test = Test::gnu();
302     test.gcc()
303         .file("foo.c")
304         .flag("-v")
305         .flag_if_supported("-Wall")
306         .flag_if_supported("-Wflag-does-not-exist")
307         .flag_if_supported("-std=c++11")
308         .compile("foo");
309 
310     test.cmd(0)
311         .must_have("-v")
312         .must_have("-Wall")
313         .must_not_have("-Wflag-does-not-exist")
314         .must_not_have("-std=c++11");
315 }
316 
317 #[test]
gnu_flag_if_supported_cpp()318 fn gnu_flag_if_supported_cpp() {
319     if cfg!(windows) {
320         return;
321     }
322     let test = Test::gnu();
323     test.gcc()
324         .cpp(true)
325         .file("foo.cpp")
326         .flag_if_supported("-std=c++11")
327         .compile("foo");
328 
329     test.cmd(0).must_have("-std=c++11");
330 }
331 
332 #[test]
gnu_static()333 fn gnu_static() {
334     reset_env();
335 
336     let test = Test::gnu();
337     test.gcc()
338         .file("foo.c")
339         .shared_flag(false)
340         .static_flag(true)
341         .compile("foo");
342 
343     test.cmd(0).must_have("-static").must_not_have("-shared");
344 }
345 
346 #[test]
msvc_smoke()347 fn msvc_smoke() {
348     reset_env();
349 
350     let test = Test::msvc();
351     test.gcc().file("foo.c").compile("foo");
352 
353     test.cmd(0)
354         .must_have("-O2")
355         .must_have("foo.c")
356         .must_not_have("-Z7")
357         .must_have("-c")
358         .must_have("-MD");
359     test.cmd(1).must_have(test.td.path().join("foo.o"));
360 }
361 
362 #[test]
msvc_opt_level_0()363 fn msvc_opt_level_0() {
364     reset_env();
365 
366     let test = Test::msvc();
367     test.gcc().opt_level(0).file("foo.c").compile("foo");
368 
369     test.cmd(0).must_not_have("-O2");
370 }
371 
372 #[test]
msvc_debug()373 fn msvc_debug() {
374     let test = Test::msvc();
375     test.gcc().debug(true).file("foo.c").compile("foo");
376     test.cmd(0).must_have("-Z7");
377 }
378 
379 #[test]
msvc_include()380 fn msvc_include() {
381     let test = Test::msvc();
382     test.gcc().include("foo/bar").file("foo.c").compile("foo");
383 
384     test.cmd(0).must_have("-I").must_have("foo/bar");
385 }
386 
387 #[test]
msvc_define()388 fn msvc_define() {
389     let test = Test::msvc();
390     test.gcc()
391         .define("FOO", "bar")
392         .define("BAR", None)
393         .file("foo.c")
394         .compile("foo");
395 
396     test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
397 }
398 
399 #[test]
msvc_static_crt()400 fn msvc_static_crt() {
401     let test = Test::msvc();
402     test.gcc().static_crt(true).file("foo.c").compile("foo");
403 
404     test.cmd(0).must_have("-MT");
405 }
406 
407 #[test]
msvc_no_static_crt()408 fn msvc_no_static_crt() {
409     let test = Test::msvc();
410     test.gcc().static_crt(false).file("foo.c").compile("foo");
411 
412     test.cmd(0).must_have("-MD");
413 }
414