79 lines
2.2 KiB
Rust
79 lines
2.2 KiB
Rust
use std::{path::PathBuf, process::Command, thread, time::Duration};
|
|
|
|
pub struct LDRunner {
|
|
command: String,
|
|
dynamic_linker: String,
|
|
libraries: Vec<String>,
|
|
}
|
|
|
|
impl LDRunner {
|
|
pub fn from_command(command: &str) -> LDRunner {
|
|
LDRunner {
|
|
command: command.to_owned(),
|
|
dynamic_linker: "ld-linux-x86-64.so.2".to_string(),
|
|
libraries: Default::default(),
|
|
}
|
|
}
|
|
|
|
pub fn with_library(mut self, lib: &str) -> LDRunner {
|
|
self.libraries.push(lib.to_owned());
|
|
self
|
|
}
|
|
|
|
pub fn invoke(&self, input: &PathBuf, out_path: &PathBuf) {
|
|
let input_path = input.canonicalize().unwrap();
|
|
|
|
let dyn_linker_path = find_objectfile(&self.dynamic_linker);
|
|
let crt1_path = find_objectfile("crt1.o");
|
|
|
|
#[cfg(feature = "log_output")]
|
|
println!("LDRunner: Using dynamic linker at: {:?}", dyn_linker_path);
|
|
|
|
let mut ld = Command::new(&self.command);
|
|
ld.arg("-dynamic-linker").arg(dyn_linker_path).arg(crt1_path);
|
|
|
|
for library in &self.libraries {
|
|
ld.arg(format!("-l{}", library));
|
|
}
|
|
|
|
ld.arg(input_path.to_str().unwrap())
|
|
.arg("-o")
|
|
.arg(out_path.to_str().unwrap());
|
|
|
|
#[cfg(feature = "log_output")]
|
|
println!(
|
|
"LDRunner: Executing linker to objfile at {:?} => {:?}",
|
|
input_path, out_path
|
|
);
|
|
#[cfg(feature = "log_output")]
|
|
dbg!(&ld);
|
|
|
|
ld.spawn().expect("Unable to execute ld!");
|
|
|
|
thread::sleep(Duration::from_millis(100));
|
|
|
|
#[cfg(feature = "log_output")]
|
|
println!("Setting executable bit to {:?}..", out_path);
|
|
Command::new("chmod").arg("+x").arg(out_path).spawn().unwrap();
|
|
thread::sleep(Duration::from_millis(100));
|
|
}
|
|
}
|
|
|
|
fn find_objectfile(name: &str) -> String {
|
|
let whereis = Command::new("whereis")
|
|
.arg(&name)
|
|
.output()
|
|
.expect("Unable to execute whereis");
|
|
let whereis_output = String::from_utf8(whereis.stdout).unwrap();
|
|
|
|
whereis_output
|
|
.split(" ")
|
|
.skip(1)
|
|
.next()
|
|
.expect(&format!("Unable to find {}: {}", name, whereis_output))
|
|
.split("\n")
|
|
.next()
|
|
.unwrap()
|
|
.to_owned()
|
|
}
|