【问题标题】:Building and using a pass for LLVM 3.8 on OSX在 OSX 上构建和使用 LLVM 3.8 的通行证
【发布时间】:2016-05-13 12:57:58
【问题描述】:

我正在尝试使用 llvm 3.8 在 OSX 上构建和应用通行证。 我使用 brew 使用以下公式安装了 llvm 3.8:$brew install llvm38 在通行证内,我有以下内容:

static RegisterPass<SwiftPass> X("pass", "My Pass");

我用来构建 pass 的 Makefile 如下所示:

LIB_NAME = pass$(SUFIX)
LDFLAGS = $(shell $(LLVM_PATH)llvm-config --ldflags)
CXXFLAGS = -g -Wall -fno-rtti -fPIC -std=c++11 -shared -dynamiclib $(shell $(LLVM_PATH)llvm-config  --cxxflags --system-libs --libs core executionengine interpreter mc support nativecodegen)
COMPILER = clang++
all: $(LIB_NAME)
$(LIB_NAME): $(OBJ)
    $(COMPILER) $(CXXFLAGS) $(LDFLAGS) $^ -o $@

如果给我几个clang: warning: -l[some lib]: 'linker' input unused。它也给了我:

clang: warning: argument unused during compilation: '-shared'
clang: warning: argument unused during compilation: '-dynamiclib'

但它会输出 .dylib 和 .o,所以我继续尝试。 所以现在我有了一个通行证,我可以将它应用到我的 .bc 文件中,为此我使用这样的 Makefile(为简洁起见,我省略了定义):

$(LLVM_OPT) -load $(PASSFILE) $(PASSNAME) $(NAME).bc -o $(NAME).afterMyPass.bc

这转化为:

opt -load pass.dylib -pass int.bc -o int.afterMyPass.bc

然后把这个还给我:

opt: Unknown command line argument '-pass'.  Try: '/usr/local/Cellar/llvm38/3.8.0/lib/llvm-3.8/bin/opt -help'
opt: Did you mean '-slsr'?
make: *** [pass] Error 1

我的猜测是这是由编译期间未使用的参数引起的,但我不知道为什么它们首先未被使用,因为它们是构建共享库所必需的。

我做错了什么,我该如何解决?

【问题讨论】:

  • opt -load pass.dylib -help 有什么作用?
  • $opt -load pass.dylib -help 概述:llvm .bc -> .bc 模块化优化器和分析打印机用法:opt [options] OPTIONS: ...
  • 我想知道帮助中是否显示'-pass'?
  • 不,没有。最佳匹配是 -run-pass= - 只为一个特定的 pass 运行编译器。我会试试这个,看看会发生什么。
  • 你能分享完整的makefile吗?我想我可以解决这个问题。或者除了后缀和llvm_path之外,您的makefile与问题中给出的几乎相同?

标签: c++ macos makefile llvm llvm-ir


【解决方案1】:

我已经解决了这个问题。您的 Makefile 有两个问题。

首先,如果您是平面命名空间,则需要通过传递 ld 标志来抑制未定义符号。或者在使用两级命名空间时使用动态查找进行链接。

当您解决第一个问题时会发生第二个问题。它在 opt 执行期间导致平面命名空间:

命令行错误:选项“pass-remarks”注册了多次! LLVM 错误:注册的命令行选项不一致

您不需要将 --libs 传递给 llvm-config。它会导致与来自 opt 和您的通行证的符号发生冲突。在二级命名空间中,它不会给出这个错误。只是你的选项是未知的命令行参数,就像以前的错误一样。

我的 Makefile(我也有一个注释 ldflag 用于默认的两级命名空间。LLVM 项目使用平面命名空间,所以我使用了它):

SUFIX=.so
OBJ=pass.o
LIB_NAME = pass$(SUFIX)
LLVM_PATH=/usr/local/Cellar/llvm38/3.8.0/bin/
LDFLAGS = $(shell $(LLVM_PATH)llvm-config-3.8 --ldflags)
LDFLAGS +=-Wl,-dead_strip -Wl,-flat_namespace -Wl,-undefined -Wl,suppress
#LDFLAGS += -Wl,-dead_strip -Wl,-undefined,dynamic_lookup
CXXFLAGS = -g -Wall -fno-rtti -fPIC -std=c++11 $(shell $(LLVM_PATH)llvm-config-3.8  --cxxflags --system-libs)
COMPILER = clang++
all: $(LIB_NAME)
$(LIB_NAME): $(OBJ)
        $(COMPILER) $(CXXFLAGS) -bundle $(LDFLAGS) $^ -o $@
$(OBJ): pass.cpp
        $(COMPILER) $(CXXFLAGS) -c $^ -o $@

为了正确起见,我所做的另一个小改动是添加了 -bundle,因为它不是共享库,而是无法作为库链接的可加载包。如果你不添加它,没关系,但你的输出不是捆绑的。

Stackoverflow 导致 makefile 出现问题。复制时用空格替换制表符。另请参阅:https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/MachOTopics/1-Articles/executing_files.html,了解为什么需要压制。

我真的很喜欢这个问题(尽管我花了整整 1 天半的时间来理解和解决)。

【讨论】:

  • 稍微调整一下我的SUFIX就是.dylib
  • 是的。 LLVM 项目使用 dylib。但是,如果您尝试“file "PassName.dylib"" for llvm pass ,您会看到它是捆绑包。对于捆绑包,苹果建议使用 .bundle 或 .so。所以我更喜欢那个。不过没关系。
猜你喜欢
  • 2016-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多