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.
LLVM currently supports compiling of Ada, C, C++, D, Delphi, Fortran, Haskell, Julia, Objective-C, Rust, and Swift using various front ends.
LLVM IR can be cross-platform, with the obvious exceptions others have listed. However, that does not mean Clang generates cross-platform code. As you note, the preprocessor is almost universally used to only pass parts of the code to the C/C++ compiler, depending on the platform.
While LLVM and GCC both support a wide variety languages and libraries, they are licensed and developed differently. LLVM libraries are licensed more liberally and GCC has more restrictions for its reuse. When it comes to performance differences, GCC has been considered superior in the past.
C-like languages use the Clang front end. This component compiles C, C++, Objective C, and Objective C++ code into LLVM bitcode – and from there into object files, using LLVM. Other components include: the libc++ C++ standard library, the LLD linker, and more.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With