mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
add test that combines a zig platform with a dll
This commit is contained in:
parent
61366f0d43
commit
6005ed0664
4 changed files with 73 additions and 50 deletions
|
@ -398,6 +398,8 @@ mod test {
|
|||
use object::read::pe::PeFile64;
|
||||
use object::{pe, Object};
|
||||
|
||||
use indoc::indoc;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
@ -574,27 +576,23 @@ mod test {
|
|||
assert_eq!(actual, 7)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn increase_number_of_sections() {
|
||||
fn increase_number_of_sections_help(input_data: &[u8], output_file: &Path) {
|
||||
use object::read::pe::ImageNtHeaders;
|
||||
|
||||
let dos_header = pe::ImageDosHeader::parse(PE_DYNHOST).unwrap();
|
||||
let dos_header = pe::ImageDosHeader::parse(input_data).unwrap();
|
||||
let mut offset = dos_header.nt_headers_offset().into();
|
||||
let header_offset = offset;
|
||||
let number_of_sections_offset = header_offset + 4 + 2;
|
||||
|
||||
let sections_len_old = u16::from_le_bytes(
|
||||
PE_DYNHOST[number_of_sections_offset as usize..][..2]
|
||||
input_data[number_of_sections_offset as usize..][..2]
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let new_sections = [*b"placehol", *b"aaaabbbb"];
|
||||
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let path = dir.path().join("test.exe");
|
||||
|
||||
let mmap = Preprocessor::preprocess(&path, PE_DYNHOST, &new_sections);
|
||||
let mmap = Preprocessor::preprocess(output_file, input_data, &new_sections);
|
||||
|
||||
let data = mmap.deref();
|
||||
|
||||
|
@ -622,61 +620,53 @@ mod test {
|
|||
assert_eq!(new_sections, names.as_slice());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn increase_number_of_sections() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let path = dir.path().join("test.exe");
|
||||
|
||||
increase_number_of_sections_help(PE_DYNHOST, &path);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preprocess_zig_host() {
|
||||
let host_zig = include_str!("../trivial_host.zig");
|
||||
let app_zig = include_str!("../trivial_app.zig");
|
||||
let host_zig = indoc!(
|
||||
r#"
|
||||
extern fn double(u8) u8;
|
||||
|
||||
pub fn main() u8 {
|
||||
return double(42);
|
||||
}
|
||||
"#
|
||||
);
|
||||
|
||||
let app_zig = indoc!(
|
||||
r#"
|
||||
export fn double(n: u8) u8 {
|
||||
return n + n;
|
||||
}
|
||||
"#
|
||||
);
|
||||
|
||||
let zig = std::env::var("ROC_ZIG").unwrap_or_else(|_| "zig".into());
|
||||
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let dir = dir.path();
|
||||
|
||||
std::fs::write(dir.join("trivial_host.zig"), host_zig.as_bytes()).unwrap();
|
||||
std::fs::write(dir.join("trivial_app.zig"), app_zig.as_bytes()).unwrap();
|
||||
std::fs::write(dir.join("host.zig"), host_zig.as_bytes()).unwrap();
|
||||
std::fs::write(dir.join("app.zig"), app_zig.as_bytes()).unwrap();
|
||||
|
||||
// here we would like to do
|
||||
//
|
||||
// let dylib_bytes = crate::generate_dylib::synthetic_dll(&["double".into(), "triple".into()]);
|
||||
// std::fs::write(dir.join("roc-cheaty-lib.dll"), dylib_bytes).unwrap();
|
||||
//
|
||||
// but on windows, this is not so simple. To link a .dll into an .exe we need an additional
|
||||
// .lib file, a so-called "import library". These are normally generated by the linker, and
|
||||
// based on some googling there is other tooling on windows that can also generate them
|
||||
// from a .dll. There is however very little information on what they should contain.
|
||||
//
|
||||
// Jakub intends to implement generating the .lib files in pure zig in the near(ish)
|
||||
// future, so if we can wait then we can use the zig source to create our own logic for
|
||||
// a very simple .lib file
|
||||
|
||||
let output = std::process::Command::new(&zig)
|
||||
.current_dir(dir)
|
||||
.args(&[
|
||||
"build-lib",
|
||||
"trivial_app.zig",
|
||||
"-target",
|
||||
"x86_64-windows-gnu",
|
||||
"--strip",
|
||||
"-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!();
|
||||
}
|
||||
let dylib_bytes = crate::generate_dylib::synthetic_dll(&["double".into()]);
|
||||
std::fs::write(dir.join("libapp.obj"), dylib_bytes).unwrap();
|
||||
|
||||
let output = std::process::Command::new(&zig)
|
||||
.current_dir(dir)
|
||||
.args(&[
|
||||
"build-exe",
|
||||
"trivial_host.zig",
|
||||
"trivial_app.lib",
|
||||
"-fPIE",
|
||||
"libapp.obj",
|
||||
"host.zig",
|
||||
"-lc",
|
||||
"-target",
|
||||
"x86_64-windows-gnu",
|
||||
"--strip",
|
||||
|
@ -691,7 +681,32 @@ mod test {
|
|||
std::io::stdout().write_all(&output.stdout).unwrap();
|
||||
std::io::stderr().write_all(&output.stderr).unwrap();
|
||||
|
||||
panic!();
|
||||
panic!("zig build-exe failed");
|
||||
}
|
||||
|
||||
let data = std::fs::read(dir.join("host.exe")).unwrap();
|
||||
increase_number_of_sections_help(&data, &dir.join("dynhost.exe"));
|
||||
|
||||
let output = std::process::Command::new(&zig)
|
||||
.current_dir(dir)
|
||||
.args(&[
|
||||
"build-obj",
|
||||
"app.zig",
|
||||
"-target",
|
||||
"x86_64-windows-gnu",
|
||||
"--strip",
|
||||
"-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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue