手动链接到 LLVM 中的 Windows 库

Manual linking to Windows library in LLVM

我正在编写自己的编程语言,我想通过编译为 LLVM IR 将其编译为本机二进制文件,然后让 LLVM 工具链的其余部分接管。最终,我将针对多个平台,但现在我只关注 Windows.

对于初学者来说,我编译了一个空程序,这意味着我的工具链通常已经设置好并且可以正常工作,并且我从中得到了一个无操作可执行文件。下一个合乎逻辑的步骤是执行“Hello World”,但是在查看了简单调用 puts("Hello World!") 的 C 程序的 clang 的 LLVM IR 输出之后,看起来更简单的第一步是简单地调用 _exit();。查看该 C 程序的 clang 输出时,相关行似乎是执行 call void @_exit(i32 0)。我已经将它提炼成我认为是调用 exit:

的最低限度程序
define i64* @main() {
    %1 = alloca i32, align 4
    store i32 0, i32* %1, align 4
    call void @_exit(i32 0)
    unreachable
}
declare dso_local void @_exit(i32)

当直接尝试 运行 等效的 C 程序时,当我直接使用 clang 时它当然有效,但是创建 LLVM IR 之后的步骤对我来说是不透明的,我相信我使用了错误的 linker 选项或其他东西,因为我在 lld-link 步骤中得到 lld-link: error: undefined symbol: _exit。 (实际上,当我尝试手动 link clang -S --emit-llvm 的输出时也会发生这种情况,所以我没有理由相信我的 IR 是问题所在)。我为 lld-link 使用的当前调用是 lld-link /out:"exit.exe" /entry:main exit.obj。我试过添加各种风格的 /defaultlib 开关,包括手动 linking 到 libcmt 两个 libucrt,我相信在使用 dumpbin 查看符号后包含 _exit,但是这似乎没有帮助。查看 clang 程序的 IR 输出,似乎没有对 的任何特定引用,所以我猜信息在 IR 生成阶段后丢失,所以我不认为我'我的 IR 中缺少任何内容。

这似乎是一个普遍的 Windows linker 问题,与 LLVM 无关,因为如果我这样做 link /out:exit.exe /entry:main exit.obj 我会得到基本相同的错误。

无论如何,在 linking 期间显然有一些我不明白的步骤,关于如何找到给定外部调用所在的实际库,所以如果有人可以指出我如何为任何给定的 C 运行time 调用解决这个问题的正确方向,那就太好了。特别是在这种情况下,我想我需要找到包含 _exit 函数的库。谢谢!

原来 libcmt 已被替换。替换为 ucrt,因此 /defaultlib:ucrt 似乎可以解决问题![​​=10=]