use crate::code_gen::CodeGenerationError;
use crate::linker;
use inkwell::targets::{FileType, TargetMachine};
use mun_target::spec;
use std::{io::Write, path::Path};
use tempfile::NamedTempFile;
pub struct ObjectFile {
target: spec::Target,
obj_file: NamedTempFile,
}
impl ObjectFile {
pub fn new(
target: &spec::Target,
target_machine: &TargetMachine,
module: &inkwell::module::Module,
) -> Result<Self, anyhow::Error> {
let obj = target_machine
.write_to_memory_buffer(module, FileType::Object)
.map_err(|e| CodeGenerationError::MachineCodeError(e.to_string()))?;
let mut obj_file = tempfile::NamedTempFile::new()
.map_err(CodeGenerationError::CouldNotCreateObjectFile)?;
obj_file
.write(obj.as_slice())
.map_err(CodeGenerationError::CouldNotCreateObjectFile)?;
Ok(Self {
target: target.clone(),
obj_file,
})
}
pub fn into_shared_object(self, output_path: &Path) -> Result<(), anyhow::Error> {
let mut linker = linker::create_with_target(&self.target);
linker.add_object(self.obj_file.path())?;
linker.build_shared_object(output_path)?;
linker.finalize()?;
Ok(())
}
}