save generated app_data to an object file

This commit is contained in:
Jakub Konka 2024-10-16 00:11:03 +02:00
parent 2e2be45508
commit 322366bab3
5 changed files with 42 additions and 13 deletions

View file

@ -1041,14 +1041,13 @@ fn link_macos(
// "--gc-sections", // "--gc-sections",
"-arch", "-arch",
&arch, &arch,
// Suppress warnings, because otherwise it prints:
//
// ld: warning: -undefined dynamic_lookup may not work with chained fixups
//
// We can't disable that option without breaking either x64 mac or ARM mac
"-w",
"-macos_version_min", "-macos_version_min",
&get_macos_version(), &get_macos_version(),
// Suppress fixup chains to ease working out dynamic relocs by the
// surgical linker. In my experience, working with dyld opcodes is
// slightly easier than unpacking compressed info from the __got section
// and fixups load command.
"-no_fixup_chains",
]) ])
.args(input_paths) .args(input_paths)
.args(extra_link_flags()); .args(extra_link_flags());

View file

@ -949,6 +949,11 @@ fn build_loaded_file<'a>(
match (linking_strategy, link_type) { match (linking_strategy, link_type) {
(LinkingStrategy::Surgical, _) => { (LinkingStrategy::Surgical, _) => {
if false {
let mut f = std::fs::File::create("tmp_roc.o").unwrap();
std::io::Write::write_all(&mut f, &roc_app_bytes).unwrap();
}
let metadata_file = platform_main_roc_path.with_file_name(target.metadata_file_name()); let metadata_file = platform_main_roc_path.with_file_name(target.metadata_file_name());
roc_linker::link_preprocessed_host( roc_linker::link_preprocessed_host(

View file

@ -62,6 +62,7 @@ pub fn create_dylib_macho(
let ld_flag_soname = "-install_name"; let ld_flag_soname = "-install_name";
let ld_prefix_args = [big_sur_fix, "-lSystem", "-dylib"]; let ld_prefix_args = [big_sur_fix, "-lSystem", "-dylib"];
let macos_version = get_macos_version();
let output = Command::new("ld") let output = Command::new("ld")
.args(ld_prefix_args) .args(ld_prefix_args)
@ -71,12 +72,15 @@ pub fn create_dylib_macho(
dummy_obj_file.path().to_str().unwrap(), dummy_obj_file.path().to_str().unwrap(),
"-o", "-o",
dummy_lib_file.to_str().unwrap(), dummy_lib_file.to_str().unwrap(),
// Suppress warnings, because otherwise it prints: // Suppress fixup chains to ease working out dynamic relocs by the
// // surgical linker. In my experience, working with dyld opcodes is
// ld: warning: -undefined dynamic_lookup may not work with chained fixups // slightly easier than unpacking compressed info from the __got section
// // and fixups load command.
// We can't disable that option without breaking either x64 mac or ARM mac "-no_fixup_chains",
"-w", "-platform_version",
"macos",
&macos_version,
&macos_version,
]) ])
.output() .output()
.unwrap(); .unwrap();
@ -98,3 +102,23 @@ pub fn create_dylib_macho(
Ok(std::fs::read(dummy_lib_file).expect("Failed to load dummy library")) Ok(std::fs::read(dummy_lib_file).expect("Failed to load dummy library"))
} }
fn get_macos_version() -> String {
let mut cmd = Command::new("sw_vers");
cmd.arg("-productVersion");
let cmd_stdout = cmd
.output()
.expect("Failed to execute command 'sw_vers -productVersion'")
.stdout;
let full_version_string = String::from_utf8(cmd_stdout)
.expect("Failed to convert output of command 'sw_vers -productVersion' into a utf8 string");
full_version_string
.trim_end()
.split('.')
.take(3)
.collect::<Vec<&str>>()
.join(".")
}

View file

@ -35,6 +35,7 @@ pub fn supported(link_type: LinkType, target: Target) -> bool {
Target::WinX64 => true, Target::WinX64 => true,
// macho support is incomplete // macho support is incomplete
Target::MacX64 => false, Target::MacX64 => false,
Target::MacArm64 => true,
_ => false, _ => false,
} }
} else { } else {

View file

@ -1259,7 +1259,7 @@ fn surgery_macho_help(
Some((_, size)) => size, Some((_, size)) => size,
None => 0, None => 0,
}; };
if sec.name().unwrap_or_default().starts_with("__BSS") { if sec.name().unwrap_or_default().starts_with("__bss") {
// bss sections only modify the virtual size. // bss sections only modify the virtual size.
virt_offset += sec.size() as usize; virt_offset += sec.size() as usize;
} else if section_size != sec.size() { } else if section_size != sec.size() {