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.
## 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