This example compiles a simple function using the LLVM C API through the llvm-sys
crate.
-
-
Save iwillspeak/1fed07333f7187c25735e90d73b82468 to your computer and use it in GitHub Desktop.
target |
[root] | |
name = "low_down" | |
version = "0.1.0" | |
dependencies = [ | |
"llvm-sys 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
] | |
[[package]] | |
name = "bitflags" | |
version = "0.5.0" | |
source = "registry+https://github.com/rust-lang/crates.io-index" | |
[[package]] | |
name = "gcc" | |
version = "0.3.37" | |
source = "registry+https://github.com/rust-lang/crates.io-index" | |
[[package]] | |
name = "libc" | |
version = "0.2.17" | |
source = "registry+https://github.com/rust-lang/crates.io-index" | |
[[package]] | |
name = "llvm-sys" | |
version = "0.4.0" | |
source = "registry+https://github.com/rust-lang/crates.io-index" | |
dependencies = [ | |
"bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
"gcc 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)", | |
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", | |
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", | |
] | |
[[package]] | |
name = "semver" | |
version = "0.1.20" | |
source = "registry+https://github.com/rust-lang/crates.io-index" | |
[metadata] | |
"checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" | |
"checksum gcc 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "41337e9dc80ebadf36b4f252bf7440f61bcf34f99caa170e50dcd0f9a0cdb5d8" | |
"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8" | |
"checksum llvm-sys 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "53757e4a2a442608cd0c9d50b555695e299a459a94dc25970d60dc5bc5674449" | |
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" |
[package] | |
name = "low_down" | |
version = "0.1.0" | |
authors = ["Will Speak <will@willspeak.me>"] | |
[[bin]] | |
name = "low_down" | |
path = "main.rs" | |
[dependencies] | |
llvm-sys = "*" |
//! Example of Using LLVM from Rust | |
extern crate llvm_sys; | |
use std::ffi::CStr; | |
use llvm_sys::prelude::*; | |
use llvm_sys::{core, target}; | |
/// Initialise LLVM | |
/// | |
/// Makes sure that the parts of LLVM we are going to use are | |
/// initialised before we do anything with them. | |
fn initialise_llvm() { | |
unsafe { | |
if target::LLVM_InitializeNativeTarget() != 0 { | |
panic!("Could not initialise target"); | |
} | |
if target::LLVM_InitializeNativeAsmPrinter() != 0 { | |
panic!("Could not initialise ASM Printer"); | |
} | |
} | |
} | |
/// Compile Module | |
/// | |
/// Creates a new LLVM module and compiles a simple funciton in it. | |
fn compile() -> LLVMModuleRef { | |
// Create a module to compile the expression into | |
let mod_name = CStr::from_bytes_with_nul(b"hello\0").unwrap(); | |
let module = unsafe { core::LLVMModuleCreateWithName(mod_name.as_ptr()) }; | |
// Create a function type and add a function of that type to the module | |
let function_type = unsafe { | |
let int64 = core::LLVMInt64Type(); | |
let mut param_types = [int64, int64]; | |
core::LLVMFunctionType(int64, param_types.as_mut_ptr(), param_types.len() as u32, 0) | |
}; | |
let function_name = CStr::from_bytes_with_nul(b"test\0").unwrap(); | |
let function = | |
unsafe { core::LLVMAddFunction(module, function_name.as_ptr(), function_type) }; | |
// Create a basic block and add it to the function | |
let block_name = CStr::from_bytes_with_nul(b"entry\0").unwrap(); | |
let entry_block = unsafe { core::LLVMAppendBasicBlock(function, block_name.as_ptr()) }; | |
// Create an LLVM instruction builder and position it at our new | |
// basic block | |
let builder = unsafe { | |
let b = core::LLVMCreateBuilder(); | |
core::LLVMPositionBuilderAtEnd(b, entry_block); | |
b | |
}; | |
// Fill in the body of the function. | |
unsafe { | |
let a = core::LLVMGetParam(function, 0); | |
let b = core::LLVMGetParam(function, 1); | |
let temp_name = CStr::from_bytes_with_nul(b"temp.1\0").unwrap(); | |
let res = core::LLVMBuildAdd(builder, a, b, temp_name.as_ptr()); | |
core::LLVMBuildRet(builder, res); | |
} | |
// Clean up the builder now that we are finished using it. | |
unsafe { core::LLVMDisposeBuilder(builder) } | |
module | |
} | |
fn main() { | |
initialise_llvm(); | |
let module = compile(); | |
// Dump the LLVM IR to stdout so we can see what we've created | |
unsafe { core::LLVMDumpModule(module) } | |
// Clean up the module after we're done with it. | |
unsafe { core::LLVMDisposeModule(module) } | |
} |
Hi, I tried to compile your project (
cargo build
) withllvm-sys = "100"
and I got the following error:error[E0463]: can't find crate for `llvm_sys` --> main.rs:3:1 | 3 | extern crate llvm_sys; | ^^^^^^^^^^^^^^^^^^^^^^ can't find crate
Do you know why I got this error and how to fix it?
EDIT:
Apparently, there is only an error with the latest stable release (
1.54
) but it works with1.53
Previously llvm-sys was called llvm_sys this error seems ot have happened for that reason.
This is old code. Previously I think rust normalised crate names when converting them to crate identifiers. Characters such as -
in names became _
in the identifier.
As I say. Old code.
Not sure i'm afraid. I haven't built this code in quite some time. In my more recent code I reference the
llvm-10
package like this:llvm-10 = { package = "llvm-sys", version = "100", optional = true }https://github.com/iwillspeak/ullage/blob/464d73f28df781a543f2f6a7faec634fae1572c5/Cargo.toml#L19
And then import it like this:
#[cfg(feature = "llvm-10")] use llvm_10 as llvm_sys;
Then when i try cargo build i get this error:
error[E0433]: failed to resolve: use of undeclared crate or module `llvm_sys`
--> src\main.rs:7:5
|
7 | use llvm_sys::prelude::*;
| ^^^^^^^^ use of undeclared crate or module `llvm_sys`
Not sure i'm afraid. I haven't built this code in quite some time. In my more recent code I
reference the
llvm-10
package like this:https://github.com/iwillspeak/ullage/blob/464d73f28df781a543f2f6a7faec634fae1572c5/Cargo.toml#L19
And then import it like this:
https://github.com/iwillspeak/ullage/blob/464d73f28df781a543f2f6a7faec634fae1572c5/src/low_loader.rs#L26