在 OSX 上构建和使用 LLVM 3.8 的通行证
Building and using a pass for LLVM 3.8 on OSX
我正在尝试使用 llvm 3.8 在 OSX 上构建和应用传递。
我使用带有以下公式的 brew 安装了 llvm 3.8:$brew install llvm38
在通行证中我有以下内容:
static RegisterPass<SwiftPass> X("pass", "My 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
还有 returns 这对我来说:
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
我的猜测是,这是由编译期间未使用的参数引起的,但我不知道为什么它们首先未被使用,因为它们是构建共享库所必需的。
我做错了什么,我该如何解决?
我已经解决了这个问题。您的 Makefile 有两个问题。
首先,如果您是平面名称,您需要通过传递 ld 标志来抑制未定义符号space。或者在使用二级名称时使用动态查找链接space.
当您解决第一个问题时会出现第二个问题。它在执行 opt:
期间导致 flat namespace
CommandLine Error: Option 'pass-remarks' registered more than once!
LLVM ERROR: inconsistency in registered CommandLine options
您不需要将 --libs 传递给 llvm-config。它会导致与来自 opt 和您的通行证的符号发生冲突。在二级名称space中,它不会给出这个错误。只是你的选项是 Unknown command line argument like previous error.
我的 Makefile(我有一个默认的二级名称 space 的 ldflag 注释。LLVM 项目使用平面名称space,所以我使用了它):
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 只是为了正确性,因为它不是共享库而是可加载包,不能作为库链接。如果你不添加它,没关系,但你的输出不是捆绑的。
Whosebug 导致 makefile 出现问题。复制时用 spaces 替换制表符。另请参阅:https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/MachOTopics/1-Articles/executing_files.html 为什么需要抑制。
我真的很喜欢这个问题(尽管我花了整整 1 天半的时间来理解和解决)。
我正在尝试使用 llvm 3.8 在 OSX 上构建和应用传递。
我使用带有以下公式的 brew 安装了 llvm 3.8:$brew install llvm38
在通行证中我有以下内容:
static RegisterPass<SwiftPass> X("pass", "My 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
还有 returns 这对我来说:
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
我的猜测是,这是由编译期间未使用的参数引起的,但我不知道为什么它们首先未被使用,因为它们是构建共享库所必需的。
我做错了什么,我该如何解决?
我已经解决了这个问题。您的 Makefile 有两个问题。
首先,如果您是平面名称,您需要通过传递 ld 标志来抑制未定义符号space。或者在使用二级名称时使用动态查找链接space.
当您解决第一个问题时会出现第二个问题。它在执行 opt:
期间导致 flat namespaceCommandLine Error: Option 'pass-remarks' registered more than once! LLVM ERROR: inconsistency in registered CommandLine options
您不需要将 --libs 传递给 llvm-config。它会导致与来自 opt 和您的通行证的符号发生冲突。在二级名称space中,它不会给出这个错误。只是你的选项是 Unknown command line argument like previous error.
我的 Makefile(我有一个默认的二级名称 space 的 ldflag 注释。LLVM 项目使用平面名称space,所以我使用了它):
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 只是为了正确性,因为它不是共享库而是可加载包,不能作为库链接。如果你不添加它,没关系,但你的输出不是捆绑的。
Whosebug 导致 makefile 出现问题。复制时用 spaces 替换制表符。另请参阅:https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/MachOTopics/1-Articles/executing_files.html 为什么需要抑制。
我真的很喜欢这个问题(尽管我花了整整 1 天半的时间来理解和解决)。