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