]> git.lizzy.rs Git - rust.git/blob - tests/run-make-fulldeps/long-linker-command-lines/foo.rs
Auto merge of #105716 - chriswailes:ndk-update-redux, r=pietroalbini
[rust.git] / tests / run-make-fulldeps / long-linker-command-lines / foo.rs
1 // This is a test which attempts to blow out the system limit with how many
2 // arguments can be passed to a process. This'll successively call rustc with
3 // larger and larger argument lists in an attempt to find one that's way too
4 // big for the system at hand. This file itself is then used as a "linker" to
5 // detect when the process creation succeeds.
6 //
7 // Eventually we should see an argument that looks like `@` as we switch from
8 // passing literal arguments to passing everything in the file.
9
10 use std::collections::HashSet;
11 use std::env;
12 use std::fs::{self, File};
13 use std::io::{BufWriter, Write};
14 use std::path::{Path, PathBuf};
15 use std::process::Command;
16
17 fn write_test_case(file: &Path, n: usize) -> HashSet<String> {
18     let mut libs = HashSet::new();
19     let mut f = BufWriter::new(File::create(&file).unwrap());
20     let mut prefix = String::new();
21     for _ in 0..n {
22         prefix.push_str("foo");
23     }
24     for i in 0..n {
25         writeln!(f, "#[link(name = \"S{}{}S\")]", prefix, i).unwrap();
26         libs.insert(format!("{}{}", prefix, i));
27     }
28     writeln!(f, "extern \"C\" {{}}\nfn main() {{}}").unwrap();
29     f.into_inner().unwrap();
30
31     libs
32 }
33
34 fn read_linker_args(path: &Path) -> String {
35     let contents = fs::read(path).unwrap();
36     if cfg!(target_env = "msvc") {
37         let mut i = contents.chunks(2).map(|c| {
38             c[0] as u16 | ((c[1] as u16) << 8)
39         });
40         assert_eq!(i.next(), Some(0xfeff), "Expected UTF-16 BOM");
41         String::from_utf16(&i.collect::<Vec<u16>>()).unwrap()
42     } else {
43         String::from_utf8(contents).unwrap()
44     }
45 }
46
47 fn main() {
48     let tmpdir = PathBuf::from(env::var_os("TMPDIR").unwrap());
49     let ok = tmpdir.join("ok");
50     if env::var("YOU_ARE_A_LINKER").is_ok() {
51         if let Some(file) = env::args_os().find(|a| a.to_string_lossy().contains("@")) {
52             let file = file.to_str().expect("non-utf8 file argument");
53             fs::copy(&file[1..], &ok).unwrap();
54         }
55         return
56     }
57
58     let rustc = env::var_os("RUSTC").unwrap_or("rustc".into());
59     let me_as_linker = format!("linker={}", env::current_exe().unwrap().display());
60     for i in (1..).map(|i| i * 100) {
61         println!("attempt: {}", i);
62         let file = tmpdir.join("bar.rs");
63         let mut expected_libs = write_test_case(&file, i);
64
65         drop(fs::remove_file(&ok));
66         let output = Command::new(&rustc)
67             .arg(&file)
68             .arg("-C").arg(&me_as_linker)
69             .arg("--out-dir").arg(&tmpdir)
70             .env("YOU_ARE_A_LINKER", "1")
71             .output()
72             .unwrap();
73
74         if !output.status.success() {
75             let stderr = String::from_utf8_lossy(&output.stderr);
76             panic!("status: {}\nstdout:\n{}\nstderr:\n{}",
77                    output.status,
78                    String::from_utf8_lossy(&output.stdout),
79                    stderr.lines().map(|l| {
80                        if l.len() > 200 {
81                            format!("{}...\n", &l[..200])
82                        } else {
83                            format!("{}\n", l)
84                        }
85                    }).collect::<String>());
86         }
87
88         if !ok.exists() {
89             continue
90         }
91
92         let linker_args = read_linker_args(&ok);
93         for arg in linker_args.split('S') {
94             expected_libs.remove(arg);
95         }
96
97         assert!(
98             expected_libs.is_empty(),
99             "expected but missing libraries: {:#?}\nlinker arguments: \n{}",
100             expected_libs,
101             linker_args,
102         );
103
104         break
105     }
106 }