Now it’s time to build our own clang standalone tool. The official LibTooling document provides an example code so that I was able to begin with it.
How to write CMakeLists.txt for the standalone clang tool?
Of course using the cmake is not required, but I wanted to go with it. At first I tried to use the CMakeLists which is included the rtags with few modifications, but it didn’t work well. Instead of digging it further, I tried another CMakeLists found and easily succeeded after adding more libs to link with.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## http://qiita.com/Chironian/items/8770c8ab833086fb51a9 | |
############################################################ | |
# base | |
############################################################ | |
cmake_minimum_required(VERSION 2.8.8) | |
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) | |
set(CMAKE_SUPPRESS_REGENERATION TRUE) | |
############################################################ | |
# setting Project informations | |
############################################################ | |
set(PROJECT_NAME example) | |
set(LIBRARY_LIST clangFrontend clangSerialization clangDriver clangParse clangRewriteFrontend clangStaticAnalyzerFrontend clangSema) | |
set(LIBRARY_LIST ${LIBRARY_LIST} clangAnalysis clangEdit clangAST clangLex clangBasic clangTooling ) | |
set(COMPONENT_LIST mcparser bitreader support mc option) | |
############################################################ | |
# generate makefiles | |
############################################################ | |
project(${PROJECT_NAME}) | |
find_package(LLVM REQUIRED CONFIG) | |
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") | |
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") | |
include_directories(${LLVM_INCLUDE_DIRS}) | |
if(LLVM_BUILD_MAIN_SRC_DIR) | |
include_directories(${LLVM_BUILD_MAIN_SRC_DIR}/tools/clang/include) | |
include_directories(${LLVM_BUILD_BINARY_DIR}/tools/clang/include) | |
endif() | |
link_directories(${LLVM_LIBRARY_DIRS}) | |
add_definitions(${LLVM_DEFINITIONS}) | |
add_definitions( | |
-D__STDC_LIMIT_MACROS | |
-D__STDC_CONSTANT_MACROS | |
) | |
add_executable(${PROJECT_NAME} main.cpp) | |
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") | |
foreach(link_lib IN LISTS LIBRARY_LIST) | |
target_link_libraries(${PROJECT_NAME} optimized ${link_lib}) | |
target_link_libraries(${PROJECT_NAME} debug ${link_lib}d) | |
endforeach() | |
else() | |
target_link_libraries(${PROJECT_NAME} ${LIBRARY_LIST}) | |
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-unused-parameter -fno-strict-aliasing -fno-exceptions -fno-rtti") | |
#set(CMAKE_EXE_LINKER_FLAGS "-static -static-libgcc -static-libstdc++") | |
endif() | |
#llvm_map_components_to_libnames(llvm_libs ${COMPONENT_LIST}) | |
#target_link_libraries(${PROJECT_NAME} ${llvm_libs}) | |
target_link_libraries(${PROJECT_NAME} | |
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 | |
LLVMAnalysis | |
LLVMTarget | |
LLVMOption # Support | |
LLVMMCParser # MC, Support | |
LLVMMC # Object, Support | |
LLVMObject # BitReader, Core, Support | |
LLVMBitReader # Core, Support | |
LLVMCore # Support | |
LLVMSupport | |
) | |
message(STATUS "User selected librarys = ${LIBRARY_LIST}") | |
message(STATUS "User selected components = ${COMPONENT_LIST}") | |
message(STATUS " = ${llvm_libs}") |
However If you run the cmake, an error will be occurred indicating it failed to find the cmake file for llvm as below output:
➜ build$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
— The C compiler identification is AppleClang 7.0.2.7000181
— The CXX compiler identification is AppleClang 7.0.2.7000181
— Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
— Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc — works
— Detecting C compiler ABI info
— Detecting C compiler ABI info – done
— Detecting C compile features
— Detecting C compile features – done
— Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
— Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ — works
— Detecting CXX compiler ABI info
— Detecting CXX compiler ABI info – done
— Detecting CXX compile features
— Detecting CXX compile features – done
CMake Error at CMakeLists.txt:26 (find_package):
Could not find a package configuration file provided by “LLVM” with any of
the following names:
LLVMConfig.cmake
llvm-config.cmake
Add the installation prefix of “LLVM” to CMAKE_PREFIX_PATH or set
“LLVM_DIR” to a directory containing one of the above files. If “LLVM”
provides a separate development package or SDK, be sure it has been
installed.
— Configuring incomplete, errors occurred!
See also “/Users/hekim/Dropbox/clangtool/build/CMakeFiles/CMakeOutput.log”.
In such case, you need to define CMAKE_PREFIX_PATH which contains LLVMConfig.cmake for its subdirectory. The files are located at:
➜ build$ find ~/Documents/sources/clang-build -name LLVMConfig.cmake
/Users/hekim/Documents/sources/clang-build/cmake/modules/CMakeFiles/LLVMConfig.cmake
/Users/hekim/Documents/sources/clang-build/lib/cmake/llvm/LLVMConfig.cmake
So, I added the llvm&clang build output root directory(where the Makefile files are generated by cmake),
➜ build$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_PREFIX_PATH=/Users/hekim/Documents/sources/clang-build ..
— Found LLVM 4.0.0svn
— Using LLVMConfig.cmake in: /Users/hekim/Documents/sources/clang-build/lib/cmake/llvm
— User selected librarys = clangFrontend;clangSerialization;clangDriver;clangParse;clangRewriteFrontend;clangStaticAnalyzerFrontend;clangSema;clangAnalysis;clangEdit;clangAST;clangLex;clangBasic;clangTooling
— User selected components = mcparser;bitreader;support;mc;option
— =
— Configuring done
— Generating done
— Build files have been written to: /Users/hekim/Dropbox/clangtool/build
➜ build$ make
Scanning dependencies of target example
[ 50%] Building CXX object CMakeFiles/example.dir/main.cpp.o
[100%] Linking CXX executable example
[100%] Built target example
➜ build$ ./example
example: Not enough positional command line arguments specified!
Must specify at least 1 positional argument: See: ./example – help
Then it succeeded.
I just spent a whole day trying to get this to work.
I had no luck until I found your blogpost.
THANK YOU SO MUCH! 🙂 🙂 🙂
Glad it helped! 🙂
I also do this example by following the same sources and CMakeLists.txt in http://qiita.com/Chironian/items/8770c8ab833086fb51a9
But there are some may error occurred when linking.
/home/xlous/Development/compiler/llvm4.0/build/./lib/libclangFrontend.a(CompilerInvocation.cpp.o):in function ‘clang::CompilerInvocation::CreateFromArgs(clang::CompilerInvocation&, char const* const*, char const* const*, clang::DiagnosticsEngine&)’:
CompilerInvocation.cpp:(.text._ZN5clang18CompilerInvocation14CreateFromArgsERS0_PKPKcS5_RNS_17DiagnosticsEngineE+0x5191):undefined reference to ‘llvm::IndexedInstrProfReader::create(llvm::Twine const&)’
CMakeFiles/libTooling.dir/main.cpp.o:(.rodata._ZTIZN5clang7tooling24newFrontendActionFactoryI21ExampleFrontendActionEESt10unique_ptrINS0_21FrontendActionFactoryESt14default_deleteIS4_EEvE27SimpleFrontendActionFactory[_ZTIZN5clang7tooling24newFrontendActionFactoryI21ExampleFrontendActionEESt10unique_ptrINS0_21FrontendActionFactoryESt14default_deleteIS4_EEvE27SimpleFrontendActionFactory]+0x10):undefined reference to ‘typeinfo for clang::tooling::FrontendActionFactory’
CMakeFiles/libTooling.dir/main.cpp.o:(.rodata._ZTI21ExampleFrontendAction[_ZTI21ExampleFrontendAction]+0x10):undefined reference to ‘typeinfo for clang::SyntaxOnlyAction’
CMakeFiles/libTooling.dir/main.cpp.o:(.rodata._ZTI18ExampleASTConsumer[_ZTI18ExampleASTConsumer]+0x10):undefined reference to ‘typeinfo for clang::ASTConsumer’
CMakeFiles/libTooling.dir/main.cpp.o:(.rodata._ZTI18PPCallbacksTracker[_ZTI18PPCallbacksTracker]+0x10):undefined reference to ‘typeinfo for clang::PPCallbacks’
Note that, i use ubuntu 16.04, Clang/LLVM 4.0.0, also the same error in mac osx 10.12 with apple clang 8.1
I’ve used https://github.com/firolino/clang-tool as base project without getting into any build/cmake trouble