Reputation: 745
I am new to LLVM compiler and infrastructure. I have the following thought. Clang is the LLVM front end for C/C++, similarly Rustc for Rust programming language. Both can emit the LLVM IR code and the emitted code can be compiled to executable application.
My question is is it possible to link different programming languages? Example shown below -
/* Code in C */
int add(int, int);
int main()
{
printf("%d", add(5 ,6));
}
The function defined in Rust for example
// Code in Rust
fn main()
{
println!("{}", add(5, 6));
}
fn add (x: i32, y: i32) -> i32
{
x + y
}
Once the IR is generated from both the source files, is it possible to link them and create a single application?
I am just curious to know if this works, please let me know.
Upvotes: 9
Views: 1989
Reputation: 299730
Short answer: Yes.
Long answer: Yes, as long as some requirements are fulfilled.
There are two kinds of compatibility: API (Application Program Interface) and ABI (Application Binary Interface). Essentially, the API dictates whether your program compiles whereas the ABI dictates whether it links, loads and runs.
Since Rust has a C FFI, Rust can emit code that can normally interact with C (it has the proper C ABI, for the considered platform). This is evident in that a Rust binary can call a C library.
If you take the LLVM IR of that Rust binary, the LLVM IR of that C library, merge both together, and use LLVM to produce a new binary, then you'll get a single binary (no dependency).
So, the "only" requirement is that your two pieces of code must be able to link/load/run independently first.
Another way to obtain a single binary, which is independent from LLVM, is static linking; in Rust you can for example static link with the musl implementation of the C standard library. The main advantage of merging at LLVM IR, is that you can then run LLVM optimization passes on the merged IR, and therefore benefit from cross-language inlining (and other optimizations).
Upvotes: 10
Reputation: 374
Firstly, Rust and C can talk but through Rust's FFI (Foreign Function Interface). For very basic functions, I imagine it would be possible to compile both languages to LLVM and have some sort of functionality but we're talking hello world length programs (maybe even not at that level though). In general there must be some sort of ABI to implement what you're suggesting. However, even with an ABI the implementation is done at the Front End level.
Concisely put, LLVM can't represent all language specific constructs. So you can't just link two program's LLVM IR and hope it works. There must be some work done at the front end to ensure compatibility between two languages.
Upvotes: 3