在 OS X 上使用 LLVM 时出现未定义的符号错误

Undefined Symbol errors when using LLVM on OS X

我无法让 LLVM 在我的系统上运行。我对 GCC 和要传递的标志类型以及 makefile 的了解非常有限,如果有人能指出我正确的方向,我将不胜感激。

我在 OSX 并使用自制软件安装了 LLVM。 GCC无法找到的符号在我的系统中都存在,但由于某种原因无法找到。

这是我尝试使用下面的 makefile 编译的文件:

// STL 
#include <map>
#include <vector>
#include <utility>

// LLVM 
#include <llvm/Pass.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instruction.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/CFG.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/IR/InstIterator.h>
#include <llvm/IR/Constants.h>

// For older versions of llvm you may have to include instead:
// #include "llvm/Support/CFG.h"
// #include <llvm/Support/InstIterator.h>

using namespace llvm;

namespace {

class DefinitionPass  : public FunctionPass {
public:
    static char ID;
    DefinitionPass() : FunctionPass(ID) {}

    virtual void getAnalysisUsage(AnalysisUsage &au) const {
        au.setPreservesAll();
    }

    virtual bool runOnFunction(Function &F) {
            // TODO
            errs() << "def-pass\n";
        return false;
    }
};

class FixingPass : public FunctionPass {
public:
    static char ID;
    FixingPass() : FunctionPass(ID){}

    virtual bool runOnFunction(Function &F){
            // TODO
            errs() << "fix-pass\n";
        return true;
    }
};
} // namespace


char DefinitionPass::ID = 0;
char FixingPass::ID = 1;

// Pass registrations
static RegisterPass<DefinitionPass> X("def-pass", "Reaching definitions pass");
static RegisterPass<FixingPass> Y("fix-pass", "Fixing initialization pass");

制作文件:

CXXFLAGS = -rdynamic $(shell llvm-config --cxxflags) -g -O0 -std=c++0x

all: p34.so

%.so: %.o 
  $(CXX) $(CXXFLAGS) -dylib -shared -fPIC  $^ -o $@

clean:
  rm -f *.o *~ *.so

rdynamic 选项由于某种原因被忽略。

llvm-config --cxxflags 在我的系统上产生以下结果:

-I/usr/local/Cellar/llvm/9.0.0_1/include -std=c++11 -stdlib=libc++   -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS

这是我收到的错误消息:

c++ -rdynamic -I/usr/local/Cellar/llvm/9.0.0_1/include -std=c++11 -stdlib=libc++   -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -g -O0 -std=c++0x -I/usr/local/opt/llvm/include  -c -o p34.o p34.cpp
clang: warning: argument unused during compilation: '-rdynamic' [-Wunused-command-line-argument]
c++ -rdynamic -I/usr/local/Cellar/llvm/9.0.0_1/include -std=c++11 -stdlib=libc++   -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -g -O0 -std=c++0x -dylib -shared -fPIC  p34.o -o p34.so
Undefined symbols for architecture x86_64:
  "llvm::raw_ostream::write(char const*, unsigned long)", referenced from:
      llvm::raw_ostream::operator<<(llvm::StringRef) in p34.o
  "llvm::FunctionPass::assignPassManager(llvm::PMStack&, llvm::PassManagerType)", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::PassRegistry::registerPass(llvm::PassInfo const&, bool)", referenced from:
      llvm::RegisterPass<(anonymous namespace)::DefinitionPass>::RegisterPass(llvm::StringRef, llvm::StringRef, bool, bool) in p34.o
      llvm::RegisterPass<(anonymous namespace)::FixingPass>::RegisterPass(llvm::StringRef, llvm::StringRef, bool, bool) in p34.o
  "llvm::PassRegistry::getPassRegistry()", referenced from:
      llvm::RegisterPass<(anonymous namespace)::DefinitionPass>::RegisterPass(llvm::StringRef, llvm::StringRef, bool, bool) in p34.o
      llvm::RegisterPass<(anonymous namespace)::FixingPass>::RegisterPass(llvm::StringRef, llvm::StringRef, bool, bool) in p34.o
  "llvm::DisableABIBreakingChecks", referenced from:
      llvm::VerifyDisableABIBreakingChecks in p34.o
  "llvm::Pass::releaseMemory()", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::Pass::dumpPassStructure(unsigned int)", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::Pass::getAsImmutablePass()", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::Pass::getAsPMDataManager()", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::Pass::preparePassManager(llvm::PMStack&)", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::Pass::getAdjustedAnalysisPointer(void const*)", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::Pass::~Pass()", referenced from:
      llvm::FunctionPass::~FunctionPass() in p34.o
  "llvm::errs()", referenced from:
      (anonymous namespace)::DefinitionPass::runOnFunction(llvm::Function&) in p34.o
      (anonymous namespace)::FixingPass::runOnFunction(llvm::Function&) in p34.o
  "llvm::FunctionPass::createPrinterPass(llvm::raw_ostream&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::FunctionPass::getPotentialPassManagerType() const", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::Pass::getPassName() const", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::Pass::verifyAnalysis() const", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::Pass::getAnalysisUsage(llvm::AnalysisUsage&) const", referenced from:
      vtable for (anonymous namespace)::FixingPass in p34.o
  "llvm::Pass::print(llvm::raw_ostream&, llvm::Module const*) const", referenced from:
      vtable for (anonymous namespace)::DefinitionPass in p34.o
      vtable for (anonymous namespace)::FixingPass in p34.o
  "typeinfo for llvm::FunctionPass", referenced from:
      typeinfo for (anonymous namespace)::DefinitionPass in p34.o
      typeinfo for (anonymous namespace)::FixingPass in p34.o
  "vtable for llvm::FunctionPass", referenced from:
      llvm::FunctionPass::FunctionPass(char&) in p34.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for llvm::Pass", referenced from:
      llvm::Pass::Pass(llvm::PassKind, char&) in p34.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [p34.so] Error 1
rm p34.o

谁能告诉我如何让 GCC 找到那些 LLVM 文件?

您还需要获取 LLVM 链接器标志和库:

LDFLAGS += $(shell llvm-config --libs --ldflags)

%.so: %.o 
  $(CXX) $(CXXFLAGS) -dylib -shared -fPIC  $^ -o $@ $(LDFLAGS)