mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-24 12:32:29 +00:00
don't regenerate the dynhost file if it is unchanged
This commit is contained in:
parent
f879798b17
commit
d433448d6f
1 changed files with 55 additions and 3 deletions
|
@ -136,10 +136,62 @@ fn generate_dynamic_lib(
|
|||
}
|
||||
}
|
||||
|
||||
let bytes = crate::generate_dylib::generate(target, &custom_names)
|
||||
.unwrap_or_else(|e| internal_error!("{}", e));
|
||||
if !dynhost_is_up_to_date(target, dummy_lib_path, &custom_names) {
|
||||
let bytes = crate::generate_dylib::generate(target, &custom_names)
|
||||
.unwrap_or_else(|e| internal_error!("{}", e));
|
||||
|
||||
std::fs::write(dummy_lib_path, &bytes).unwrap_or_else(|e| internal_error!("{}", e))
|
||||
std::fs::write(dummy_lib_path, &bytes).unwrap_or_else(|e| internal_error!("{}", e))
|
||||
}
|
||||
}
|
||||
|
||||
fn object_matches_target<'a>(target: &Triple, object: &object::File<'a, &'a [u8]>) -> bool {
|
||||
use target_lexicon::{Architecture as TLA, OperatingSystem as TLO};
|
||||
|
||||
match target.architecture {
|
||||
TLA::X86_64 => {
|
||||
if object.architecture() != object::Architecture::X86_64 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let actual = object.format();
|
||||
|
||||
let expected = match target.operating_system {
|
||||
TLO::Linux => object::BinaryFormat::Elf,
|
||||
other => internal_error!("unexpected target {:?}", other),
|
||||
};
|
||||
|
||||
actual == expected
|
||||
}
|
||||
TLA::Aarch64(_) => object.architecture() == object::Architecture::Aarch64,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn dynhost_is_up_to_date(target: &Triple, dummy_lib_path: &Path, custom_names: &[String]) -> bool {
|
||||
if !std::path::Path::exists(dummy_lib_path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let exec_file = fs::File::open(dummy_lib_path).unwrap_or_else(|e| internal_error!("{}", e));
|
||||
let exec_mmap = unsafe { Mmap::map(&exec_file).unwrap_or_else(|e| internal_error!("{}", e)) };
|
||||
let exec_data = &*exec_mmap;
|
||||
|
||||
let object = object::File::parse(exec_data).unwrap();
|
||||
|
||||
// the user may have been cross-compiling.
|
||||
// The dynhost on disk must match our current target
|
||||
if !object_matches_target(target, &object) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// we made this dynhost file. For the file to be the same as what we'd generate,
|
||||
// we need all symbols to be there and in the correct order
|
||||
let dynamic_symbols: Vec<_> = object.exports().unwrap();
|
||||
|
||||
let it1 = dynamic_symbols.iter().map(|e| e.name());
|
||||
let it2 = custom_names.iter().map(|s| s.as_bytes());
|
||||
|
||||
it1.eq(it2)
|
||||
}
|
||||
|
||||
fn is_roc_symbol(sym: &object::Symbol) -> bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue