Add LDRunner

This commit is contained in:
Sofia 2025-07-23 18:57:56 +03:00
parent c622d59c93
commit 1a65b4085f
6 changed files with 91 additions and 5 deletions

0
examples/ptr.reid Normal file → Executable file
View File

View 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

View File

@ -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
View 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()
}

View File

@ -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;

View File

@ -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::<(), ()>(())
})))