diff --git a/CMakeLists.txt b/CMakeLists.txt index 8277d394..173a373e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,39 +1,35 @@ cmake_minimum_required(VERSION 3.8) project(ccls LANGUAGES CXX) -list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) -include(DefaultCMakeBuildType) - -# Required Clang version -option(LLVM_ENABLE_RTTI "-fno-rtti if OFF. This should match LLVM libraries" OFF) -option(USE_SHARED_LLVM "Link against libLLVM.so instead separate LLVM{Option,Support,...}" OFF) option(USE_SYSTEM_RAPIDJSON "Use system RapidJSON instead of the git submodule if exists" ON) # Sources for the executable are specified at end of CMakeLists.txt add_executable(ccls "") -### Compile options +### Default build type -# CMake default compile flags: -# MSVC + Clang(Windows): -# debug: /MDd /Zi /Ob0 /Od /RTC1 -# release: /MD /O2 /Ob2 /DNDEBUG -# GCC + Clang(Linux): -# debug: -g -# release: -O3 -DNDEBUG +set(DEFAULT_CMAKE_BUILD_TYPE Release) + +# CMAKE_BUILD_TYPE is not available if a multi-configuration generator is used +# (eg Visual Studio generators) +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${DEFAULT_CMAKE_BUILD_TYPE}' as none \ +was specified.") + set(CMAKE_BUILD_TYPE ${DEFAULT_CMAKE_BUILD_TYPE} + CACHE STRING "Choose the type of build." FORCE) + + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE + PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo) +endif() + +### Compile options # Enable C++17 (Required) set_property(TARGET ccls PROPERTY CXX_STANDARD 17) set_property(TARGET ccls PROPERTY CXX_STANDARD_REQUIRED ON) set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF) -if(NOT LLVM_ENABLE_RTTI) - # releases.llvm.org libraries are compiled with -fno-rtti - # The mismatch between lib{clang,LLVM}* and ccls can make libstdc++ std::make_shared return nullptr - # _Sp_counted_ptr_inplace::_M_get_deleter - target_compile_options(ccls PRIVATE -fno-rtti) -endif() - # CMake sets MSVC for both MSVC and Clang(Windows) if(MSVC) # Common MSVC/Clang(Windows) options @@ -72,9 +68,41 @@ endif() ### Libraries -# See cmake/FindClang.cmake -find_package(Clang 7.0.0) -target_link_libraries(ccls PRIVATE Clang::Clang) +find_package(Clang REQUIRED) + +target_link_libraries(ccls PRIVATE + clangIndex + clangFormat + clangTooling + clangToolingInclusions + clangToolingCore + clangFrontend + clangParse + clangSerialization + clangSema + clangAST + clangLex + clangDriver + clangBasic +) + +if(LLVM_LINK_LLVM_DYLIB) + target_link_libraries(ccls PRIVATE LLVM) +else() + # In llvm 7, clangDriver headers reference LLVMOption + target_link_libraries(ccls PRIVATE LLVMOption LLVMSupport) +endif() + +if(NOT LLVM_ENABLE_RTTI) + # releases.llvm.org libraries are compiled with -fno-rtti + # The mismatch between lib{clang,LLVM}* and ccls can make libstdc++ std::make_shared return nullptr + # _Sp_counted_ptr_inplace::_M_get_deleter + if(MSVC) + target_compile_options(ccls PRIVATE /GR-) + else() + target_compile_options(ccls PRIVATE -fno-rtti) + endif() +endif() # Enable threading support set(THREADS_PREFER_PTHREAD_FLAG ON) @@ -90,13 +118,34 @@ endif() ### Definitions -target_compile_definitions(ccls PRIVATE - DEFAULT_RESOURCE_DIRECTORY=R"\(${Clang_RESOURCE_DIR}\)") +# Find Clang resource directory with Clang executable. + +find_program(CLANG_EXECUTABLE clang) +if(NOT CLANG_EXECUTABLE) + message(FATAL_ERROR "clang executable not found.") +endif() + +execute_process( + COMMAND ${CLANG_EXECUTABLE} -print-resource-dir + RESULT_VARIABLE CLANG_FIND_RESOURCE_DIR_RESULT + OUTPUT_VARIABLE CLANG_RESOURCE_DIR + ERROR_VARIABLE CLANG_FIND_RESOURCE_DIR_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if(CLANG_FIND_RESOURCE_DIR_RESULT) + message(FATAL_ERROR "Error retrieving Clang resource directory with Clang \ + executable. Output:\n ${CLANG_FIND_RESOURCE_DIR_ERROR}") +endif() + +set_property(SOURCE src/utils.cc APPEND PROPERTY COMPILE_DEFINITIONS + CLANG_RESOURCE_DIRECTORY=R"\(${CLANG_RESOURCE_DIR}\)") ### Includes target_include_directories(ccls PRIVATE src) -target_include_directories(ccls SYSTEM PRIVATE third_party) +target_include_directories(ccls SYSTEM PRIVATE + third_party ${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS}) if(USE_SYSTEM_RAPIDJSON) find_package(RapidJSON QUIET) @@ -110,13 +159,6 @@ target_include_directories(ccls SYSTEM PRIVATE ${RapidJSON_INCLUDE_DIRS}) install(TARGETS ccls RUNTIME DESTINATION bin) -### Tools - -# We use glob here since source files are already manually added with -# target_sources further down -file(GLOB SOURCES src/*.cc src/*.h src/serializers/*.cc src/serializers/*.h - src/messages/*.h src/messages/*.cc) - ### Sources target_sources(ccls PRIVATE third_party/siphash.cc) diff --git a/cmake/DefaultCMakeBuildType.cmake b/cmake/DefaultCMakeBuildType.cmake deleted file mode 100644 index ae440bf5..00000000 --- a/cmake/DefaultCMakeBuildType.cmake +++ /dev/null @@ -1,14 +0,0 @@ -set(DEFAULT_CMAKE_BUILD_TYPE Release) - -# CMAKE_BUILD_TYPE is not available if a multi-configuration generator is used -# (eg Visual Studio generators) -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to '${DEFAULT_CMAKE_BUILD_TYPE}' as none \ -was specified.") - set(CMAKE_BUILD_TYPE ${DEFAULT_CMAKE_BUILD_TYPE} - CACHE STRING "Choose the type of build." FORCE) - - # Set the possible values of build type for cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE - PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo) -endif() diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake deleted file mode 100644 index 078395dd..00000000 --- a/cmake/FindClang.cmake +++ /dev/null @@ -1,153 +0,0 @@ -#.rst -# FindClang -# --------- -# -# Find Clang and LLVM libraries required by ccls -# -# Results are reported in the following variables:: -# -# Clang_FOUND - True if headers and requested libraries were found -# Clang_EXECUTABLE - Clang executable -# Clang_RESOURCE_DIR - Clang resource directory -# Clang_VERSION - Clang version as reported by Clang executable -# -# The following :prop_tgt:`IMPORTED` targets are also defined:: -# -# Clang::Clang - Target for all required Clang libraries and headers -# -# This module reads hints about which libraries to look for and where to find -# them from the following variables:: -# -# CLANG_ROOT - If set, only look for Clang components in CLANG_ROOT -# -# Example to link against Clang target:: -# -# target_link_libraries( PRIVATE Clang::Clang) - -### Definitions - -# Wrapper macro's around the find_* macro's from CMake that only search in -# CLANG_ROOT if it is defined - -macro(_Clang_find_library VAR NAME) - # Windows needs lib prefix - if (CLANG_ROOT) - find_library(${VAR} NAMES ${NAME} lib${NAME} - NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES lib) - else() - find_library(${VAR} NAMES ${NAME} lib${NAME}) - endif() -endmacro() - -macro(_Clang_find_add_library NAME) - _Clang_find_library(${NAME}_LIBRARY ${NAME}) - list(APPEND _Clang_LIBRARIES ${${NAME}_LIBRARY}) -endmacro() - -macro(_Clang_find_path VAR INCLUDE_FILE) - if (CLANG_ROOT) - find_path(${VAR} ${INCLUDE_FILE} - NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES include) - else() - find_path(${VAR} ${INCLUDE_FILE}) - endif() -endmacro() - -macro(_Clang_find_program VAR NAME) - if (CLANG_ROOT) - find_program(${VAR} ${NAME} - NO_DEFAULT_PATH PATHS ${CLANG_ROOT} PATH_SUFFIXES bin) - else() - find_program(${VAR} ${NAME}) - endif() -endmacro() - -### Start - -set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE - Clang_RESOURCE_DIR Clang_VERSION - LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR) - -_Clang_find_library(Clang_LIBRARY clangIndex) -_Clang_find_add_library(clangFormat) -_Clang_find_add_library(clangTooling) - -_Clang_find_library(clangToolingInclusions_LIBRARY clangToolingInclusions) -if (clangToolingInclusions_LIBRARY) - list(APPEND _Clang_LIBRARIES ${clangToolingInclusions_LIBRARY}) -endif() - -_Clang_find_add_library(clangToolingCore) -_Clang_find_add_library(clangRewrite) -_Clang_find_add_library(clangFrontend) -_Clang_find_add_library(clangParse) -_Clang_find_add_library(clangSerialization) -_Clang_find_add_library(clangSema) -_Clang_find_add_library(clangAnalysis) -_Clang_find_add_library(clangEdit) -_Clang_find_add_library(clangAST) -_Clang_find_add_library(clangLex) -_Clang_find_add_library(clangDriver) -_Clang_find_add_library(clangBasic) -if(USE_SHARED_LLVM) - _Clang_find_add_library(LLVM) -else() - _Clang_find_add_library(LLVMMCParser) - _Clang_find_add_library(LLVMMC) - _Clang_find_add_library(LLVMBitReader) - _Clang_find_add_library(LLVMOption) - _Clang_find_add_library(LLVMProfileData) - _Clang_find_add_library(LLVMCore) - _Clang_find_add_library(LLVMBinaryFormat) - _Clang_find_add_library(LLVMSupport) - _Clang_find_add_library(LLVMDemangle) -endif() -_Clang_find_path(Clang_INCLUDE_DIR clang-c/Index.h) -_Clang_find_path(Clang_BUILD_INCLUDE_DIR clang/Driver/Options.inc) -_Clang_find_path(LLVM_INCLUDE_DIR llvm/PassInfo.h) -_Clang_find_path(LLVM_BUILD_INCLUDE_DIR llvm/Config/llvm-config.h) - -_Clang_find_program(Clang_EXECUTABLE clang) -if(Clang_EXECUTABLE) - # Find Clang resource directory with Clang executable - execute_process(COMMAND ${Clang_EXECUTABLE} -print-resource-dir - RESULT_VARIABLE _Clang_FIND_RESOURCE_DIR_RESULT - OUTPUT_VARIABLE Clang_RESOURCE_DIR - ERROR_VARIABLE _Clang_FIND_RESOURCE_DIR_ERROR - OUTPUT_STRIP_TRAILING_WHITESPACE) - - if(_Clang_FIND_RESOURCE_DIR_RESULT) - message(FATAL_ERROR "Error retrieving Clang resource directory with Clang \ -executable. Output:\n ${_Clang_FIND_RESOURCE_DIR_ERROR}") - endif() - - # Find Clang version - set(_Clang_VERSION_REGEX "([0-9]+)\\.([0-9]+)\\.([0-9]+)") - execute_process( - COMMAND ${Clang_EXECUTABLE} --version - OUTPUT_VARIABLE Clang_VERSION - ) - string(REGEX MATCH ${_Clang_VERSION_REGEX} Clang_VERSION ${Clang_VERSION}) -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Clang - FOUND_VAR Clang_FOUND - REQUIRED_VARS ${_Clang_REQUIRED_VARS} - VERSION_VAR Clang_VERSION -) - -if(Clang_FOUND AND NOT TARGET Clang::Clang) - add_library(Clang::Clang UNKNOWN IMPORTED) - set_target_properties(Clang::Clang PROPERTIES - IMPORTED_LOCATION ${Clang_LIBRARY} - INTERFACE_INCLUDE_DIRECTORIES "${Clang_INCLUDE_DIR};${Clang_BUILD_INCLUDE_DIR};${LLVM_INCLUDE_DIR};${LLVM_BUILD_INCLUDE_DIR}") - if(NOT MSVC) - find_package(Curses REQUIRED) - find_package(ZLIB REQUIRED) - endif() - set_property(TARGET Clang::Clang PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES "${_Clang_LIBRARIES};${CURSES_LIBRARIES};${ZLIB_LIBRARIES}") - if(MINGW) - set_property(TARGET Clang::Clang APPEND_STRING PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES ";version") - endif() -endif() diff --git a/src/utils.cc b/src/utils.cc index f37ac58e..46728522 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -189,5 +189,5 @@ int ReverseSubseqMatch(std::string_view pat, std::string_view text, return -1; } -std::string GetDefaultResourceDirectory() { return DEFAULT_RESOURCE_DIRECTORY; } -} +std::string GetDefaultResourceDirectory() { return CLANG_RESOURCE_DIRECTORY; } +} // namespace ccls