0

I'm attempting to build an LLVM pass using the instructions here and link it against the copy of LLVM installed by Julia. The pass is currently being compiled successfully, but cmake fails on linking with undefined symbol errors.

[ 50%] Building CXX object VectorizePass/CMakeFiles/VectorizePass.dir/VectorizePass.cpp.o
[100%] Linking CXX shared module libVectorizePass.so
Undefined symbols for architecture x86_64:
    "llvm::raw_ostream::write_escaped(llvm::StringRef, bool)", referenced from:
  (anonymous namespace)::Hello::runOnFunction(llvm::Function&) in VectorizePass.cpp.o
   "llvm::raw_ostream::write(char const*, unsigned long)", referenced from:
        llvm::raw_ostream::operator<<(llvm::StringRef) in VectorizePass.cpp.o

There are dozens of undefined symbol errors followed by

"vtable for llvm::Pass", referenced from:
  llvm::Pass::Pass(llvm::PassKind, char&) in VectorizePass.cpp.o
NOTE: a missing vtable usually means the first non-inline virtual 
    member function has no definition.

VectorizePass.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",  "My Hello World Pass",  false, false);

This is exactly as it is in the tutorial.

CMakeLists.txt (1)

add_library(VectorizePass MODULE VectorizePass.cpp)
SET(CMAKE_CXX_FLAGS "-std=c++11 -Wall -fno-rtti -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -fPIC")

CMakeLists.txt (2)

project(VectorizePass)

set(LLVM_DIR "/Users/user/julia5/deps/build/llvm-3.7.1/build_Release")
set(LLVM_TOOLS_BINARY_DIR "/Users/user/julia5/deps/build/llvm-3.7.1/build_Release/Release/bin")

include_directories(${LLVM_INCLUDE_DIRS})
include_directories("/Users/user/julia5/deps/build/llvm-3.7.1/build_Release/include")
include_directories("/Users/user/julia5/deps/srccache/llvm-3.7.1/include")
link_directories("/Users/user/julia5/deps/build/llvm-3.7.1/build_Release/Release/lib")
link_directories("/Users/user/julia5/deps/build/llvm-3.7.1/build_Release/lib")
link_directories(${LLVM_LINK_DIRS})
add_definitions(${LLVM_DEFINITIONS})


add_subdirectory(VectorizePass)

Clearly, for some reason CMake isn't finding the appropriate object files even though they are in the directories that I have in the link_directories statements. What am I missing? I'm fairly new to CMake so it may be something obvious.

I've attempted to include(AddLLVM) as suggested here but CMake reports that it cannot find AddLLVM. This Stack post also suggests using a regular Makefile but that does not work when compiling out-of-source passes as all the paths in the regular LLVM Makefile.common/Makefile.config are relative and don't work at all.

hyperdelia
  • 1,105
  • 6
  • 26
  • `for some reason CMake isn't finding the appropriate object files even though they are in the directories that I have in the link_directories statements.` - You need to specify which object files (**libraries**) you need with [target_link_libraries](https://cmake.org/cmake/help/v3.0/command/target_link_libraries.html) command. – Tsyvarev May 21 '16 at 08:33
  • Can you check here: http://stackoverflow.com/a/37308946/4946286 – khrm May 24 '16 at 16:23

1 Answers1

0

Have you read this? You need to use add_llvm_loadable_module() macro to define target for your pass.

arrowd
  • 33,231
  • 8
  • 79
  • 110
  • As stated in my question, `include(AddLLVM)` and the other code from my section will not compile - CMake reports that `AddLLVM` could not be found. Also, if you read the link that you provided (and that is also linked in my answer), `add_llvm_loadable_module()` is optional and suggested only if you wish to merge the pass into the LLVM source tree at some point. – hyperdelia May 21 '16 at 16:28
  • I, initially, wrote that section. You'd better find out why CMake gives you that error. You, probably, need to point it to LLVM CMake modules with `CMAKE_PREFIX_PATH` or something like that. Anyway, you can just use `add_llvm_loadable_module()` as reference to see how to set up CMakeLists.txt. – arrowd May 21 '16 at 18:36