mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 17:11:59 +00:00
Import cmake improvement by Daan De Meyer
This commit is contained in:
parent
a52d56a453
commit
b51347960c
@ -3,13 +3,14 @@ project(ccls LANGUAGES CXX)
|
|||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
||||||
include(DefaultCMakeBuildType)
|
include(DefaultCMakeBuildType)
|
||||||
include(DownloadAndExtractLLVM)
|
|
||||||
|
|
||||||
set(CLANG_VERSION 6.0.0 CACHE STRING "Downloaded Clang version (6.0.0)")
|
# Required libclang version
|
||||||
option(SYSTEM_CLANG "Use system Clang instead of downloading Clang" OFF)
|
set(LIBCLANG_VERSION 6.0.0 CACHE STRING "libclang version")
|
||||||
|
set(LIBCLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR}
|
||||||
|
CACHE STRING "Downloaded libclang location")
|
||||||
|
option(SYSTEM_LIBCLANG "Use system installation of libclang instead of \
|
||||||
|
downloading libclang" OFF)
|
||||||
option(ASAN "Compile with address sanitizers" OFF)
|
option(ASAN "Compile with address sanitizers" OFF)
|
||||||
option(CLANG_CXX "Build with Clang C++ api required by some ccls \
|
|
||||||
features (warning: not available in LLVM Windows downloads)" OFF)
|
|
||||||
|
|
||||||
# Sources for the executable are specified at end of CMakeLists.txt
|
# Sources for the executable are specified at end of CMakeLists.txt
|
||||||
add_executable(ccls "")
|
add_executable(ccls "")
|
||||||
@ -63,13 +64,6 @@ else()
|
|||||||
$<$<CONFIG:Debug>:-fno-limit-debug-info>)
|
$<$<CONFIG:Debug>:-fno-limit-debug-info>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CLANG_CXX)
|
|
||||||
# -Wno-comment: include/clang/Format/Format.h error: multi-line comment
|
|
||||||
# -fno-rtti: # Without -fno-rtti, some Clang C++ functions may report
|
|
||||||
# `undefined references to typeinfo`
|
|
||||||
target_compile_options(ccls PRIVATE -Wno-comment -fno-rtti)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ASAN)
|
if(ASAN)
|
||||||
target_compile_options(ccls PRIVATE -fsanitize=address,undefined)
|
target_compile_options(ccls PRIVATE -fsanitize=address,undefined)
|
||||||
# target_link_libraries also takes linker flags
|
# target_link_libraries also takes linker flags
|
||||||
@ -77,18 +71,23 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
### Download Clang if required
|
### Download libclang if required
|
||||||
|
|
||||||
if(NOT SYSTEM_CLANG)
|
if(NOT SYSTEM_LIBCLANG)
|
||||||
download_and_extract_llvm(${CLANG_VERSION})
|
message(STATUS "Using downloaded libclang")
|
||||||
|
|
||||||
|
include(DownloadAndExtractClang)
|
||||||
|
download_and_extract_clang(${LIBCLANG_VERSION} ${LIBCLANG_DOWNLOAD_LOCATION})
|
||||||
# Used by FindClang
|
# Used by FindClang
|
||||||
set(CLANG_ROOT ${DOWNLOADED_CLANG_DIR})
|
set(CLANG_ROOT ${DOWNLOADED_CLANG_DIR})
|
||||||
|
else()
|
||||||
|
message(STATUS "Using system libclang")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
### Libraries
|
### Libraries
|
||||||
|
|
||||||
# See cmake/FindClang.cmake
|
# See cmake/FindClang.cmake
|
||||||
find_package(Clang REQUIRED)
|
find_package(Clang ${CLANG_VERSION} REQUIRED)
|
||||||
target_link_libraries(ccls PRIVATE Clang::Clang)
|
target_link_libraries(ccls PRIVATE Clang::Clang)
|
||||||
|
|
||||||
# Enable threading support
|
# Enable threading support
|
||||||
@ -96,7 +95,9 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
|
|||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
target_link_libraries(ccls PRIVATE Threads::Threads)
|
target_link_libraries(ccls PRIVATE Threads::Threads)
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
|
||||||
|
target_link_libraries(ccls PRIVATE -lc++experimental)
|
||||||
|
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(ccls PRIVATE -lstdc++fs)
|
target_link_libraries(ccls PRIVATE -lstdc++fs)
|
||||||
endif()
|
endif()
|
||||||
@ -117,12 +118,6 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
|||||||
target_link_libraries(ccls PRIVATE Psapi)
|
target_link_libraries(ccls PRIVATE Psapi)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CLANG_CXX)
|
|
||||||
# Clang C++ api uses ncurses
|
|
||||||
find_package(Curses REQUIRED)
|
|
||||||
target_link_libraries(ccls PRIVATE ${CURSES_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
### Definitions
|
### Definitions
|
||||||
|
|
||||||
target_compile_definitions(ccls PRIVATE
|
target_compile_definitions(ccls PRIVATE
|
||||||
@ -131,10 +126,6 @@ target_compile_definitions(ccls PRIVATE
|
|||||||
LOGURU_THREADNAME_WIDTH=13
|
LOGURU_THREADNAME_WIDTH=13
|
||||||
DEFAULT_RESOURCE_DIRECTORY="${Clang_RESOURCE_DIR}")
|
DEFAULT_RESOURCE_DIRECTORY="${Clang_RESOURCE_DIR}")
|
||||||
|
|
||||||
if(CLANG_CXX)
|
|
||||||
target_compile_definitions(ccls PRIVATE USE_CLANG_CXX=1 LOGURU_RTTI=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
### Includes
|
### Includes
|
||||||
|
|
||||||
target_include_directories(ccls PRIVATE
|
target_include_directories(ccls PRIVATE
|
||||||
@ -150,9 +141,8 @@ target_include_directories(ccls PRIVATE
|
|||||||
|
|
||||||
install(TARGETS ccls RUNTIME DESTINATION bin)
|
install(TARGETS ccls RUNTIME DESTINATION bin)
|
||||||
|
|
||||||
# We don't need to install libclang on Windows if we are using downloaded LLVM
|
# TODO: install libclang.dll on Windows as well
|
||||||
# since libclang is distributed as a static library on Windows
|
if(NOT SYSTEM_LIBCLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
||||||
if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES Linux|FreeBSD)
|
if(${CMAKE_SYSTEM_NAME} MATCHES Linux|FreeBSD)
|
||||||
set_property(TARGET ccls APPEND PROPERTY
|
set_property(TARGET ccls APPEND PROPERTY
|
||||||
@ -167,6 +157,44 @@ if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
|||||||
install(FILES ${LIBCLANG_PLUS_SYMLINKS} DESTINATION lib)
|
install(FILES ${LIBCLANG_PLUS_SYMLINKS} DESTINATION lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Allow running from build Windows by copying libclang.dll to build directory
|
||||||
|
if(NOT SYSTEM_LIBCLANG AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
||||||
|
add_custom_command(TARGET ccls
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy
|
||||||
|
${DOWNLOADED_CLANG_DIR}/bin/libclang.dll
|
||||||
|
$<TARGET_FILE_DIR:ccls>
|
||||||
|
COMMENT "Copying libclang.dll to build directory ...")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
### 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)
|
||||||
|
|
||||||
|
if(Clang_FORMAT AND ${Clang_VERSION} STREQUAL 6.0.0)
|
||||||
|
add_custom_target(format
|
||||||
|
COMMAND ${Clang_FORMAT} -i ${SOURCES}
|
||||||
|
# .clang-format is located in the ccls root project dir
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
COMMENT "Running clang-format ...")
|
||||||
|
else()
|
||||||
|
# Set error message depending on which condition was false
|
||||||
|
if (NOT Clang_FORMAT)
|
||||||
|
set(Clang_FORMAT_ERROR "Error: clang-format executable not found")
|
||||||
|
elseif(NOT ${Clang_VERSION} STREQUAL 6.0.0)
|
||||||
|
set(Clang_FORMAT_ERROR "Error: clang-format version does not match \
|
||||||
|
6.0.0. Due to differences in clang-format output between versions we only \
|
||||||
|
support clang-format 6.0.0")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_target(format
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold
|
||||||
|
${Clang_FORMAT_ERROR})
|
||||||
|
endif()
|
||||||
|
|
||||||
### Sources
|
### Sources
|
||||||
|
|
||||||
target_sources(ccls PRIVATE third_party/siphash.cc)
|
target_sources(ccls PRIVATE third_party/siphash.cc)
|
||||||
|
@ -1,29 +1,27 @@
|
|||||||
# Downloads and extracts the 7-Zip MSI installer from https://www.7-zip.org/.
|
# Downloads and extracts the 7-Zip MSI installer from https://www.7-zip.org/.
|
||||||
#
|
#
|
||||||
# Returns the extracted 7-Zip directory in DOWNLOADED_7ZIP_DIR
|
# Returns the extracted 7-Zip directory in DOWNLOADED_7ZIP_DIR
|
||||||
#
|
function(download_and_extract_7zip 7ZIP_DOWNLOAD_LOCATION)
|
||||||
# Downloads 7-Zip to extract LLVM if it isn't available in the PATH
|
|
||||||
function(download_and_extract_7zip)
|
|
||||||
|
|
||||||
set(7ZIP_VERSION 1801)
|
set(7ZIP_VERSION 1801)
|
||||||
set(7ZIP_EXT .msi)
|
set(7ZIP_EXT .msi)
|
||||||
set(7ZIP_NAME 7z${7ZIP_VERSION}-x64)
|
set(7ZIP_NAME 7z${7ZIP_VERSION}-x64)
|
||||||
set(7ZIP_FULL_NAME ${7ZIP_NAME}${7ZIP_EXT})
|
set(7ZIP_FULL_NAME ${7ZIP_NAME}${7ZIP_EXT})
|
||||||
|
|
||||||
set(7ZIP_FILE ${CMAKE_BINARY_DIR}/${7ZIP_FULL_NAME})
|
set(7ZIP_FILE ${7ZIP_DOWNLOAD_LOCATION}/${7ZIP_FULL_NAME})
|
||||||
set(7ZIP_EXTRACT_DIR ${CMAKE_BINARY_DIR}/${7ZIP_NAME})
|
set(7ZIP_EXTRACT_DIR ${7ZIP_DOWNLOAD_LOCATION}/${7ZIP_NAME})
|
||||||
set(7ZIP_URL https://www.7-zip.org/a/${7ZIP_FULL_NAME})
|
set(7ZIP_URL https://www.7-zip.org/a/${7ZIP_FULL_NAME})
|
||||||
|
|
||||||
# msiexec requires Windows path separators (\)
|
# Exit if 7-Zip is already downloaded and extracted
|
||||||
file(TO_NATIVE_PATH ${7ZIP_FILE} 7ZIP_FILE)
|
find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH
|
||||||
file(TO_NATIVE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR)
|
PATHS ${7ZIP_EXTRACT_DIR}/Files/7-Zip)
|
||||||
|
if(7ZIP_EXECUTABLE)
|
||||||
if(NOT EXISTS ${7ZIP_FILE})
|
message(STATUS "7-Zip already downloaded")
|
||||||
message(STATUS "Downloading 7-Zip ${7ZIP_VERSION} (${7ZIP_URL}) ...")
|
return()
|
||||||
file(DOWNLOAD ${7ZIP_URL} ${7ZIP_FILE})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT EXISTS ${7ZIP_EXTRACT_DIR})
|
message(STATUS "Downloading 7-Zip ${7ZIP_VERSION} (${7ZIP_URL}) ...")
|
||||||
|
file(DOWNLOAD ${7ZIP_URL} ${7ZIP_FILE})
|
||||||
|
|
||||||
find_program(MSIEXEC_EXECUTABLE msiexec)
|
find_program(MSIEXEC_EXECUTABLE msiexec)
|
||||||
if(NOT MSIEXEC_EXECUTABLE)
|
if(NOT MSIEXEC_EXECUTABLE)
|
||||||
@ -33,19 +31,22 @@ installer). Install 7-Zip yourself and make sure it is available in the path")
|
|||||||
|
|
||||||
message(STATUS "Extracting downloaded 7-Zip ...")
|
message(STATUS "Extracting downloaded 7-Zip ...")
|
||||||
|
|
||||||
|
# msiexec requires Windows path separators (\)
|
||||||
|
file(TO_NATIVE_PATH ${7ZIP_FILE} 7ZIP_FILE)
|
||||||
|
file(TO_NATIVE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR)
|
||||||
|
|
||||||
# msiexec with /a option allows extraction of msi installers without requiring
|
# msiexec with /a option allows extraction of msi installers without requiring
|
||||||
# admin privileges. We use this to extract the 7-Zip installer without
|
# admin privileges. We use this to extract the 7-Zip installer without
|
||||||
# requiring any actions from the user
|
# requiring any actions from the user
|
||||||
execute_process(COMMAND ${MSIEXEC_EXECUTABLE} /a ${7ZIP_FILE} /qn
|
execute_process(COMMAND ${MSIEXEC_EXECUTABLE} /a ${7ZIP_FILE} /qn
|
||||||
TARGETDIR=${7ZIP_EXTRACT_DIR}
|
TARGETDIR=${7ZIP_EXTRACT_DIR}
|
||||||
|
WORKING_DIRECTORY ${7ZIP_DOWNLOAD_LOCATION}
|
||||||
OUTPUT_QUIET)
|
OUTPUT_QUIET)
|
||||||
endif()
|
|
||||||
|
|
||||||
# Convert back to CMake separators (/) before returning
|
# Convert back to CMake separators (/) before returning
|
||||||
file(TO_CMAKE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR)
|
file(TO_CMAKE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR)
|
||||||
|
|
||||||
# Actual directory is nested inside the extract directory. We return the nested
|
# Actual 7-Zip directory is nested inside the extract directory.
|
||||||
# directory instead of the extract directory
|
|
||||||
set(DOWNLOADED_7ZIP_DIR ${7ZIP_EXTRACT_DIR}/Files/7-Zip PARENT_SCOPE)
|
set(DOWNLOADED_7ZIP_DIR ${7ZIP_EXTRACT_DIR}/Files/7-Zip PARENT_SCOPE)
|
||||||
|
|
||||||
endfunction()
|
endfunction()
|
124
cmake/DownloadAndExtractClang.cmake
Normal file
124
cmake/DownloadAndExtractClang.cmake
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
# Downloads and extracts the Clang archive for the current system from
|
||||||
|
# https://releases.llvm.org
|
||||||
|
#
|
||||||
|
# Returns the extracted Clang archive directory in DOWNLOADED_CLANG_DIR
|
||||||
|
#
|
||||||
|
# Downloads 7-Zip to extract Clang if it isn't available in the PATH
|
||||||
|
function(download_and_extract_clang CLANG_VERSION CLANG_DOWNLOAD_LOCATION)
|
||||||
|
|
||||||
|
set(CLANG_ARCHIVE_EXT .tar.xz)
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
|
||||||
|
|
||||||
|
set(CLANG_ARCHIVE_NAME
|
||||||
|
clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04)
|
||||||
|
|
||||||
|
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
|
||||||
|
|
||||||
|
set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-x86_64-apple-darwin)
|
||||||
|
|
||||||
|
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
||||||
|
|
||||||
|
set(CLANG_ARCHIVE_NAME LLVM-${CLANG_VERSION}-win64)
|
||||||
|
set(CLANG_ARCHIVE_EXT .exe)
|
||||||
|
|
||||||
|
elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
|
||||||
|
|
||||||
|
if(${CLANG_VERSION} STREQUAL 6.0.0)
|
||||||
|
set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd-10)
|
||||||
|
else()
|
||||||
|
set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd10)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CLANG_ARCHIVE_FULL_NAME ${CLANG_ARCHIVE_NAME}${CLANG_ARCHIVE_EXT})
|
||||||
|
set(CLANG_ARCHIVE_FILE ${CLANG_DOWNLOAD_LOCATION}/${CLANG_ARCHIVE_FULL_NAME})
|
||||||
|
set(CLANG_ARCHIVE_EXTRACT_DIR ${CLANG_DOWNLOAD_LOCATION}/${CLANG_ARCHIVE_NAME})
|
||||||
|
set(CLANG_ARCHIVE_URL
|
||||||
|
https://releases.llvm.org/${CLANG_VERSION}/${CLANG_ARCHIVE_FULL_NAME})
|
||||||
|
set(CLANG_ARCHIVE_HASH_FILE
|
||||||
|
${CMAKE_SOURCE_DIR}/clang_archive_hashes/${CLANG_ARCHIVE_FULL_NAME}.SHA256)
|
||||||
|
|
||||||
|
# Exit if Clang is already downloaded and extracted
|
||||||
|
set(CLANG_ROOT ${CLANG_ARCHIVE_EXTRACT_DIR})
|
||||||
|
find_package(Clang ${CLANG_VERSION} QUIET)
|
||||||
|
if(Clang_FOUND)
|
||||||
|
message(STATUS "Clang already downloaded")
|
||||||
|
set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT CLANG_ARCHIVE_NAME)
|
||||||
|
message(FATAL_ERROR "No Clang archive url specified for current platform \
|
||||||
|
(${CMAKE_SYSTEM_NAME}). Please file an issue to get it added.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT EXISTS ${CLANG_ARCHIVE_HASH_FILE})
|
||||||
|
message(FATAL_ERROR "No SHA256 hash available for the current platform \
|
||||||
|
(${CMAKE_SYSTEM_NAME}) + clang version (${CLANG_VERSION}) combination. Please \
|
||||||
|
file an issue to get it added.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Download Clang archive
|
||||||
|
message(STATUS "Downloading Clang ${CLANG_VERSION} (${CLANG_ARCHIVE_URL}) ...")
|
||||||
|
file(DOWNLOAD ${CLANG_ARCHIVE_URL} ${CLANG_ARCHIVE_FILE}
|
||||||
|
STATUS CLANG_ARCHIVE_DOWNLOAD_RESULT)
|
||||||
|
|
||||||
|
# Abort if download failed
|
||||||
|
list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 0 ERROR_CODE)
|
||||||
|
if(${ERROR_CODE})
|
||||||
|
list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 1 ERROR_STRING)
|
||||||
|
message(FATAL_ERROR ${ERROR_STRING})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Retrieve expected hash from file and strip newline
|
||||||
|
file(READ ${CLANG_ARCHIVE_HASH_FILE} CLANG_ARCHIVE_EXPECTED_HASH)
|
||||||
|
string(STRIP ${CLANG_ARCHIVE_EXPECTED_HASH} CLANG_ARCHIVE_EXPECTED_HASH)
|
||||||
|
# Calculate actual hash
|
||||||
|
file(SHA256 ${CLANG_ARCHIVE_FILE} CLANG_ARCHIVE_HASH)
|
||||||
|
# Abort if hashes do not match
|
||||||
|
if(NOT ${CLANG_ARCHIVE_EXPECTED_HASH} STREQUAL ${CLANG_ARCHIVE_HASH})
|
||||||
|
message(FATAL_ERROR "SHA256 hash of downloaded Clang does not match \
|
||||||
|
expected hash. Remove the build directory and try running CMake again. If this \
|
||||||
|
keeps happening, file an issue to report the problem.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${CLANG_ARCHIVE_EXT} STREQUAL .exe)
|
||||||
|
# Download and extract 7-zip if not found in PATH
|
||||||
|
find_program(7ZIP_EXECUTABLE 7z)
|
||||||
|
if(NOT 7ZIP_EXECUTABLE)
|
||||||
|
message(STATUS "7-Zip not found in PATH")
|
||||||
|
|
||||||
|
include(DownloadAndExtract7zip)
|
||||||
|
download_and_extract_7zip(${CLANG_DOWNLOAD_LOCATION})
|
||||||
|
find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH
|
||||||
|
PATHS ${DOWNLOADED_7ZIP_DIR})
|
||||||
|
else()
|
||||||
|
message(STATUS "7-Zip found in PATH")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Extracting downloaded Clang with 7-Zip ...")
|
||||||
|
|
||||||
|
# Avoid running the Clang installer by extracting the exe with 7-Zip
|
||||||
|
execute_process(COMMAND ${7ZIP_EXECUTABLE} x
|
||||||
|
-o${CLANG_ARCHIVE_EXTRACT_DIR}
|
||||||
|
-xr!$PLUGINSDIR ${CLANG_ARCHIVE_FILE}
|
||||||
|
WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION}
|
||||||
|
OUTPUT_QUIET)
|
||||||
|
|
||||||
|
elseif(${CLANG_ARCHIVE_EXT} STREQUAL .tar.xz)
|
||||||
|
message(STATUS "Extracting downloaded Clang with CMake built-in tar ...")
|
||||||
|
|
||||||
|
# CMake has builtin support for tar via the -E flag
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE}
|
||||||
|
# Specify working directory to allow running cmake from
|
||||||
|
# everywhere
|
||||||
|
# (example: cmake -H"$HOME/ccls" -B"$home/ccls/build")
|
||||||
|
WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION}
|
||||||
|
OUTPUT_QUIET)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE)
|
||||||
|
|
||||||
|
endfunction()
|
@ -1,112 +0,0 @@
|
|||||||
# Downloads and extracts the LLVM archive for the current system from
|
|
||||||
# https://releases.llvm.org
|
|
||||||
#
|
|
||||||
# Returns the extracted LLVM archive directory in DOWNLOADED_CLANG_DIR
|
|
||||||
#
|
|
||||||
# Downloads 7-Zip to extract LLVM if it isn't available in the PATH
|
|
||||||
function(download_and_extract_llvm CLANG_VERSION)
|
|
||||||
|
|
||||||
include(DownloadAndExtract7zip)
|
|
||||||
|
|
||||||
set(CLANG_ARCHIVE_EXT .tar.xz)
|
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
|
|
||||||
|
|
||||||
set(CLANG_ARCHIVE_NAME
|
|
||||||
clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-14.04)
|
|
||||||
|
|
||||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
|
|
||||||
|
|
||||||
set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-x86_64-apple-darwin)
|
|
||||||
|
|
||||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
|
||||||
|
|
||||||
set(CLANG_ARCHIVE_NAME LLVM-${CLANG_VERSION}-win64)
|
|
||||||
set(CLANG_ARCHIVE_EXT .exe)
|
|
||||||
|
|
||||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
|
|
||||||
|
|
||||||
if(${CLANG_VERSION} STREQUAL 6.0.0)
|
|
||||||
set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd-10)
|
|
||||||
else()
|
|
||||||
set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd10)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT CLANG_ARCHIVE_NAME)
|
|
||||||
message(FATAL_ERROR "No LLVM archive url specified for current platform \
|
|
||||||
(${CMAKE_SYSTEM_NAME}). Please file an issue to get it added.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CLANG_ARCHIVE_FULL_NAME ${CLANG_ARCHIVE_NAME}${CLANG_ARCHIVE_EXT})
|
|
||||||
set(CLANG_ARCHIVE_FILE ${CMAKE_BINARY_DIR}/${CLANG_ARCHIVE_FULL_NAME})
|
|
||||||
set(CLANG_ARCHIVE_EXTRACT_DIR ${CMAKE_BINARY_DIR}/${CLANG_ARCHIVE_NAME})
|
|
||||||
set(CLANG_ARCHIVE_URL
|
|
||||||
https://releases.llvm.org/${CLANG_VERSION}/${CLANG_ARCHIVE_FULL_NAME})
|
|
||||||
set(CLANG_ARCHIVE_HASH_FILE
|
|
||||||
${CMAKE_SOURCE_DIR}/clang_archive_hashes/${CLANG_ARCHIVE_FULL_NAME}.SHA256)
|
|
||||||
|
|
||||||
if(NOT EXISTS ${CLANG_ARCHIVE_HASH_FILE})
|
|
||||||
message(FATAL_ERROR "No SHA256 hash available for the current platform \
|
|
||||||
(${CMAKE_SYSTEM_NAME}) + clang version (${CLANG_VERSION}) combination. Please \
|
|
||||||
file an issue to get it added.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(READ ${CLANG_ARCHIVE_HASH_FILE} CLANG_ARCHIVE_EXPECTED_HASH)
|
|
||||||
# Strip newline
|
|
||||||
string(STRIP ${CLANG_ARCHIVE_EXPECTED_HASH} CLANG_ARCHIVE_EXPECTED_HASH)
|
|
||||||
|
|
||||||
if(NOT EXISTS ${CLANG_ARCHIVE_FILE})
|
|
||||||
message(STATUS "Downloading LLVM ${CLANG_VERSION} (${CLANG_ARCHIVE_URL}) ...")
|
|
||||||
file(DOWNLOAD ${CLANG_ARCHIVE_URL} ${CLANG_ARCHIVE_FILE}
|
|
||||||
STATUS CLANG_ARCHIVE_DOWNLOAD_RESULT)
|
|
||||||
|
|
||||||
list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 0 ERROR_CODE)
|
|
||||||
if(${ERROR_CODE})
|
|
||||||
list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 1 ERROR_STRING)
|
|
||||||
message(FATAL_ERROR ${ERROR_STRING})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(SHA256 ${CLANG_ARCHIVE_FILE} CLANG_ARCHIVE_HASH)
|
|
||||||
if(NOT ${CLANG_ARCHIVE_EXPECTED_HASH} STREQUAL ${CLANG_ARCHIVE_HASH})
|
|
||||||
message(FATAL_ERROR "SHA256 hash of downloaded LLVM does not match \
|
|
||||||
expected hash. Remove the build directory and try running CMake again. If this \
|
|
||||||
keeps happening, file an issue to report the problem.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT EXISTS ${CLANG_ARCHIVE_EXTRACT_DIR})
|
|
||||||
if(${CLANG_ARCHIVE_EXT} STREQUAL .exe)
|
|
||||||
find_program(7ZIP_EXECUTABLE 7z)
|
|
||||||
|
|
||||||
if(NOT 7ZIP_EXECUTABLE)
|
|
||||||
message(STATUS "7-Zip not found in PATH")
|
|
||||||
download_and_extract_7zip()
|
|
||||||
find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH
|
|
||||||
PATHS ${DOWNLOADED_7ZIP_DIR})
|
|
||||||
else()
|
|
||||||
message(STATUS "7-Zip found in PATH")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "Extracting downloaded LLVM with 7-Zip ...")
|
|
||||||
|
|
||||||
# Avoid running the LLVM installer by extracting the exe with 7-Zip
|
|
||||||
execute_process(COMMAND ${7ZIP_EXECUTABLE} x
|
|
||||||
-o${CLANG_ARCHIVE_EXTRACT_DIR}
|
|
||||||
-xr!$PLUGINSDIR ${CLANG_ARCHIVE_FILE}
|
|
||||||
OUTPUT_QUIET)
|
|
||||||
elseif(${CLANG_ARCHIVE_EXT} STREQUAL .tar.xz)
|
|
||||||
message(STATUS "Extracting downloaded LLVM with CMake built-in tar ...")
|
|
||||||
# CMake has builtin support for tar via the -E flag
|
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE}
|
|
||||||
# Extract to here to allow running cmake from everywhere
|
|
||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
|
||||||
OUTPUT_QUIET)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# CMake functions have no return values so we just lift our return variable to
|
|
||||||
# the parent scope
|
|
||||||
set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE)
|
|
||||||
|
|
||||||
endfunction()
|
|
@ -2,12 +2,13 @@
|
|||||||
# FindClang
|
# FindClang
|
||||||
# ---------
|
# ---------
|
||||||
#
|
#
|
||||||
# Find Clang and LLVM libraries required by cquery
|
# Find Clang and LLVM libraries required by ccls
|
||||||
#
|
#
|
||||||
# Results are reported in the following variables::
|
# Results are reported in the following variables::
|
||||||
#
|
#
|
||||||
# Clang_FOUND - True if headers and requested libraries were found
|
# Clang_FOUND - True if headers and requested libraries were found
|
||||||
# Clang_EXECUTABLE - Clang executable
|
# Clang_EXECUTABLE - Clang executable
|
||||||
|
# Clang_FORMAT - Clang-format executable
|
||||||
# Clang_RESOURCE_DIR - Clang resource directory
|
# Clang_RESOURCE_DIR - Clang resource directory
|
||||||
# Clang_VERSION - Clang version as reported by Clang executable
|
# Clang_VERSION - Clang version as reported by Clang executable
|
||||||
#
|
#
|
||||||
@ -96,13 +97,21 @@ if(CLANG_CXX)
|
|||||||
_Clang_find_and_add_cxx_lib(LLVMDemangle llvm/Demangle/Demangle.h)
|
_Clang_find_and_add_cxx_lib(LLVMDemangle llvm/Demangle/Demangle.h)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
_Clang_find_program(Clang_FORMAT clang-format)
|
||||||
_Clang_find_program(Clang_EXECUTABLE clang)
|
_Clang_find_program(Clang_EXECUTABLE clang)
|
||||||
if(Clang_EXECUTABLE)
|
if(Clang_EXECUTABLE)
|
||||||
# Find Clang resource directory with Clang executable
|
# Find Clang resource directory with Clang executable
|
||||||
execute_process(COMMAND ${Clang_EXECUTABLE} -print-resource-dir
|
execute_process(COMMAND ${Clang_EXECUTABLE} -print-resource-dir
|
||||||
|
RESULT_VARIABLE _Clang_FIND_RESOURCE_DIR_RESULT
|
||||||
OUTPUT_VARIABLE Clang_RESOURCE_DIR
|
OUTPUT_VARIABLE Clang_RESOURCE_DIR
|
||||||
|
ERROR_VARIABLE _Clang_FIND_RESOURCE_DIR_ERROR
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
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
|
# Find Clang version
|
||||||
set(_Clang_VERSION_REGEX "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
|
set(_Clang_VERSION_REGEX "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
|
||||||
execute_process(COMMAND ${Clang_EXECUTABLE} --version
|
execute_process(COMMAND ${Clang_EXECUTABLE} --version
|
||||||
|
Loading…
Reference in New Issue
Block a user