windows - 手动链接到 LLVM 中的 Windows 库
问题描述
我正在编写自己的编程语言,并希望通过编译为 LLVM IR 将其编译为本机二进制文件,然后让 LLVM 工具链的其余部分接管。最终,我将针对多个平台,但现在我只关注 Windows。
对于初学者,我编译的是空程序,这意味着通常我的工具链已设置并正在工作,并且我从中获得了一个无操作可执行文件。下一个合乎逻辑的步骤是执行“Hello World”,但是在查看了简单调用它的 C 程序的 clang 的 LLVM IR 输出之后,puts("Hello World!")
看起来更简单的第一步是简单地_exit();
. 在查看该 C 程序的 clang 输出时,看起来相关行是 to do 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: error: undefined symbol: _exit
在 lld-link 步骤期间。(实际上,当我尝试手动链接 的输出时也会发生这种情况clang -S --emit-llvm
,因此我没有理由相信我的 IR 是问题所在)。我用于 lld-link 的当前调用是lld-link /out:"exit.exe" /entry:main exit.obj
. 我尝试过添加各种风格的/defaultlib
开关,包括手动链接到 libcmt 两个 libucrt,我认为在查看符号后包含 _exitdumpbin
,但这似乎没有帮助。查看 clang 程序的 IR 输出,似乎没有对 <stdlib.h> 的任何特别引用,所以我猜在 IR 生成阶段之后信息会丢失,所以我不认为我错过了我的 IR 中的任何内容。
这似乎是一个一般的 Windows 链接器问题,而不是与 LLVM 有任何关系,因为如果我这样做,link /out:exit.exe /entry:main exit.obj
我会得到基本相同的错误。
无论如何,在链接期间显然有一些我不明白的步骤,围绕如何找到给定外部调用所在的实际库,所以如果有人能指出我如何解决这个问题的正确方向给定 C 运行时调用,那就太好了。特别是在这种情况下,我想我需要找到包含 _exit 函数的库。谢谢!
解决方案
Turns out the libcmt has been replaced. The replacement is ucrt, and so doing /defaultlib:ucrt seems to fix the problem!
推荐阅读
- r - 使用 plm 对智能电表进行面板分析
- python - 如何从 yuv 框架中获取形状(宽度、高度、3)的额外尺寸值
- android - React Native:Android端的onPress以某种方式触发onNavigationStateChange
- google-apps-script - 无法在“为当前用户安装”配置下测试插件(即 AuthMode.NONE)
- json - 如何使用 linux shell 脚本将行分隔的 JSON 拆分为多个文件
- javascript - 如何在手风琴上创建打开和关闭状态?
- machine-learning - CNN 能否按指定比例减小输入大小
- mysql - 无法在 WordPress 中使用 wpdb->insert 查询插入数据库
- npm - 由于 Homebrew Python 安装导致 NPM 配置错误
- c# - 使用示例表的 Specflow 测试在测试运行器中显示空参数