2015-10-18 63 views
3

我一直在尝试写LLVM通过以下文档的一部分thisthis的混合。运行一个简单的源LLVM通过的问题

我假设,既然Mac自带Clang和LLVM,我应该可以使用他们的安装来创建插件。所以我做了一个目录布局如下:

optimizations 
    CMakeLists.txt (--> outer) 
    Hello 
     CMakeLists.txt (--> inner) 
     Hello.cpp 

"outer"内容是:

find_package(LLVM REQUIRED CONFIG) 
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") 
include(AddLLVM) 

add_definitions(${LLVM_DEFINITONS}) 
include_directories(${LLVM_INCLUDE_DIRS}) 

add_subdirectory(Hello) 

"inner"内容是:

add_llvm_loadable_module(LLVMHello 
    Hello.cpp 
    ) 

在HELLO.CPP我有什么在另一组指令中提出:

#include "llvm/Pass.h" 
#include "llvm/IR/Function.h" 
#include "llvm/Support/raw_ostream.h" 

using namespace llvm; 

namespace { 
    struct Hello : public FunctionPass { 
    static char ID; 
    Hello() : FunctionPass(ID) {} 

    bool runOnFunction(Function &F) override { 
     errs() << "Hello: "; 
     errs().write_escaped(F.getName()) << '\n'; 
     return false; 
    } 
    }; 
} 

char Hello::ID = 0; 
static RegisterPass<Hello> X("hello", "Hello World Pass", false, false); 

然后我进入优化目录并运行cmake CMakeLists.txt。这在每个目录中创建了一个Makefile以及一堆其他cmake相关文件。这工作得很好,但后来我试着运行make和第一个I got errors similar to here。为了解决这个问题,在Hello.cpp上面我说:

#define __STDC_LIMIT_MACROS 
#define __STDC_CONSTANT_MACROS 

但现在我得到这些错误:

/usr/local/include/llvm/Support/AlignOf.h:53:10: error: unknown type name 'constexpr' 
    static constexpr unsigned Alignment = 
     ^
/usr/local/include/llvm/Support/AlignOf.h:53:20: error: expected member name or ';' after declaration specifiers 
    static constexpr unsigned Alignment = 
    ~~~~~~~~~~~~~~~~^
/usr/local/include/llvm/Support/AlignOf.h:59:42: error: use of undeclared identifier 'Alignment' 
    enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 }; 
             ^
/usr/local/include/llvm/Support/AlignOf.h:60:42: error: use of undeclared identifier 'Alignment' 
    enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 }; 
             ^
/usr/local/include/llvm/Support/AlignOf.h:61:42: error: use of undeclared identifier 'Alignment' 
    enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 }; 
             ^
/usr/local/include/llvm/Support/AlignOf.h:62:43: error: use of undeclared identifier 'Alignment' 
    enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 }; 
             ^
/usr/local/include/llvm/Support/AlignOf.h:64:39: error: use of undeclared identifier 'Alignment' 
    enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 }; 
            ^
/usr/local/include/llvm/Support/AlignOf.h:65:39: error: use of undeclared identifier 'Alignment' 
    enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 }; 
            ^
/usr/local/include/llvm/Support/AlignOf.h:66:39: error: use of undeclared identifier 'Alignment' 
    enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 }; 
            ^
/usr/local/include/llvm/Support/AlignOf.h:67:40: error: use of undeclared identifier 'Alignment' 
    enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 }; 
            ^
/usr/local/include/llvm/Support/AlignOf.h:71:23: error: unknown type name 'constexpr' 
template <typename T> constexpr unsigned AlignOf<T>::Alignment; 
        ^
/usr/local/include/llvm/Support/AlignOf.h:71:33: error: expected unqualified-id 
template <typename T> constexpr unsigned AlignOf<T>::Alignment; 

我不太确定如何处理这些错误。任何帮助,将不胜感激。

添加set(CMAKE_CXX_STANDARD 11)CMakeLists.txt给出:

Hello[ 50%] Linking CXX shared module LLVMHello.dylib 
Undefined symbols for architecture x86_64: 
    "llvm::FunctionPass::assignPassManager(llvm::PMStack&, llvm::PassManagerType)", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.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)::Hello in Hello.o 
    "llvm::Pass::getAnalysisUsage(llvm::AnalysisUsage&) const", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "llvm::Pass::getAdjustedAnalysisPointer(void const*)", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "llvm::Pass::getPassName() const", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "llvm::Pass::verifyAnalysis() const", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "llvm::Value::getName() const", referenced from: 
     (anonymous namespace)::Hello::runOnFunction(llvm::Function&) in Hello.o 
    "llvm::errs()", referenced from: 
     (anonymous namespace)::Hello::runOnFunction(llvm::Function&) in Hello.o 
    "llvm::raw_ostream::write(char const*, unsigned long)", referenced from: 
     llvm::raw_ostream::operator<<(llvm::StringRef) in Hello.o 
    "llvm::Pass::dumpPassStructure(unsigned int)", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "llvm::Pass::getAsPMDataManager()", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "llvm::Pass::~Pass()", referenced from: 
     llvm::FunctionPass::~FunctionPass() in Hello.o 
    "llvm::Pass::print(llvm::raw_ostream&, llvm::Module const*) const", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "llvm::raw_ostream::write(unsigned char)", referenced from: 
     llvm::raw_ostream::operator<<(char) in Hello.o 
    "llvm::FunctionPass::getPotentialPassManagerType() const", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "vtable for llvm::FunctionPass", referenced from: 
     llvm::FunctionPass::FunctionPass(char&) in Hello.o 
    NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. 
    "llvm::Pass::preparePassManager(llvm::PMStack&)", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "llvm::Pass::getAsImmutablePass()", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "vtable for llvm::Pass", referenced from: 
     llvm::Pass::Pass(llvm::PassKind, char&) in Hello.o 
    NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. 
    "llvm::raw_ostream::write_escaped(llvm::StringRef, bool)", referenced from: 
     (anonymous namespace)::Hello::runOnFunction(llvm::Function&) in Hello.o 
    "llvm::Pass::releaseMemory()", referenced from: 
     vtable for (anonymous namespace)::Hello in Hello.o 
    "llvm::PassRegistry::getPassRegistry()", referenced from: 
     llvm::RegisterPass<(anonymous namespace)::Hello>::RegisterPass(char const*, char const*, bool, bool) in Hello.o 
    "llvm::PassRegistry::registerPass(llvm::PassInfo const&, bool)", referenced from: 
     llvm::RegisterPass<(anonymous namespace)::Hello>::RegisterPass(char const*, char const*, bool, bool) in Hello.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
make[2]: *** [Hello/LLVMHello.dylib] Error 1 
make[1]: *** [Hello/CMakeFiles/LLVMHello.dir/all] Error 2 
make: *** [all] Error 2 

回答

-2

UPDATE:忽略这个答案。关于C++ 11的答案是正确的。因此无法找到constexpr的定义。这可能是一个typedef作为typedef something constexpr,但更有可能的宏为#define constexpr const

应该在.h文件中的某个地方被定义(或生成文件中为-Dconstexpr=const)。

注意:在您引用的页面上,他们建议在生成文件中添加-D。另请参阅使用llvm-config --cppflags的第二个答案。只需输入它并查看它输出的内容。

但是,它必须进一步解决......

首先,发现通过像有定义的文件:

egrep -r '#define.*constexpr' .
你可能会得到一些额外的功能。筛选它们并找到具有该定义的文件。然后,在它周围寻找 #ifdef BLAH包装。 BLAH没有被正确定义。

如果BLAH是您提到的__STDC_ *之一,您可能需要间接定义它,因为有时某些.h文件将取消这些并基于更“全局”符号重新设定它们。STDC_ *或_STDC_SOURCE)

例如,GNU,让子功能,你不能直接定义它们,您使用_GNU_SOURCE其开启一大堆

1

编译器抱怨constexpr这是一个C++ 11功能。确保通过将-std=c++11开关传递给gcc(或Clang,两个编译器使用相同的开关)来启用C++ 11。这将修复您所看到的所有错误。由于您使用的是生成文件,因此您应该将此开关添加到CXXFLAGS变量中,如here所示。

+0

你知道好像说了'set(CMAKE_CXX_STANDARD 11)'我'CMakeLists.txt'相当于'-std = C++ 11'这样做修复这些错误,但也有创建别人。 – Dair

+0

@Dair这也适用。其他错误是什么? –

+0

@Dair关于新的错误集。看起来您并未引用所有必需的LLVM静态库。在LLVM的'build'目录中有一个名为'Makefile.common'的文件。这个文件必须包含在makefile中。 –