我已经解决了这个问题。您的 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/MachOTpics/1-Articles/executing_files.html为什么你需要压制。
我真的很喜欢这个问题(尽管我花了整整一天半的时间来理解和解决)。