Search code examples
clangllvmclang++llvm-clang

order of imports for clang libraries


I'm writing my own Makefile to compile my minimum standalone clang tool consisting of the following code:

#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"                                                                                                                                                   

using namespace clang;
using namespace clang::driver;
using namespace clang::tooling;

static llvm::cl::OptionCategory ToolingSampleCategory("MetaLift Clang Frontend");

int main (int argc, const char **argv)
{
  CommonOptionsParser op(argc, argv, ToolingSampleCategory);
  ClangTool Tool(op.getCompilations(), op.getSourcePathList());
  return 0;
}

Is there a "proper" order to import the clang libraries? My current order is:

-lclangTooling -lclangSerialization -lclangFrontend 

But I keep running into undefined symbols issues.


Solution

  • I find using CMake to be the easiest way to build a libTooling-based application. Here is a minimalistic snippet to compile your example:

    # CMakeLists.txt
    cmake_minimum_required(VERSION 3.12)
    
    # Find CMake file for Clang
    find_package(Clang REQUIRED)
    
    # Add path to LLVM modules
    set(CMAKE_MODULE_PATH
      ${CMAKE_MODULE_PATH}
      "${LLVM_CMAKE_DIR}"
      )
    
    # import LLVM CMake functions
    include(AddLLVM)
    
    include_directories(${LLVM_INCLUDE_DIRS})
    include_directories(${CLANG_INCLUDE_DIRS})
    
    add_definitions(${LLVM_DEFINITIONS})
    add_definitions(${CLANG_DEFINITIONS})
    
    add_llvm_executable(myTool main.cpp)
    set_property(TARGET myTool PROPERTY CXX_STANDARD 11)
    target_link_libraries(myTool PRIVATE clangTooling)
    
    // main.cpp
    #include "clang/Tooling/CommonOptionsParser.h"
    #include "clang/Tooling/Tooling.h"
    
    using namespace clang;
    using namespace clang::driver;
    using namespace clang::tooling;
    
    static llvm::cl::OptionCategory
        ToolingSampleCategory("MetaLift Clang Frontend");
    
    int main(int argc, const char **argv) {
      CommonOptionsParser op(argc, argv, ToolingSampleCategory);
      ClangTool Tool(op.getCompilations(), op.getSourcePathList());
      return 0;
    }
    

    I checked the actual commands happening during the build:

    c++  -DGTEST_HAS_RTTI=0 -I${CLANG}/include  -O3 -DNDEBUG -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk   -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS  -fno-exceptions -fno-rtti -std=gnu++11 -o CMakeFiles/myTool.dir/main.cpp.o -c /Users/vsavchenko/source/c++/clang-makefile/main.cpp
    
    c++  -O3 -DNDEBUG -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names  -Wl,-dead_strip CMakeFiles/myTool.dir/main.cpp.o  -o myTool -Wl,-rpath,@loader_path/../lib -Wl,-rpath,${CLANG}/lib ${CLANG}/lib/libclangTooling.a ${CLANG}/lib/libclangASTMatchers.a ${CLANG}/lib/libclangFormat.a ${CLANG}/lib/libclangFrontend.a ${CLANG}/lib/libclangDriver.a ${CLANG}/lib/libclangParse.a ${CLANG}/lib/libLLVMMCParser.a ${CLANG}/lib/libclangSerialization.a ${CLANG}/lib/libclangSema.a ${CLANG}/lib/libclangEdit.a ${CLANG}/lib/libclangAnalysis.a ${CLANG}/lib/libLLVMBitReader.a ${CLANG}/lib/libLLVMProfileData.a ${CLANG}/lib/libclangToolingCore.a ${CLANG}/lib/libclangAST.a ${CLANG}/lib/libclangRewrite.a ${CLANG}/lib/libclangLex.a ${CLANG}/lib/libclangBasic.a ${CLANG}/lib/libLLVMCore.a ${CLANG}/lib/libLLVMBinaryFormat.a ${CLANG}/lib/libLLVMMC.a ${CLANG}/lib/libLLVMOption.a ${CLANG}/lib/libLLVMSupport.a -lz -lcurses -lm /Users/vsavchenko/bin/clang/lib/libLLVMDemangle.a 
    

    It looks like the problem is not with the order of Clang libraries, but rather an insufficient set of them. The following command finishes without linking errors:

    LIBRARY_PATH=${CLANG}/lib clang++ -std=c++11 -lclangTooling -lclangASTMatchers -lclangFormat -lclangFrontend -lclangDriver -lclangParse -lLLVMMCParser -lclangSerialization -lclangSema -lclangEdit -lclangAnalysis -lLLVMBitReader -lLLVMProfileData -lclangToolingCore -lclangAST -lclangRewrite -lclangLex -lclangBasic -lLLVMCore -lLLVMBinaryFormat -lLLVMMC -lLLVMOption -lLLVMSupport -lz -lcurses -lLLVMDemangle -I${CLANG}/include main.cpp
    

    Happy hacking with Clang!