2
votes

I've been playing around with clang/llvm 3.0, following the tutorial here http://amnoid.de/tmp/clangtut/tut.html

The code in the tutorial is a bit outdated but after some modification, it compiles ok (both with clang++/g++, on Ubuntu):

#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/Host.h>
#include <llvm/ADT/IntrusiveRefCntPtr.h>

#include <clang/Frontend/DiagnosticOptions.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Frontend/CompilerInstance.h>

#include <clang/Basic/Diagnostic.h>
#include <clang/Basic/TargetOptions.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Basic/FileManager.h>

#include <clang/Lex/Preprocessor.h>
#include <clang/Lex/HeaderSearch.h>

using namespace clang;

int main()
{
  DiagnosticOptions diagOpt;
  TextDiagnosticPrinter *pTextDiagPrinter = new TextDiagnosticPrinter(llvm::outs(), diagOpt);
  llvm::IntrusiveRefCntPtr<DiagnosticIDs> pDiagIds(new DiagnosticIDs);
  DiagnosticsEngine *pDiagEng = new DiagnosticsEngine(pDiagIds, pTextDiagPrinter);
  Diagnostic diag(pDiagEng);

  LangOptions lang;
  FileSystemOptions fmOpt;
  FileManager fm(fmOpt);
  SourceManager sm(*pDiagEng, fm);
  HeaderSearch headers(fm);
  TargetOptions tgtOpt;
  tgtOpt.Triple = llvm::sys::getHostTriple();

  TargetInfo *ti = TargetInfo::CreateTargetInfo(*pDiagEng, tgtOpt);
  CompilerInstance comp;

  Preprocessor pp(*pDiagEng, lang, ti, sm, headers, comp);

  return 0;
}

The problem is linking, I guess the problem is library order, tried various combinations, some gives thousands of undefined symbols, the best I get is with this:

g++ -fno-exceptions -fno-rtti -fno-common \
-lclangParse -lclangSerialization -lclangDriver -lclangSema -lclangAnalysis -lclangAST -lclangFrontend \
-lclangLex -lclangBasic -lclang \
`llvm-config --cxxflags --ldflags --libs` -ldl tut1.cpp

which gives

tut1.cpp:(.text.startup+0xca): undefined reference to `llvm::outs()'
tut1.cpp:(.text.startup+0xef): undefined reference to `clang::TextDiagnosticPrinter::TextDiagnostic
Printer(llvm::raw_ostream&, clang::DiagnosticOptions const&, bool)'
tut1.cpp:(.text.startup+0x104): undefined reference to `clang::DiagnosticIDs::DiagnosticIDs()'
tut1.cpp:(.text.startup+0x13d): undefined reference to `clang::DiagnosticsEngine::DiagnosticsEngine
(llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> const&, clang::DiagnosticConsumer*, bool)'
tut1.cpp:(.text.startup+0x14a): undefined reference to `clang::LangOptions::LangOptions()'
tut1.cpp:(.text.startup+0x167): undefined reference to `clang::FileManager::FileManager(clang::File
SystemOptions const&)'
tut1.cpp:(.text.startup+0x17f): undefined reference to `clang::SourceManager::SourceManager(clang::
DiagnosticsEngine&, clang::FileManager&)'
tut1.cpp:(.text.startup+0x194): undefined reference to `clang::HeaderSearch::HeaderSearch(clang::Fi
leManager&)'
tut1.cpp:(.text.startup+0x1f5): undefined reference to `llvm::sys::getHostTriple()'
tut1.cpp:(.text.startup+0x227): undefined reference to `clang::TargetInfo::CreateTargetInfo(clang::
DiagnosticsEngine&, clang::TargetOptions&)'
tut1.cpp:(.text.startup+0x232): undefined reference to `clang::CompilerInstance::CompilerInstance()
'
tut1.cpp:(.text.startup+0x277): undefined reference to `clang::Preprocessor::Preprocessor(clang::Di
agnosticsEngine&, clang::LangOptions&, clang::TargetInfo const*, clang::SourceManager&, clang::Head
erSearch&, clang::ModuleLoader&, clang::IdentifierInfoLookup*, bool, bool)'
tut1.cpp:(.text.startup+0x281): undefined reference to `clang::Preprocessor::~Preprocessor()'
tut1.cpp:(.text.startup+0x289): undefined reference to `clang::CompilerInstance::~CompilerInstance(
)'
tut1.cpp:(.text.startup+0x2e4): undefined reference to `clang::HeaderSearch::~HeaderSearch()'
tut1.cpp:(.text.startup+0x2f1): undefined reference to `clang::SourceManager::~SourceManager()'
tut1.cpp:(.text.startup+0x2fe): undefined reference to `clang::FileManager::~FileManager()'
tut1.cpp:(.text.startup+0x345): undefined reference to `clang::DiagnosticIDs::~DiagnosticIDs()'
collect2: ld returned 1 exit status

I also followed this link Linking against clang-llvm but seems it doesn't apply to clang 3.0.

Anybody knows how to successfully build the code, or better yet, some tool like some clang-config?

3

3 Answers

4
votes

just use the LLVM flags AFTER the .o file, object file won't be linked unless the flags are written after it. A simple makefile to show what I mean

CC=clang++
LFLAGS=`llvm-config --cppflags --ldflags --libs core`
all:
    $(CC) -o out in.cc $(FLAGS)
0
votes

clang driver itself links with:

-lclangFrontendTool -lclangFrontend -lclangDriver -lclangSerialization -lclangCodeGen -lclangParse -lclangSema -lclangStaticAnalyzerFrontend -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore -lclangAnalysis -lclangIndex -lclangARCMigrate -lclangRewrite -lclangAST -lclangLex -lclangBasic

A little trick how to find it out: build clang, remove the clang binary, and run make -n.

0
votes

Some linkers a sensitive to the order of -l* flags when working with static libraries. The of clang libraries seems OK, so try swapping `llvm-config --cxxflags --ldflags --libs` with clang libraries list.

If that don't help, only solution for you is what @SK-logic suggested - run make -n and look at compile command for clang target.