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
|
echo $1
|
||||||
|
|
||||||
make clean SRC=$1 ; make SRC=$1 && echo ""
|
cargo run --example cli $@ && \
|
||||||
|
sleep 0.1 && \
|
||||||
|
chmod +x $BINARY && \
|
||||||
$BINARY ; echo "Return value: ""$?"
|
$BINARY ; echo "Return value: ""$?"
|
||||||
|
|
||||||
## Command from: clang -v hello.o -o test
|
## Command from: clang -v hello.o -o test
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
use std::{env, fs, path::PathBuf};
|
use std::{env, fs, path::PathBuf};
|
||||||
|
|
||||||
use reid::{compile_simple, CustomIRs};
|
use reid::{compile_simple, ld::LDRunner, CustomIRs};
|
||||||
use reid_lib::compile::CompileOutput;
|
use reid_lib::compile::CompileOutput;
|
||||||
|
|
||||||
fn main() -> Result<(), std::io::Error> {
|
fn main() -> Result<(), std::io::Error> {
|
||||||
let args: Vec<String> = env::args().collect();
|
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 path = PathBuf::from(filename).canonicalize().unwrap();
|
||||||
let parent = path.with_extension("");
|
let parent = path.with_extension("");
|
||||||
let llvm_ir_path = parent.with_extension("ll");
|
let llvm_ir_path = parent.with_extension("ll");
|
||||||
@ -46,6 +53,14 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
"Compilation took: {:.2}ms\n",
|
"Compilation took: {:.2}ms\n",
|
||||||
(after.duration_since(before).unwrap().as_micros() as f32) / 1000.
|
(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),
|
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 ast;
|
||||||
mod codegen;
|
mod codegen;
|
||||||
pub mod error_raporting;
|
pub mod error_raporting;
|
||||||
|
pub mod ld;
|
||||||
mod lexer;
|
mod lexer;
|
||||||
pub mod mir;
|
pub mod mir;
|
||||||
mod pad_adapter;
|
mod pad_adapter;
|
||||||
|
@ -19,7 +19,9 @@ fn test(source: &str, name: &str) {
|
|||||||
|
|
||||||
let context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION")));
|
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::<(), ()>(())
|
Ok::<(), ()>(())
|
||||||
})))
|
})))
|
||||||
|
Loading…
Reference in New Issue
Block a user