preprocess itself produces a functioning binary

This commit is contained in:
Folkert 2022-10-02 17:19:19 +02:00
parent 355bbcb3a7
commit 7a04c1e801
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C

View file

@ -1487,6 +1487,7 @@ mod test {
{
let dir = tempfile::tempdir().unwrap();
let dir = dir.path();
let dir = Path::new("/tmp/roc");
runner(dir);
@ -1672,4 +1673,129 @@ mod test {
fn preprocessing_wine() {
assert_eq!("Hello there\n", wine_test(preprocessing_help))
}
#[allow(dead_code)]
fn stripped_basics(dir: &Path) {
{
let host_zig = indoc!(
r#"
const std = @import("std");
extern fn roc_magic() callconv(.C) u64;
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
var timer = std.time.Timer.start() catch unreachable;
if (timer.read() == 1234) {
try stdout.print("Hello, {}!\n", .{roc_magic()});
} else {
try stdout.print("Hello, {}!\n", .{32});
}
}
"#
);
let app_zig = indoc!(
r#"
export fn roc_magic() u64 {
return 32;
}
"#
);
let zig = std::env::var("ROC_ZIG").unwrap_or_else(|_| "zig".into());
std::fs::write(dir.join("host.zig"), host_zig.as_bytes()).unwrap();
std::fs::write(dir.join("app.zig"), app_zig.as_bytes()).unwrap();
// we need to compile the app first
let output = std::process::Command::new(&zig)
.current_dir(dir)
.args(&[
"build-obj",
"app.zig",
"-target",
"x86_64-windows-gnu",
"--strip",
"-rdynamic",
"-OReleaseFast",
])
.output()
.unwrap();
if !output.status.success() {
use std::io::Write;
std::io::stdout().write_all(&output.stdout).unwrap();
std::io::stderr().write_all(&output.stderr).unwrap();
panic!("zig build-obj failed");
}
// open our app object; we'll copy sections from it later
let file = std::fs::File::open(dir.join("app.obj")).unwrap();
let roc_app = unsafe { memmap2::Mmap::map(&file) }.unwrap();
let roc_app_sections = AppSections::from_data(&*roc_app);
let symbols = roc_app_sections.roc_symbols;
// make the dummy dylib based on the app object
let names: Vec<_> = symbols.iter().map(|s| s.name.clone()).collect();
let dylib_bytes = crate::generate_dylib::synthetic_dll(&names);
std::fs::write(dir.join("libapp.obj"), dylib_bytes).unwrap();
// now we can compile the host (it uses libapp.obj, hence the order here)
let output = std::process::Command::new(&zig)
.current_dir(dir)
.args(&[
"build-exe",
"libapp.obj",
"host.zig",
"-lc",
"-target",
"x86_64-windows-gnu",
"-rdynamic",
"--strip",
"-rdynamic",
"-OReleaseFast",
])
.output()
.unwrap();
if !output.status.success() {
use std::io::Write;
std::io::stdout().write_all(&output.stdout).unwrap();
std::io::stderr().write_all(&output.stderr).unwrap();
panic!("zig build-exe failed");
}
preprocess_windows(
&dir.join("host.exe"),
&dir.join("metadata"),
&dir.join("preprocessedhost"),
false,
false,
)
.unwrap();
std::fs::copy(&dir.join("preprocessedhost"), &dir.join("app.exe")).unwrap();
// surgery_pe(&dir.join("app.exe"), &dir.join("metadata"), &*roc_app);
};
}
#[cfg(windows)]
#[test]
#[ignore = "does not work yet"]
fn stripped_basics_windows() {
assert_eq!("Hello, 32!\n", windows_test(stripped_basics))
}
#[test]
#[ignore]
fn stripped_basics_wine() {
assert_eq!("Hello, 32!\n", wine_test(stripped_basics))
}
}