1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
use std::{ffi, ptr}; use llvm_sys::core::*; use llvm_sys::target_machine::*; enum TripleString { Cross(ffi::CString), LlvmDefault(*mut libc::c_char), } impl TripleString { fn as_ptr(&self) -> *const libc::c_char { match self { TripleString::Cross(cross_triple) => cross_triple.as_ptr() as *const _, TripleString::LlvmDefault(llvm_default) => *llvm_default, } } } impl Drop for TripleString { fn drop(&mut self) { if let TripleString::LlvmDefault(llvm_default) = self { unsafe { LLVMDisposeMessage(*llvm_default); } } } } pub fn create_target_machine( cross_triple: Option<&str>, reloc_mode: LLVMRelocMode, code_model: LLVMCodeModel, ) -> LLVMTargetMachineRef { let cross_triple = cross_triple.map(|cross_triple| ffi::CString::new(cross_triple).unwrap()); unsafe { let mut target: LLVMTargetRef = ptr::null_mut(); let triple_string = cross_triple .map(|cross_triple| TripleString::Cross(ffi::CString::new(cross_triple).unwrap())) .unwrap_or_else(|| TripleString::LlvmDefault(LLVMGetDefaultTargetTriple())); let mut error: *mut libc::c_char = ptr::null_mut(); if LLVMGetTargetFromTriple(triple_string.as_ptr(), &mut target, &mut error as *mut _) != 0 { panic!( "LLVMGetTargetFromTriple({:?}): {}", ffi::CStr::from_ptr(triple_string.as_ptr()) .to_str() .unwrap(), ffi::CStr::from_ptr(error).to_str().unwrap() ); } LLVMCreateTargetMachine( target, triple_string.as_ptr(), ptr::null(), ptr::null(), LLVMCodeGenOptLevel::LLVMCodeGenLevelDefault, reloc_mode, code_model, ) } }