Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

llvm 5.0 linking error with llvm::Module::dump()

I was trying to link LLVM with My C++ project for the past two days and it's finally working but the issue is when i use dump() method it gives a linker error i thought the problem is with the libraries that i'm linking against, so i've linked my executable against all the LLVM libraries(modules) but with no success. so is that a bug in the LLVM5.0 code base or am i doing something wrong and the reason i'm specifically speaking about LLVM5.0 because i've read else where (LLVM-5.0 Makefile undefined reference fail) in the comment section that there was no issue compiling the same code using LLVM4.0 and of course i've searched about other solution but there's nothing

llvm_test.cpp:

#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"

llvm::LLVMContext context;

int main(){
    llvm::Module*module = new llvm::Module("llvm-module",context);
    module->dump();
}

commands:

clang++ -O3  -Wall -std=c++11 `llvm-config --cppflags --ldflags` `llvm-config --libs core --system-libs` toy.cpp 

and about that i have linked against all modules:

clang++ -O3 -Wall -std=c++11 `llvm-config --cxxflags --ldflags` `llvm-config --libs all --system-libs` toy.cpp 

compiler: Apple Clang 8.0.0 x86_64

OS: mac OS 10.12.5

thanks for any help in advance

like image 866
yazan daba Avatar asked Sep 22 '17 15:09

yazan daba


2 Answers

OK, I looked into the code of llvm and you can actually do it far easier. All you have to do is stop using dump and instead:

module->print(llvm::errs(), nullptr);

Which is exactly what dump does internally.

like image 62
gruszczy Avatar answered Sep 20 '22 03:09

gruszczy


So after working after the problem it's finally led me to simple hack for the issue part of solution is back for the guy who answered the question in the link above but i will give a full solution for the problem, but before i answer the question i need to move your attention that this solution worked with LLVM5.0 so i don't know if it will work with other versions.

-first: i've copied the definition of llvm::LLVMContext::dump from the file AsmWriter.cpp file you can find the definition of various llvm::Dump methods right at the total end of this file i've copied them all for future uses i will write the contents of LLVMDump.cpp that i've used

LLVMDump.cpp

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/IR/TypeFinder.h"
#include "llvm/IR/UseListOrder.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include <algorithm>
#include <cctype>
using namespace llvm;
LLVM_DUMP_METHOD
void Value::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }

// Type::dump - allow easy printing of Types from the debugger.
LLVM_DUMP_METHOD
void Type::dump() const { print(dbgs(), /*IsForDebug=*/true); dbgs() << '\n'; }

// Module::dump() - Allow printing of Modules from the debugger.
LLVM_DUMP_METHOD
void Module::dump() const {
    print(dbgs(), nullptr,
            /*ShouldPreserveUseListOrder=*/false, /*IsForDebug=*/true);
}

// \brief Allow printing of Comdats from the debugger.
LLVM_DUMP_METHOD
void Comdat::dump() const { print(dbgs(), /*IsForDebug=*/true); }

// NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger.
LLVM_DUMP_METHOD
void NamedMDNode::dump() const { print(dbgs(), /*IsForDebug=*/true); }

LLVM_DUMP_METHOD
void Metadata::dump() const { dump(nullptr); }

LLVM_DUMP_METHOD
void Metadata::dump(const Module *M) const {
    print(dbgs(), M, /*IsForDebug=*/true);
    dbgs() << '\n';
}

please note that i've changed an old include directory #include "llvm/Support/Dwarf.h" to #include "llvm/BinaryFormat/Dwarf.h"

-second: i've compiled LLVMDUmp.cpp as static library to link against it later when i need it.

in case you don't know how to create static linked library on mac because the -static flag will not work with clang or gcc on mac

clang++ -std=c++1z -O3 -c LLVMDump.cpp -o LLVMDump.o 

then for creating the static linked library

ar -rv libLLVMDump.a LLVMDump.o 

now just move libLLVMDump.a to the lib directory on your computer to use it when you need it (if you don't know where you should set the lib directory from your llvm installation ) use llvm-config

llvm-config --lib-dir

and it will show where you should put your llvm/lib directory of where it's installed .

test: you can use the code in the question if you want

clang++ -O3 -Wall -std=c++1z -L /path/lib -lLLVMCore -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle -lLLVMDump  llvmtest.cpp

note LLVMDump at the end which we've just created.

I hope that helped anyone and Happy coding😊.

like image 21
yazan daba Avatar answered Sep 21 '22 03:09

yazan daba