Не удалось скомпилировать передачу в DLL на Windows - PullRequest
0 голосов
/ 02 февраля 2020

Я следую за https://www.cs.cornell.edu/~asampson/blog/llvm.html и пытаюсь скомпилировать передачу на Windows. Но когда я создаю проход с помощью Clion, он завершается ошибкой с

[ 50%] Building CXX object skeleton/CMakeFiles/SkeletonPass.dir/Skeleton.cpp.obj
[100%] Linking CXX shared module libSkeletonPass.dll
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj): In function `runOnFunction':
I:/llvm_research/llvm-pass-tutorial/skeleton/Skeleton.cpp:14: undefined reference to `llvm::errs()'
I:/llvm_research/llvm-pass-tutorial/skeleton/Skeleton.cpp:14: undefined reference to `llvm::Value::getName() const'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x188): undefined reference to `llvm::Pass::getPassName() const'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1a0): undefined reference to `llvm::Pass::print(llvm::raw_ostream&, llvm::Module const*) const'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1a8): undefined reference to `llvm::FunctionPass::createPrinterPass(llvm::raw_ostream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1b0): undefined reference to `llvm::FunctionPass::assignPassManager(llvm::PMStack&, llvm::PassManagerType)'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1b8): undefined reference to `llvm::Pass::preparePassManager(llvm::PMStack&)'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1c0): undefined reference to `llvm::FunctionPass::getPotentialPassManagerType() const'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1c8): undefined reference to `llvm::Pass::getAnalysisUsage(llvm::AnalysisUsage&) const'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1d0): undefined reference to `llvm::Pass::releaseMemory()'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1d8): undefined reference to `llvm::Pass::getAdjustedAnalysisPointer(void const*)'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1e0): undefined reference to `llvm::Pass::getAsImmutablePass()'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1e8): undefined reference to `llvm::Pass::getAsPMDataManager()'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1f0): undefined reference to `llvm::Pass::verifyAnalysis() const'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata+0x1f8): undefined reference to `llvm::Pass::dumpPassStructure(unsigned int)'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj): In function `llvm::raw_ostream::operator<<(llvm::StringRef)':
I:/llvm_research/llvm/include/llvm/Support/raw_ostream.h:174: undefined reference to `llvm::raw_ostream::write(char const*, unsigned long long)'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj): In function `llvm::RegisterStandardPasses::RegisterStandardPasses(llvm::PassManagerBuilder::ExtensionPointTy, std::function<void (llvm::PassManagerBuilder const&, llvm::legacy::PassManagerBase&)>)':
I:/llvm_research/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h:212: undefined reference to `llvm::PassManagerBuilder::addGlobalExtension(llvm::PassManagerBuilder::ExtensionPointTy, std::function<void (llvm::PassManagerBuilder const&, llvm::legacy::PassManagerBase&)>)'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj): In function `llvm::FunctionPass::~FunctionPass()':
I:/llvm_research/llvm/include/llvm/Pass.h:285: undefined reference to `llvm::Pass::~Pass()'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata$.refptr._ZTVN4llvm12FunctionPassE[.refptr._ZTVN4llvm12FunctionPassE]+0x0): undefined reference to `vtable for llvm::FunctionPass'
CMakeFiles\SkeletonPass.dir/objects.a(Skeleton.cpp.obj):Skeleton.cpp:(.rdata$.refptr._ZTVN4llvm4PassE[.refptr._ZTVN4llvm4PassE]+0x0): undefined reference to `vtable for llvm::Pass'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [skeleton\CMakeFiles\SkeletonPass.dir\build.make:86: skeleton/libSkeletonPass.dll] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:121: skeleton/CMakeFiles/SkeletonPass.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:128: skeleton/CMakeFiles/SkeletonPass.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:130: SkeletonPass] Error 2

Но я добавляю и включаю каталог llvm в CMakeLists.

Дерево моего проекта:

MySkeletonPass
├── CMakeLists.txt
└── skeleton
    ├── CMakeLists.txt
    └── Skeleton.cpp

внешний CMakeLists.txt -

cmake_minimum_required(VERSION 3.15)
project(Skeleton)

set(LLVM_HOME I:/llvm_research/build_llvm)
set(LLVM_DIR ${LLVM_HOME}/lib/cmake/llvm)

find_package(LLVM REQUIRED CONFIG)
add_definitions(${LLVM_DEFINITIONS})
include_directories(${LLVM_INCLUDE_DIRS})
link_directories(${LLVM_LIBRARY_DIRS})
MESSAGE(${LLVM_LIBRARY_DIRS})
MESSAGE(${LLVM_INCLUDE_DIRS})
MESSAGE(${LLVM_DIR})

add_subdirectory(skeleton)

А внутренний CMakeLists.txt -

add_library(SkeletonPass MODULE
        # List your source files here.
        Skeleton.cpp
        )

# Use C++11 to compile your pass (i.e., supply -std=c++11).
target_compile_features(SkeletonPass PRIVATE cxx_range_for cxx_auto_type)

# LLVM is (typically) built with no C++ RTTI. We need to match that;
# otherwise, we'll get linker errors about missing RTTI data.
set_target_properties(SkeletonPass PROPERTIES
        COMPILE_FLAGS "-fno-rtti"
        )

скелет. cpp просто как

#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
using namespace llvm;

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

    virtual bool runOnFunction(Function &F) {
      llvm::errs() << "I saw a function called " << F.getName() << "!\n";
      return false;
    }
  };
}

char SkeletonPass::ID = 0;

// Automatically enable the pass.
// http://adriansampson.net/blog/clangpass.html
static void registerSkeletonPass(const PassManagerBuilder &,
                         legacy::PassManagerBase &PM) {
  PM.add(new SkeletonPass());
}
static RegisterStandardPasses
  RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible,
                 registerSkeletonPass);

Мне было интересно, почему он не может найти ссылку при сборке.

Более того, я создаю решение Clang и Library с VS2017 для build_llvm dir. Интересно, достаточно ли этого для построения прохода

против решения

...