在Mac上使用带有自定义LLVM传递的opt时未定义的符号

时间:2018-04-19 07:55:03

标签: c++ macos cmake linker llvm

我想帮助找出这个令人头疼的问题。对不起,很长的帖子!

环境

  • Mac OS X,10.10.5“Yosemite”
  • Clang / LLVM 6.0.0,源于2018年3月9日来源
  • C ++ 14源代码
  • CMake 3.11.0
  • Ninja 1.8.2

注意:我没有Apple的Clang / LLVM工具链 - 我在2016年小心地删除了它,然后用在线提供的UIUC稳定版本替换它。我能找到的与网上相关的每个问题都是因为Apple特有的。我仔细检查以确保我在CMake中链接的Clang / LLVM工具链确实是正确的(我唯一拥有的)。

如果您需要了解其他任何内容,请与我们联系。

背景

所以我正在使用自己的C ++头文件/类文件编写自定义LLVM传递。我有以下目录结构:

.
├── CMakeLists.txt
├── lib
│   ├── libgraphs.a
│   ├── libprograms.a
│   ├── libvisitors.a
│   └── passes.so
├── include
│   ├── graphs
│   │   └── (...)
│   ├── passes
│   │   └── (...)
│   ├── programs
│   │   └── (...)
│   └── visitors
│       └── (...)
└── src
    ├── CMakeLists.txt
    ├── graphs
    │   ├── CMakeLists.txt
    │   └── (...)
    ├── passes
    │   ├── CMakeLists.txt
    │   └── (...)
    ├── programs
    │   ├── CMakeLists.txt
    │   └── (...)
    └── visitors
        ├── CMakeLists.txt
        └── (...)

(...)标记包含include中的自定义头文件和src中的C ++实现。我有点确定这个设置是正确的,一切都很好。

我正在使用CMake将整个项目串在一起,而我现在遇到的一个问题是链接时错误。现在,每个CMakeLists.txt在每个子目录级别中都很好地构建。但是,我不确定事情是否真的被联系在一起。因此,我的所有库文件都生成为lib。这里我有实际传递的共享库以及为每个子目录生成的静态库。我现在没有做任何特别的事情将这些联系在一起,我认为这就是问题。

问题

我要做的是以下内容。我在Hello.cpp中有一个非常简单的programs文件,我已经使用

将其编译为bitcode
clang++ -std=c++14 -emit-llvm -c src/programs/Hello.cpp -o src/programs/Hello.bc

然后,我想申请我的通行证(以下匿名标志):

opt -load lib/passes.so -[FLAG] < src/programs/Hello.bc

当我这样做时,我收到以下链接时错误(下面匿名的错位名称):

Error opening 'lib/passes.so': dlopen(lib/passes.so, 9):
  Symbol not found: [mangled_name]
    Referenced from: lib/passes.so
    Expected in: flat namespace
  in lib/passes.so

尝试解决方案

我在已修改的名称上使用了c++filt来查看它是什么,它是我的一个自定义头文件中的类名:

$ c++filt [mangled_name]
  vtable for [namespace]::[custom_visitor_class]

所以在我看来,静态库libvisitors.a至少没有被链接到共享库passes.so,所以尽管所有单元编译都很好,但仍存在链接时失败。

有没有办法解决这个问题?在CMakeLists.txt中,我尝试使用link_directories(lib),以便静态库全部链接,但每次都得到相同的结果。我花了几个小时在谷歌和各种旧的StackOverflow帖子上,但一切都是(1)来自旧版LLVM的不同配置或(2)一个似乎对我不起作用的解决方案(虽然它可能我误解了它!)。

我真的需要一些帮助来消除这些链接时错误。我认为它们只发生在我使用自定义标头时,就像我只使用标准的LLVM库(当前链接很好)没有任何自己的包装器一样,任何生成的.so都能正常工作并完成它的设想到。

我设法从谷歌确定的一件事是,这是特定于OS X的,可能不会在Linux上发生。不幸的是,我没有备用的LLVM工具链设置的Linux机器,但我真的相信花2个小时从源代码构建最新版本并在该环境下测试我的程序。

有什么想法吗?

0 个答案:

没有答案