首页 > 解决方案 > 无法在 Windows 上编译传递给 DLL

问题描述

我遵循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

但是我在 CMakeLists 中添加并包含 llvm 目录。

我的项目树是:

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);

我想知道为什么它在构建时找不到参考。

更重要的是,我使用 VS2017 构建ClangLibrary解决该build_llvm目录。我想知道这是否足以建立通行证

vs 解决方案视图

标签: c++clangllvmllvm-clang

解决方案


推荐阅读