This example compiles a simple function using the LLVM C API through the llvm-sys crate.
Last active
August 15, 2025 17:32
-
-
Save iwillspeak/1fed07333f7187c25735e90d73b82468 to your computer and use it in GitHub Desktop.
Example of using LLVM from Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| target |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [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" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [package] | |
| name = "low_down" | |
| version = "0.1.0" | |
| authors = ["Will Speak <[email protected]>"] | |
| [[bin]] | |
| name = "low_down" | |
| path = "main.rs" | |
| [dependencies] | |
| llvm-sys = "*" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //! 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) } | |
| } |
Author
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-10package like this:llvm-10 = { package = "llvm-sys", version = "100", optional = true }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`
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Previously llvm-sys was called llvm_sys this error seems ot have happened for that reason.