CMake and Clang Tooling linking error (out-of-tree)

10,427

I ended up using rewriting CMakeLists.txt based on this particular file.

Here is the modified working file:

cmake_minimum_required(VERSION 2.8.4)
project(ifcount)

set(LLVM_PATH /home/adel/Downloads/llvm)
link_directories(${LLVM_PATH}/lib)
include_directories(${LLVM_PATH}/include)

add_definitions(
-D__STDC_LIMIT_MACROS
-D__STDC_CONSTANT_MACROS
)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -std=c++11")

set(SOURCE_FILES main.cpp)
add_executable(ifcount ${SOURCE_FILES})

target_link_libraries(ifcount
  clangFrontend
  clangSerialization
  clangDriver
  clangParse
  clangSema
  clangAnalysis
  clangAST
  clangBasic
  clangEdit
  clangLex
  clangTooling
)

target_link_libraries(ifcount
  LLVMX86AsmParser # MC, MCParser, Support, X86Desc, X86Info
  LLVMX86Desc # MC, Support, X86AsmPrinter, X86Info
  LLVMX86AsmPrinter # MC, Support, X86Utils
  LLVMX86Info # MC, Support, Target
  LLVMX86Utils # Core, Support
  LLVMipo
  LLVMScalarOpts
  LLVMInstCombine
  LLVMTransformUtils
  LLVMipa
  LLVMAnalysis
  LLVMTarget
  LLVMOption # Support
  LLVMMCParser # MC, Support
  LLVMMC # Object, Support
  LLVMObject # BitReader, Core, Support
  LLVMBitReader # Core, Support
  LLVMCore # Support
  LLVMSupport
)

include(FindCurses)
target_link_libraries(ifcount
    pthread
    z
    dl
    ${CURSES_LIBRARIES}
)
Share:
10,427
Adel
Author by

Adel

Updated on June 03, 2022

Comments

  • Adel
    Adel almost 2 years

    I am trying to compile the RecursiveASTVisitor example of Clang using a CMake file. Building the project goes well, however, linking C++ executable fails with multiple undefined references to LLVM and Clang libraries. I am building the example outside of the LLVM/Clang source file tree.

    Here is my CMakeLists.txt (I am using FindClang.cmake and FindLLVM.cmake from this project):

    cmake_minimum_required(VERSION 2.8.4)
    project(ifcount)
    
    set(CMAKE_MODULE_PATH
      ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules
      ${CMAKE_MODULE_PATH})
    
    message(STATUS "CMAKE module path: ${CMAKE_MODULE_PATH}")
    
    find_path(LibClang_INCLUDE_DIR clang-c/Index.h)
    find_library(LIBCLANG_LIBRARY NAMES clang)
    
    find_package(LLVM REQUIRED)
    find_package(LLVM REQUIRED CONFIG)
    Find_Package(LLVM REQUIRED)
    include_directories(${LLVM_INCLUDE_DIR})
    link_directories(${LLVM_LIB_DIR})
    
    message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
    message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
    
    find_package(Clang REQUIRED)
    find_package(Clang REQUIRED clangTooling libClang)
    include_directories(${CLANG_INCLUDE_DIRS})
    
    ###
    add_definitions(${LLVM_DEFINITIONS})
    add_definitions(${Clang_DEFINITIONS})
    
    add_definitions("-std=c++11")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_COMPILE_FLAGS} -Wall -fno-rtti -g -std=c++11 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS")
    
    set(SOURCE_FILES main.cpp)
    add_executable(ifcount ${SOURCE_FILES})
    
    llvm_map_components_to_libnames(llvm_libs support core irreader)
    
    target_link_libraries(ifcount ${llvm_libs} ${LLVM_LDFLAGS} ${CLANG_LIBS})
    

    And here is the output:

    -- The C compiler identification is Clang 3.6.0
    -- The CXX compiler identification is Clang 3.6.0
    -- Check for working C compiler: /usr/local/bin/clang
    -- Check for working C compiler: /usr/local/bin/clang -- works
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Check for working CXX compiler: /usr/local/bin/clang++
    -- Check for working CXX compiler: /usr/local/bin/clang++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- CMAKE module path: /home/adel/workspace/ifcount/cmake/modules
    -- LLVM CXX flags: -I/usr/local/include  -fPIC -fvisibility-inlines-hidden -Wall -W -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -ffunction-sections -fdata-sections   -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
    -- LLVM LD flags: -L/usr/local/lib-lrt -ldl -ltinfo -lpthread -lz
    -- LLVM core libs: -lLLVMLTO -lLLVMObjCARCOpts -lLLVMLinker -lLLVMipo -lLLVMVectorize -lLLVMBitWriter -lLLVMIRReader -lLLVMAsmParser -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMXCoreAsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter -lLLVMSparcDisassembler -lLLVMSparcCodeGen -lLLVMSparcAsmParser -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMSparcAsmPrinter -lLLVMR600CodeGen -lLLVMR600Desc -lLLVMR600Info -lLLVMR600AsmPrinter -lLLVMPowerPCDisassembler -lLLVMPowerPCCodeGen -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMHexagonCodeGen -lLLVMHexagonAsmPrinter -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMCppBackendCodeGen -lLLVMCppBackendInfo -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMAArch64Disassembler l-LLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMTableGen -lLLVMDebugInfo -lLLVMOption -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMX86Desc -lLLVMMCDisassembler -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMJIT -lLLVMLineEditor -lLLVMMCAnalysis -lLLVMInstrumentation -lLLVMInterpreter -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMProfileData -lLLVMMCJIT -lLLVMTarget -lLLVMRuntimeDyld -lLLVMObject -lLLVMMCParser -lLLVMBitReader -lLLVMExecutionEngine -lLLVMMC -lLLVMCore -lLLVMSupport
    -- LLVM JIT libs: -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMX86Desc -lLLVMObject -lLLVMMCParser -lLLVMBitReader -lLLVMMCDisassembler -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMJIT -lLLVMExecutionEngine -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMTarget -lLLVMMC -lLLVMCore -lLLVMSupport
    -- LLVM JIT objs: 
    -- Found LLVM: /usr/local/include
    -- Found LLVM 3.6.0svn
    -- Using LLVMConfig.cmake in: /usr/local/share/llvm/cmake
    -- Clang libs: /usr/local/lib/libclangFrontend.a/usr/local/lib/libclangDriver.a/usr/local/lib/libclangCodeGen.a/usr/local/lib/libclangSema.a/usr/local/lib/libclangAnalysis.a/usr/local/lib/libclangRewrite.a/usr/local/lib/libclangAST.a/usr/local/lib/libclangParse.a/usr/local/lib/libclangLex.a/usr/local/lib/libclangBasic.a/usr/local/lib/libclangARCMigrate.a/usr/local/lib/libclangEdit.a/usr/local/lib/libclangFrontendTool.a/usr/local/lib/libclangRewrite.a/usr/local/lib/libclangSerialization.a/usr/local/lib/libclangTooling.a/usr/local/lib/libclangStaticAnalyzerCheckers.a/usr/local/lib/libclangStaticAnalyzerCore.a/usr/local/lib/libclangStaticAnalyzerFrontend.a/usr/local/lib/libclangSema.a
    -- Found Clang: /usr/local/include
    -- Clang libs: /usr/local/lib/libclangFrontend.a/usr/local/lib/libclangDriver.a/usr/local/lib/libclangCodeGen.a/usr/local/lib/libclangSema.a/usr/local/lib/libclangAnalysis.a/usr/local/lib/libclangRewrite.a/usr/local/lib/libclangAST.a/usr/local/lib/libclangParse.a/usr/local/lib/libclangLex.a/usr/local/lib/libclangBasic.a/usr/local/lib/libclangARCMigrate.a/usr/local/lib/libclangEdit.a/usr/local/lib/libclangFrontendTool.a/usr/local/lib/libclangRewrite.a/usr/local/lib/libclangSerialization.a/usr/local/lib/libclangTooling.a/usr/local/lib/libclangStaticAnalyzerCheckers.a/usr/local/lib/libclangStaticAnalyzerCore.a/usr/local/lib/libclangStaticAnalyzerFrontend.a/usr/local/lib/libclangSema.a/usr/local/lib/libclangFrontend.a/usr/local/lib/libclangDriver.a/usr/local/lib/libclangCodeGen.a/usr/local/lib/libclangSema.a/usr/local/lib/libclangAnalysis.a/usr/local/lib/libclangRewrite.a/usr/local/lib/libclangAST.a/usr/local/lib/libclangParse.a/usr/local/lib/libclangLex.a/usr/local/lib/libclangBasic.a/usr/local/lib/libclangARCMigrate.a/usr/local/lib/libclangEdit.a/usr/local/lib/libclangFrontendTool.a/usr/local/lib/libclangRewrite.a/usr/local/lib/libclangSerialization.a/usr/local/lib/libclangTooling.a/usr/local/lib/libclangStaticAnalyzerCheckers.a/usr/local/lib/libclangStaticAnalyzerCore.a/usr/local/lib/libclangStaticAnalyzerFrontend.a/usr/local/lib/libclangSema.a
    -- Found Clang: /usr/local/include;/usr/local/include
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/adel/workspace/ifcount/build
    Scanning dependencies of target ifcount
    [100%] Building CXX object CMakeFiles/ifcount.dir/main.cpp.o
    Linking CXX executable ifcount
    

    And finally, the errors are too numerous, here are some of their input:

    /usr/local/bin/../lib/libclangFrontend.a(CompilerInvocation.cpp.o): In function `llvm::opt::arg_iterator::arg_iterator(llvm::opt::Arg* const*, llvm::opt::ArgList const&, llvm::opt::OptSpecifier, llvm::opt::OptSpecifier, llvm::opt::OptSpecifier)':
    CompilerInvocation.cpp:(.text._ZN4llvm3opt12arg_iteratorC2EPKPNS0_3ArgERKNS0_7ArgListENS0_12OptSpecifierES9_S9_[_ZN4llvm3opt12arg_iteratorC5EPKPNS0_3ArgERKNS0_7ArgListENS0_12OptSpecifierES9_S9_]+0x5c): undefined reference to `llvm::opt::arg_iterator::SkipToNextArg()'
    /usr/local/bin/../lib/libclangFrontend.a(CompilerInvocation.cpp.o): In function `llvm::opt::arg_iterator::operator++()':
    CompilerInvocation.cpp:(.text._ZN4llvm3opt12arg_iteratorppEv[_ZN4llvm3opt12arg_iteratorppEv]+0x26): undefined reference to `llvm::opt::arg_iterator::SkipToNextArg()'
    /usr/local/bin/../lib/libclangFrontend.a(CompilerInvocation.cpp.o): In function `llvm::opt::ArgList::hasArg(llvm::opt::OptSpecifier) const':
    CompilerInvocation.cpp:(.text._ZNK4llvm3opt7ArgList6hasArgENS0_12OptSpecifierE[_ZNK4llvm3opt7ArgList6hasArgENS0_12OptSpecifierE]+0x1c): undefined reference to `llvm::opt::ArgList::getLastArg(llvm::opt::OptSpecifier) const'
    /usr/local/bin/../lib/libclangFrontend.a(CompilerInvocation.cpp.o): In function `getOptimizationLevel(llvm::opt::ArgList&, clang::InputKind, clang::DiagnosticsEngine&)':
    CompilerInvocation.cpp:(.text._ZL20getOptimizationLevelRN4llvm3opt7ArgListEN5clang9InputKindERNS3_17DiagnosticsEngineE+0x8d): undefined reference to `llvm::opt::ArgList::getLastArg(llvm::opt::OptSpecifier) const'
    CompilerInvocation.cpp:(.text._ZL20getOptimizationLevelRN4llvm3opt7ArgListEN5clang9InputKindERNS3_17DiagnosticsEngineE+0xc6): undefined reference to `llvm::opt::Option::matches(llvm::opt::OptSpecifier) const'
    CompilerInvocation.cpp:(.text._ZL20getOptimizationLevelRN4llvm3opt7ArgListEN5clang9InputKindERNS3_17DiagnosticsEngineE+0xfe): undefined reference to `llvm::opt::Option::matches(llvm::opt::OptSpecifier) const'
    CompilerInvocation.cpp:(.text._ZL20getOptimizationLevelRN4llvm3opt7ArgListEN5clang9InputKindERNS3_17DiagnosticsEngineE+0x136): undefined reference to `llvm::opt::Option::matches(llvm::opt::OptSpecifier) const'
    /usr/local/bin/../lib/libclangFrontend.a(CompilerInvocation.cpp.o): In function `getOptimizationLevelSize(llvm::opt::ArgList&)':
    CompilerInvocation.cpp:(.text._ZL24getOptimizationLevelSizeRN4llvm3opt7ArgListE+0x2a): undefined reference to `llvm::opt::ArgList::getLastArg(llvm::opt::OptSpecifier) const'
    CompilerInvocation.cpp:(.text._ZL24getOptimizationLevelSizeRN4llvm3opt7ArgListE+0x5f): undefined reference to `llvm::opt::Option::matches(llvm::opt::OptSpecifier) const'
    /usr/local/bin/../lib/libclangFrontend.a(CompilerInvocation.cpp.o): In function `addDiagnosticArgs(llvm::opt::ArgList&, llvm::opt::OptSpecifier, llvm::opt::OptSpecifier, std::vector<std::string, std::allocator<std::string> >&)':
    CompilerInvocation.cpp:(.text._ZL17addDiagnosticArgsRN4llvm3opt7ArgListENS0_12OptSpecifierES3_RSt6vectorISsSaISsEE+0x188): undefined reference to `llvm::opt::Option::matches(llvm::opt::OptSpecifier) const'
    /usr/local/bin/../lib/libclangFrontend.a(CompilerInvocation.cpp.o): In function `ParseAnalyzerArgs(clang::AnalyzerOptions&, llvm::opt::ArgList&, clang::DiagnosticsEngine&)':
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0x5e): undefined reference to `llvm::opt::ArgList::getLastArg(llvm::opt::OptSpecifier) const'
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0x132): undefined reference to `llvm::opt::Arg::getAsString(llvm::opt::ArgList const&) const'
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0x204): undefined reference to `llvm::opt::ArgList::getLastArg(llvm::opt::OptSpecifier) const'
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0x2d8): undefined reference to `llvm::opt::Arg::getAsString(llvm::opt::ArgList const&) const'
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0x3aa): undefined reference to `llvm::opt::ArgList::getLastArg(llvm::opt::OptSpecifier) const'
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0x4fe): undefined reference to `llvm::opt::Arg::getAsString(llvm::opt::ArgList const&) const'
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0x5d0): undefined reference to `llvm::opt::ArgList::getLastArg(llvm::opt::OptSpecifier) const'
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0x6e4): undefined reference to `llvm::opt::Arg::getAsString(llvm::opt::ArgList const&) const'
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0x7b6): undefined reference to `llvm::opt::ArgList::getLastArg(llvm::opt::OptSpecifier) const'
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0x8aa): undefined reference to `llvm::opt::Arg::getAsString(llvm::opt::ArgList const&) const'
    CompilerInvocation.cpp:(.text._ZL17ParseAnalyzerArgsRN5clang15AnalyzerOptionsERN4llvm3opt7ArgListERNS_17DiagnosticsEngineE+0xc3f): undefined reference to `llvm::opt::ArgList::getLastArgValue(llvm::opt::OptSpecifier, llvm::StringRef) const'
    

    Any help or tips would be appreciated.

  • Hongxu Chen
    Hongxu Chen over 9 years
    better use llvm-config --src-root for $LLVM_PATH
  • Adel
    Adel over 9 years
    Thanks Hongxu, that's much helpful.
  • isPrime
    isPrime about 5 years
    @HongxuChen Could you elaborate a bit more about your suggestion?
  • Hongxu Chen
    Hongxu Chen about 5 years
    @isPrime LLVM_PATH can be set with llvm-config --src-root specified one, rather than hard coded.
  • isPrime
    isPrime about 5 years
    Thanks. I was trying to use set(LLVM_PATH "$(LLVM_BIN_PATH)/llvm-config --src_root") But cmake cannot get the result as a string.
  • Adam
    Adam over 2 years
    This helped me as well! target_link_libraries(...exec... LLVMBitstreamReader LLVMRemarks LLVMBinaryFormat LLVMCore LLVMSupport ...other stuff...)