5

我是 LLVM 编译器和基础架构的新手。我有以下想法。Clang 是 C/C++ 的 LLVM 前端,类似于 Rust 编程语言的 Rustc。两者都可以发出 LLVM IR 代码,并且发出的代码可以编译为可执行的应用程序。

我的问题是可以链接不同的编程语言吗?示例如下 -

/* Code in C */
int add(int, int);
int main()
{
  printf("%d", add(5 ,6));
}

以 Rust 中定义的函数为例

// Code in Rust
fn main()
{
  println!("{}", add(5, 6));
}

fn add (x: i32, y: i32) -> i32
{
  x + y
}

从两个源文件生成 IR 后,是否可以链接它们并创建一个应用程序?

我只是想知道这是否有效,请告诉我。

4

2 回答 2

6

简短的回答:的。


长答案:是的,只要满足一些要求。

有两种兼容性:API(应用程序接口)和ABI(应用程序二进制接口)。从本质上讲,API 决定你的程序是否编译,而 ABI 决定它是否链接、加载和运行。

由于 Rust 具有 C FFI,Rust 可以发出通常可以与 C 交互的代码(它具有适当的 C ABI,适用于所考虑的平台)。这一点很明显,Rust 二进制文件可以调用 C 库。

如果你将那个 Rust 二进制文件的 LLVM IR 和那个 C 库的 LLVM IR 合并在一起,并使用 LLVM 生成一个新的二进制文件,那么你将得到一个二进制文件(无依赖关系)。

因此,“唯一”要求是您的两段代码必须能够首先独立链接/加载/运行。


获得独立于 LLVM 的单个二进制文件的另一种方法是静态链接;例如,在 Rust 中,您可以与 C 标准库的 musl 实现进行静态链接。在 LLVM IR 上合并的主要优点是,您可以在合并的 IR 上运行 LLVM 优化传递,因此可以从跨语言内联(和其他优化)中受益。

于 2016-07-07T15:12:33.463 回答
2

首先,Rust 和 C 可以对话,但要通过 Rust 的 FFI(Foreign Function Interface)。对于非常基本的功能,我想可以将两种语言编译为 LLVM 并具有某种功能,但我们正在谈论的是世界长度的程序(尽管甚至可能不在那个级别)。一般来说,必须有某种ABI来实现您的建议。然而,即使使用 ABI,实现也是在前端级别完成的。

简而言之,LLVM 不能代表所有特定于语言的结构。所以你不能只链接两个程序的 LLVM IR 并希望它有效。前端必须做一些工作来确保两种语言之间的兼容性。

于 2016-07-07T14:49:23.367 回答