Change clang-command to ld, add util.rs
This commit is contained in:
		
							parent
							
								
									d0aa3e1410
								
							
						
					
					
						commit
						922afaa672
					
				
							
								
								
									
										39
									
								
								libtest.sh
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								libtest.sh
									
									
									
									
									
								
							| @ -7,5 +7,40 @@ | ||||
| 
 | ||||
| export .env | ||||
| cargo run --example libtest && \ | ||||
| clang++ main.cpp hello.o -o main && \ | ||||
| ./main | ||||
| # clang++ main.cpp hello.o -o main && \ | ||||
| ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \ | ||||
|    -o main /usr/lib/crt1.o hello.o -lc  && \ | ||||
| ./main ; echo $? | ||||
| 
 | ||||
| 
 | ||||
| ## Command from: clang -v hello.o -o test | ||||
| ## Original command: | ||||
| # ld --hash-style=gnu \ | ||||
| #    --build-id \ | ||||
| #    --eh-frame-hdr \ | ||||
| #     -m elf_x86_64 \ | ||||
| #     -pie \ | ||||
| #     -dynamic-linker /lib64/ld-linux-x86-64.so.2 \ | ||||
| #     -o test \ | ||||
| #     /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/15.1.1/../../../../lib64/Scrt1.o \ | ||||
| #     /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/15.1.1/../../../../lib64/crti.o \ | ||||
| #     /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/15.1.1/crtbeginS.o \ | ||||
| #     -L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/15.1.1 \ | ||||
| #     -L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/15.1.1/../../../../lib64 \ | ||||
| #     -L/lib/../lib64 \ | ||||
| #     -L/usr/lib/../lib64 \ | ||||
| #     -L/lib \ | ||||
| #     -L/usr/lib \ | ||||
| #     hello.o \ | ||||
| #     -lgcc \ | ||||
| #     --as-needed \ | ||||
| #     -lgcc_s \ | ||||
| #     --no-as-needed \ | ||||
| #     -lc \ | ||||
| #     -lgcc \ | ||||
| #     --as-needed \ | ||||
| #     -lgcc_s \ | ||||
| #     --no-as-needed \ | ||||
| #     /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/15.1.1/crtendS.o \ | ||||
| #     /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/15.1.1/../../../../lib64/crtn.o \ | ||||
| #     && \ | ||||
| @ -1,10 +1,16 @@ | ||||
| use reid_lib::*; | ||||
| 
 | ||||
| pub fn main() { | ||||
|     // Notes from inkwell:
 | ||||
|     // - Creating new values should probably just be functions in the context
 | ||||
|     // - Creating functions should probably be functions from module
 | ||||
|     // - Builder could well be it's own struct
 | ||||
|     // - Although, I do like the fact where blocks move the builder by itself..
 | ||||
| 
 | ||||
|     let context = IRContext::new(); | ||||
|     let module = IRModule::new(&context, &"hello".to_owned()); | ||||
| 
 | ||||
|     let mainfunc = IRFunction::new(&module, &"mainfunc".to_owned()); | ||||
|     let mainfunc = IRFunction::new(&module, &"main".to_owned()); | ||||
| 
 | ||||
|     let secondary_func = IRFunction::new(&module, &"secondary".to_owned()); | ||||
| 
 | ||||
|  | ||||
| @ -1,46 +1,22 @@ | ||||
| use std::ffi::{CStr, CString, c_char}; | ||||
| use std::ffi::{CStr, CString}; | ||||
| use std::marker::PhantomData; | ||||
| use std::mem; | ||||
| use std::ptr::{null, null_mut}; | ||||
| use std::ptr::null_mut; | ||||
| 
 | ||||
| use llvm_sys::analysis::LLVMVerifyModule; | ||||
| use llvm_sys::target::{ | ||||
|     LLVM_InitializeAllAsmParsers, LLVM_InitializeAllAsmPrinters, LLVM_InitializeAllTargetInfos, | ||||
|     LLVM_InitializeAllTargetMCs, LLVM_InitializeAllTargets, LLVM_InitializeNativeAsmParser, | ||||
|     LLVM_InitializeNativeTarget, LLVMInitializeAMDGPUAsmPrinter, LLVMInitializeX86Target, | ||||
|     LLVMInitializeX86TargetInfo, LLVMInitializeX86TargetMC, LLVMSetModuleDataLayout, | ||||
|     LLVM_InitializeAllTargetMCs, LLVM_InitializeAllTargets, LLVMSetModuleDataLayout, | ||||
| }; | ||||
| use llvm_sys::target_machine::{ | ||||
|     LLVMCodeGenFileType, LLVMCreateTargetDataLayout, LLVMCreateTargetMachine, | ||||
|     LLVMGetDefaultTargetTriple, LLVMGetFirstTarget, LLVMGetHostCPUFeatures, LLVMGetHostCPUName, | ||||
|     LLVMGetTargetFromTriple, LLVMTargetMachineEmitToFile, LLVMTargetMachineEmitToMemoryBuffer, | ||||
| }; | ||||
| use llvm_sys::transforms::pass_manager_builder::{ | ||||
|     LLVMPassManagerBuilderCreate, LLVMPassManagerBuilderPopulateModulePassManager, | ||||
|     LLVMPassManagerBuilderSetOptLevel, | ||||
|     LLVMGetDefaultTargetTriple, LLVMGetTargetFromTriple, LLVMTargetMachineEmitToFile, | ||||
| }; | ||||
| use llvm_sys::{ | ||||
|     LLVMBasicBlock, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue, core::*, prelude::*, | ||||
| }; | ||||
| use util::{ErrorMessageHolder, from_cstring, into_cstring}; | ||||
| 
 | ||||
| fn into_cstring<T: Into<String>>(value: T) -> CString { | ||||
|     let string = value.into(); | ||||
|     unsafe { CString::from_vec_with_nul_unchecked((string + "\0").into_bytes()) } | ||||
| } | ||||
| 
 | ||||
| fn from_cstring(value: *mut c_char) -> Option<String> { | ||||
|     if value.is_null() { | ||||
|         None | ||||
|     } else { | ||||
|         unsafe { CString::from_raw(value).into_string().ok() } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn cstring_to_err(value: *mut c_char) -> Result<(), String> { | ||||
|     from_cstring(value) | ||||
|         .filter(|s| !s.is_empty()) | ||||
|         .map_or(Ok(()), |s| Err(s)) | ||||
| } | ||||
| mod util; | ||||
| 
 | ||||
| pub trait IRType { | ||||
|     const SIGNED: LLVMBool; | ||||
| @ -131,12 +107,6 @@ impl<'a> IRModule<'a> { | ||||
| 
 | ||||
|     pub fn print_to_string(&self) -> Result<&str, String> { | ||||
|         unsafe { | ||||
|             // let pmb = LLVMPassManagerBuilderCreate();
 | ||||
|             // LLVMPassManagerBuilderSetOptLevel(pmb, 0);
 | ||||
|             // let pm = LLVMCreatePassManager();
 | ||||
|             // LLVMPassManagerBuilderPopulateModulePassManager(pmb, pm);
 | ||||
|             // println!("{}", LLVMRunPassManager(pm, self.module));
 | ||||
| 
 | ||||
|             LLVM_InitializeAllTargets(); | ||||
|             LLVM_InitializeAllTargetInfos(); | ||||
|             LLVM_InitializeAllTargetMCs(); | ||||
| @ -146,10 +116,14 @@ impl<'a> IRModule<'a> { | ||||
|             let triple = LLVMGetDefaultTargetTriple(); | ||||
| 
 | ||||
|             let mut target: _ = null_mut(); | ||||
|             let mut err: _ = null_mut(); | ||||
|             LLVMGetTargetFromTriple(c"x86_64-unknown-linux-gnu".as_ptr(), &mut target, &mut err); | ||||
|             let mut err = ErrorMessageHolder::null(); | ||||
|             LLVMGetTargetFromTriple( | ||||
|                 c"x86_64-unknown-linux-gnu".as_ptr(), | ||||
|                 &mut target, | ||||
|                 err.borrow_mut(), | ||||
|             ); | ||||
|             println!("{:?}, {:?}", from_cstring(triple), target); | ||||
|             cstring_to_err(err).unwrap(); | ||||
|             err.into_result().unwrap(); | ||||
| 
 | ||||
|             let target_machine = LLVMCreateTargetMachine( | ||||
|                 target, | ||||
| @ -164,33 +138,33 @@ impl<'a> IRModule<'a> { | ||||
|             let data_layout = LLVMCreateTargetDataLayout(target_machine); | ||||
|             LLVMSetModuleDataLayout(self.module, data_layout); | ||||
| 
 | ||||
|             let mut err = null_mut(); | ||||
|             let mut err = ErrorMessageHolder::null(); | ||||
|             LLVMVerifyModule( | ||||
|                 self.module, | ||||
|                 llvm_sys::analysis::LLVMVerifierFailureAction::LLVMPrintMessageAction, | ||||
|                 &mut err, | ||||
|                 err.borrow_mut(), | ||||
|             ); | ||||
|             cstring_to_err(err).unwrap(); | ||||
|             err.into_result().unwrap(); | ||||
| 
 | ||||
|             let mut err = null_mut(); | ||||
|             let mut err = ErrorMessageHolder::null(); | ||||
|             LLVMTargetMachineEmitToFile( | ||||
|                 target_machine, | ||||
|                 self.module, | ||||
|                 CString::new("hello.asm").unwrap().into_raw(), | ||||
|                 LLVMCodeGenFileType::LLVMAssemblyFile, | ||||
|                 &mut err, | ||||
|                 err.borrow_mut(), | ||||
|             ); | ||||
|             cstring_to_err(err).unwrap(); | ||||
|             err.into_result().unwrap(); | ||||
| 
 | ||||
|             let mut err = null_mut(); | ||||
|             let mut err = ErrorMessageHolder::null(); | ||||
|             LLVMTargetMachineEmitToFile( | ||||
|                 target_machine, | ||||
|                 self.module, | ||||
|                 CString::new("hello.o").unwrap().into_raw(), | ||||
|                 LLVMCodeGenFileType::LLVMObjectFile, | ||||
|                 &mut err, | ||||
|                 err.borrow_mut(), | ||||
|             ); | ||||
|             cstring_to_err(err).unwrap(); | ||||
|             err.into_result().unwrap(); | ||||
| 
 | ||||
|             Ok(CStr::from_ptr(LLVMPrintModuleToString(self.module)) | ||||
|                 .to_str() | ||||
|  | ||||
							
								
								
									
										51
									
								
								reid-llvm-lib/src/util.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								reid-llvm-lib/src/util.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| use std::{ | ||||
|     ffi::{CString, c_char}, | ||||
|     ptr::null_mut, | ||||
| }; | ||||
| 
 | ||||
| use llvm_sys::error::LLVMDisposeErrorMessage; | ||||
| 
 | ||||
| pub fn into_cstring<T: Into<String>>(value: T) -> CString { | ||||
|     let string = value.into(); | ||||
|     unsafe { CString::from_vec_with_nul_unchecked((string + "\0").into_bytes()) } | ||||
| } | ||||
| 
 | ||||
| pub fn from_cstring(value: *mut c_char) -> Option<String> { | ||||
|     if value.is_null() { | ||||
|         None | ||||
|     } else { | ||||
|         unsafe { CString::from_raw(value).into_string().ok() } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn cstring_to_err(value: *mut c_char) -> Result<(), String> { | ||||
|     from_cstring(value) | ||||
|         .filter(|s| !s.is_empty()) | ||||
|         .map_or(Ok(()), |s| Err(s)) | ||||
| } | ||||
| 
 | ||||
| pub struct ErrorMessageHolder(*mut c_char); | ||||
| 
 | ||||
| impl ErrorMessageHolder { | ||||
|     pub fn null() -> Self { | ||||
|         ErrorMessageHolder(null_mut()) | ||||
|     } | ||||
| 
 | ||||
|     pub fn borrow_mut(&mut self) -> *mut *mut c_char { | ||||
|         &mut self.0 | ||||
|     } | ||||
| 
 | ||||
|     pub fn into_result(&self) -> Result<(), String> { | ||||
|         cstring_to_err(self.0) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Drop for ErrorMessageHolder { | ||||
|     fn drop(&mut self) { | ||||
|         unsafe { | ||||
|             if !self.0.is_null() { | ||||
|                 LLVMDisposeErrorMessage(self.0); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user