【问题标题】:Manual linking to Windows library in LLVM手动链接到 LLVM 中的 Windows 库
【发布时间】:2021-07-13 20:49:30
【问题描述】:

我正在编写自己的编程语言,并希望通过编译为 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 后的步骤对我来说是不透明的,我相信我使用了错误的链接器选项或者什么,因为我在 lld-link 步骤中得到lld-link: error: undefined symbol: _exit。 (实际上,当我尝试手动链接clang -S --emit-llvm 的输出时也会发生这种情况,所以我没有理由相信我的 IR 是问题所在)。我用于 lld-link 的当前调用是 lld-link /out:"exit.exe" /entry:main exit.obj。我尝试过添加各种风格的/defaultlib 开关,包括手动链接到libcmt 两个libucrt,我相信在使用dumpbin 查看符号后包含_exit,但这似乎没有帮助。查看 clang 程序的 IR 输出,似乎没有对 的任何特别引用,所以我猜在 IR 生成阶段之后信息会丢失,所以我认为我没有丢失我的 IR 中的任何内容。

这似乎是一个一般的 Windows 链接器问题,而不是与 LLVM 有任何关系,因为如果我这样做 link /out:exit.exe /entry:main exit.obj 我会得到基本相同的错误。

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

【问题讨论】:

    标签: windows linker llvm


    【解决方案1】:

    原来 libcmt 已被替换。替换是 ucrt,所以这样做 /defaultlib:ucrt 似乎可以解决问题!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-17
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多