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