|
| 1 | +//! Large archive example. |
| 2 | +//! |
| 3 | +//! This creates several C files with a bunch of global arrays. The goal is to |
| 4 | +//! create an rlib that is over 4GB in size so that the LLVM archiver creates |
| 5 | +//! a /SYM64/ entry instead of /. |
| 6 | +//! |
| 7 | +//! It compiles the C files to .o files, and then uses `ar` to collect them |
| 8 | +//! into a static library. It creates `foo.rs` with references to all the C |
| 9 | +//! arrays, and then uses `rustc` to build an rlib with that static |
| 10 | +//! information. It then creates `bar.rs` which links the giant libfoo.rlib, |
| 11 | +//! which should fail since it can't read the large libfoo.rlib file. |
| 12 | +
|
| 13 | +use std::env; |
| 14 | +use std::fs::File; |
| 15 | +use std::io::{BufWriter, Write}; |
| 16 | +use std::process::Command; |
| 17 | + |
| 18 | +// Number of object files to create. |
| 19 | +const NOBJ: u32 = 12; |
| 20 | +// Make the filename longer than 16 characters to force names to be placed in // |
| 21 | +const PREFIX: &str = "abcdefghijklmnopqrstuvwxyz"; |
| 22 | + |
| 23 | +fn main() { |
| 24 | + let tmpdir = std::path::PathBuf::from(env::args_os().nth(1).unwrap()); |
| 25 | + let mut foo_rs = File::create(tmpdir.join("foo.rs")).unwrap(); |
| 26 | + write!(foo_rs, "extern \"C\" {{\n").unwrap(); |
| 27 | + for obj in 0..NOBJ { |
| 28 | + let filename = tmpdir.join(&format!("{}{}.c", PREFIX, obj)); |
| 29 | + let f = File::create(&filename).unwrap(); |
| 30 | + let mut buf = BufWriter::new(f); |
| 31 | + write!(buf, "#include<stdint.h>\n").unwrap(); |
| 32 | + for n in 0..50 { |
| 33 | + write!(buf, "int64_t FOO_{}_{}[] = {{\n", obj, n).unwrap(); |
| 34 | + for x in 0..1024 { |
| 35 | + for y in 0..1024 { |
| 36 | + write!(buf, "{},", (obj + n + x + y) % 10).unwrap(); |
| 37 | + } |
| 38 | + write!(buf, "\n").unwrap(); |
| 39 | + } |
| 40 | + write!(buf, "}};\n").unwrap(); |
| 41 | + write!(foo_rs, " pub static FOO_{}_{}: [i64; 1024*1024];\n", obj, n).unwrap(); |
| 42 | + } |
| 43 | + drop(buf); |
| 44 | + println!("compile {:?}", filename); |
| 45 | + let status = |
| 46 | + Command::new("cc").current_dir(&tmpdir).arg("-c").arg(&filename).status().unwrap(); |
| 47 | + if !status.success() { |
| 48 | + panic!("failed: {:?}", status); |
| 49 | + } |
| 50 | + } |
| 51 | + write!(foo_rs, "}}\n").unwrap(); |
| 52 | + drop(foo_rs); |
| 53 | + let mut cmd = Command::new("ar"); |
| 54 | + cmd.arg("-crs"); |
| 55 | + cmd.arg(tmpdir.join("libfoo.a")); |
| 56 | + for obj in 0..NOBJ { |
| 57 | + cmd.arg(tmpdir.join(&format!("{}{}.o", PREFIX, obj))); |
| 58 | + } |
| 59 | + println!("archiving: {:?}", cmd); |
| 60 | + let status = cmd.status().unwrap(); |
| 61 | + if !status.success() { |
| 62 | + panic!("failed: {:?}", status); |
| 63 | + } |
| 64 | +} |
0 commit comments