]> git.proxmox.com Git - rustc.git/blame - tests/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.rs
New upstream version 1.69.0+dfsg1
[rustc.git] / tests / run-make-fulldeps / long-linker-command-lines-cmd-exe / foo.rs
CommitLineData
ff7c6d11
XL
1// Like the `long-linker-command-lines` test this test attempts to blow
2// a command line limit for running the linker. Unlike that test, however,
3// this test is testing `cmd.exe` specifically rather than the OS.
4//
5// Unfortunately `cmd.exe` has a 8192 limit which is relatively small
6// in the grand scheme of things and anyone sripting rustc's linker
7// is probably using a `*.bat` script and is likely to hit this limit.
8//
9// This test uses a `foo.bat` script as the linker which just simply
10// delegates back to this program. The compiler should use a lower
11// limit for arguments before passing everything via `@`, which
12// means that everything should still succeed here.
13
14use std::env;
15use std::fs::{self, File};
16use std::io::{BufWriter, Write, Read};
17use std::path::PathBuf;
18use std::process::Command;
19
20fn main() {
21 if !cfg!(windows) {
22 return
23 }
24
25 let tmpdir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
26 let ok = tmpdir.join("ok");
27 let not_ok = tmpdir.join("not_ok");
28 if env::var("YOU_ARE_A_LINKER").is_ok() {
29 match env::args_os().find(|a| a.to_string_lossy().contains("@")) {
30 Some(file) => {
31 let file = file.to_str().unwrap();
32 fs::copy(&file[1..], &ok).unwrap();
33 }
34 None => { File::create(&not_ok).unwrap(); }
35 }
36 return
37 }
38
39 let rustc = env::var_os("RUSTC").unwrap_or("rustc".into());
40 let me = env::current_exe().unwrap();
41 let bat = me.parent()
42 .unwrap()
43 .join("foo.bat");
44 let bat_linker = format!("linker={}", bat.display());
45 for i in (1..).map(|i| i * 10) {
46 println!("attempt: {}", i);
47
48 let file = tmpdir.join("bar.rs");
49 let mut f = BufWriter::new(File::create(&file).unwrap());
50 let mut lib_name = String::new();
51 for _ in 0..i {
52 lib_name.push_str("foo");
53 }
54 for j in 0..i {
55 writeln!(f, "#[link(name = \"{}{}\")]", lib_name, j).unwrap();
56 }
57 writeln!(f, "extern {{}}\nfn main() {{}}").unwrap();
58 f.into_inner().unwrap();
59
60 drop(fs::remove_file(&ok));
61 drop(fs::remove_file(&not_ok));
62 let status = Command::new(&rustc)
63 .arg(&file)
64 .arg("-C").arg(&bat_linker)
65 .arg("--out-dir").arg(&tmpdir)
66 .env("YOU_ARE_A_LINKER", "1")
67 .env("MY_LINKER", &me)
68 .status()
69 .unwrap();
70
71 if !status.success() {
72 panic!("rustc didn't succeed: {}", status);
73 }
74
75 if !ok.exists() {
76 assert!(not_ok.exists());
77 continue
78 }
79
80 let mut contents = Vec::new();
81 File::open(&ok).unwrap().read_to_end(&mut contents).unwrap();
82
83 for j in 0..i {
84 let exp = format!("{}{}", lib_name, j);
85 let exp = if cfg!(target_env = "msvc") {
86 let mut out = Vec::with_capacity(exp.len() * 2);
87 for c in exp.encode_utf16() {
88 // encode in little endian
89 out.push(c as u8);
90 out.push((c >> 8) as u8);
91 }
92 out
93 } else {
94 exp.into_bytes()
95 };
96 assert!(contents.windows(exp.len()).any(|w| w == &exp[..]));
97 }
98
99 break
100 }
101}