Add LDRunner
This commit is contained in:
parent
c622d59c93
commit
1a65b4085f
0
examples/ptr.reid
Normal file → Executable file
0
examples/ptr.reid
Normal file → Executable file
@ -16,8 +16,9 @@ BINARY="$(echo $1 | cut -d'.' -f1)"".out"
|
||||
|
||||
echo $1
|
||||
|
||||
make clean SRC=$1 ; make SRC=$1 && echo ""
|
||||
|
||||
cargo run --example cli $@ && \
|
||||
sleep 0.1 && \
|
||||
chmod +x $BINARY && \
|
||||
$BINARY ; echo "Return value: ""$?"
|
||||
|
||||
## Command from: clang -v hello.o -o test
|
||||
|
@ -1,11 +1,18 @@
|
||||
use std::{env, fs, path::PathBuf};
|
||||
|
||||
use reid::{compile_simple, CustomIRs};
|
||||
use reid::{compile_simple, ld::LDRunner, CustomIRs};
|
||||
use reid_lib::compile::CompileOutput;
|
||||
|
||||
fn main() -> Result<(), std::io::Error> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if let Some(filename) = args.get(1) {
|
||||
let mut iter = args.into_iter().skip(1);
|
||||
if let Some(filename) = iter.next() {
|
||||
let mut libraries = Vec::new();
|
||||
while let Some(libname) = iter.next() {
|
||||
libraries.push(libname);
|
||||
}
|
||||
|
||||
dbg!(&filename);
|
||||
let path = PathBuf::from(filename).canonicalize().unwrap();
|
||||
let parent = path.with_extension("");
|
||||
let llvm_ir_path = parent.with_extension("ll");
|
||||
@ -46,6 +53,14 @@ fn main() -> Result<(), std::io::Error> {
|
||||
"Compilation took: {:.2}ms\n",
|
||||
(after.duration_since(before).unwrap().as_micros() as f32) / 1000.
|
||||
);
|
||||
|
||||
println!("Linking {:?}", &object_path);
|
||||
let linker = option_env!("LD").unwrap_or("ld").to_owned();
|
||||
let mut linker = LDRunner::from_command(linker).with_library("c".to_owned());
|
||||
for library in libraries {
|
||||
linker = linker.with_library(library);
|
||||
}
|
||||
linker.invoke(object_path);
|
||||
}
|
||||
Err(e) => panic!("{}", e),
|
||||
};
|
||||
|
67
reid/src/ld.rs
Normal file
67
reid/src/ld.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use std::{io::Read, path::PathBuf, process::Command};
|
||||
|
||||
pub struct LDRunner {
|
||||
command: String,
|
||||
dynamic_linker: String,
|
||||
libraries: Vec<String>,
|
||||
}
|
||||
|
||||
impl LDRunner {
|
||||
pub fn from_command(command: String) -> LDRunner {
|
||||
LDRunner {
|
||||
command,
|
||||
dynamic_linker: "ld-linux-x86-64.so.2".to_string(),
|
||||
libraries: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_library(mut self, lib: String) -> LDRunner {
|
||||
self.libraries.push(lib);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn invoke(&self, file: PathBuf) {
|
||||
let filepath = file.canonicalize().unwrap();
|
||||
|
||||
let dyn_linker_path = find_objectfile(&self.dynamic_linker);
|
||||
let crt1_path = find_objectfile("crt1.o");
|
||||
|
||||
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(filepath.to_str().unwrap())
|
||||
.arg("-o")
|
||||
.arg(filepath.with_extension("out"));
|
||||
|
||||
println!("LDRunner: Executing linker to objfile at {:?}", filepath);
|
||||
dbg!(&ld);
|
||||
|
||||
ld.spawn().expect("Unable to execute ld!");
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
@ -55,6 +55,7 @@ use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream};
|
||||
mod ast;
|
||||
mod codegen;
|
||||
pub mod error_raporting;
|
||||
pub mod ld;
|
||||
mod lexer;
|
||||
pub mod mir;
|
||||
mod pad_adapter;
|
||||
|
@ -19,7 +19,9 @@ fn test(source: &str, name: &str) {
|
||||
|
||||
let context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION")));
|
||||
|
||||
assert_err(mir_context.codegen(&context));
|
||||
let codegen = assert_err(mir_context.codegen(&context));
|
||||
|
||||
codegen.compile();
|
||||
|
||||
Ok::<(), ()>(())
|
||||
})))
|
||||
|
Loading…
Reference in New Issue
Block a user