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