llvm:dyld:找不到符号:__ZN4llvm11RuntimeDyld13MemoryManager6anchorEv

llvm: dyld: Symbol not found: __ZN4llvm11RuntimeDyld13MemoryManager6anchorEv

我正在玩 LLVM,但在尝试使用 JIT 时遇到了问题。我能够构建一个编译器,它可以被编译、链接并且它 运行s 正确(它编译我的玩具程序)。但是,当我尝试使用构建 JIT 时,它失败了。

dyld: Symbol not found: __ZN4llvm11RuntimeDyld13MemoryManager6anchorEv
  Referenced from: /Users/gruszczy/Projects/shwifty/./bazel-bin/_solib_darwin//liblibjit.so
  Expected in: flat namespace
 in /Users/gruszczy/Projects/shwifty/./bazel-bin/_solib_darwin//liblibjit.so
Abort trap: 6

我使用 Bazel 构建一切,这些是我的构建规则:

new_local_repository(
    name = "llvm",
    path = "/opt/local/libexec/llvm-4.0",
    build_file= "llvm.BUILD")

cc_library(
    name = "main",
    srcs = glob(["lib/*.a"]),
    hdrs = glob(["include/**/*.*"]),
    visibility = ["//visibility:public"],
    copts = ["-Iexternal/llvm/include"],
)

我在测试中使用 JIT(我在测试中生成 IR 然后 jit 它,然后 运行 方法以查看它是否有效)。

cc_library(
    name = "jit",
    srcs = ["jit.cc"],
    hdrs = ["jit.h"],
    deps = [
        ":ast",
        ":common",
        "@llvm//:main"
    ],
    copts = GENERAL_COPTS)

cc_test(
    name = "codegen_test",
    srcs = ["codegen_test.cc"],
    deps = [
        ":ast",
        ":jit",
        ":lexer",
        ":parser",
        ":codegen",
        "@gtest//:main",
        "@llvm//:main"
    ],
    copts = TEST_COPTS,
    data = [":examples"],
    size = "small"
)

有什么我可能遗漏的建议吗?

混淆的根源是 Bazel 默认情况下静态链接二进制文件,但动态测试。这使得测试代码重构循环更快,因为对测试代码的更改只会触发测试的重建,而不是整个应用程序。可以通过在 codegen_test 目标上设置 linkstatic = 1 来禁用它。

至于为什么在构建为共享库时 codegen_test 中没有这些符号,这个问题要难得多,需要更多特定于项目的信息。但是一个可能的解决方案可能是将生成 VMRuntimeDyld.aVMMCJit.a 的目标标记为 alwayslink = 1.

为了完整起见,这里是 link to an issue you reported on bazel