File: README.md
ccls
ccls, which originates from cquery, is a C/C++/Objective-C language server.
- code completion (with both signature help and snippets)
- definition/references, and other cross references
- cross reference extensions:
$ccls/call$ccls/inheritance$ccls/member$ccls/vars... - formatting
- hierarchies: call (caller/callee) hierarchy, inheritance (base/derived) hierarchy, member hierarchy
- symbol rename
- document symbols and approximate search of workspace symbol
- hover information
- diagnostics and code actions (clang FixIts)
- semantic highlighting and preprocessor skipped regions
- semantic navigation:
$ccls/navigate
It has a global view of the code base and support a lot of cross reference features, see wiki/FAQ.
It starts indexing the whole project (including subprojects if exist) parallelly when you open the first file, while the main thread can serve requests before the indexing is complete.
Saving files will incrementally update the index.
>>> [Getting started](../../wiki/Home) (CLICK HERE) <<<
ccls can index itself (~180MiB RSS when idle, noted on 2018-09-01), FreeBSD, glibc, Linux, LLVM (~1800MiB RSS), musl (~60MiB RSS), ... with decent memory footprint. See wiki/Project-Setup for examples.
File: CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(ccls LANGUAGES CXX C)
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 "")
Default build type
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)
CMake sets MSVC for both MSVC and Clang(Windows)
if(MSVC)
Common MSVC/Clang(Windows) options
target_compile_options(ccls PRIVATE
/nologo
/EHsc
/D_CRT_SECURE_NO_WARNINGS # don't try to use MSVC std replacements
/W3 # roughly -Wall
/wd4996 # ignore deprecated declaration
/wd4267 # ignores warning C4267
# (conversion from 'size_t' to 'type'),
# roughly -Wno-sign-compare
/wd4800
/wd4068 # Disable unknown pragma warning
/std:c++17
/Zc:__cplusplus
$<$CONFIG:Debug:/FS>
)
relink system libs
target_link_libraries(ccls PRIVATE Mincore.lib)
else()
Common GCC/Clang(Linux) options
target_compile_options(ccls PRIVATE
-Wall
-Wno-sign-compare
)
if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)
target_compile_options(ccls PRIVATE -Wno-return-type -Wno-unused-result)
endif()
if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)
target_compile_options(ccls PRIVATE
$<$CONFIG:Debug:-fno-limit-debug-info>)
endif()
endif()
Libraries
find_package(Clang REQUIRED)
if(CLANG_LINK_CLANG_DYLIB)
target_link_libraries(ccls PRIVATE clang-cpp)
else()
target_link_libraries(ccls PRIVATE
clangIndex
clangFormat
clangTooling
clangToolingInclusions
clangToolingCore
clangFrontend
clangParse
clangSerialization
clangSema
clangAST
clangLex
clangDriver
clangBasic
)
if(LLVM_VERSION_MAJOR GREATER_EQUAL 23) # llvmorg-22-init-27296-g65cb738ff419
target_link_libraries(ccls PRIVATE clangUnifiedSymbolResolution)
endif()
endif()
if(LLVM_LINK_LLVM_DYLIB)
target_link_libraries(ccls PRIVATE LLVM)
else()
target_link_libraries(ccls PRIVATE LLVMOption LLVMSupport)
if(LLVM_VERSION_MAJOR GREATER_EQUAL 16) # llvmorg-16-init-15123-gf09cf34d0062
target_link_libraries(ccls PRIVATE LLVMTargetParser)
endif()
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)
find_package(Threads REQUIRED)
target_link_libraries(ccls PRIVATE Threads::Threads)
if(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
find_package(Backtrace REQUIRED)
target_link_libraries(ccls PRIVATE ${Backtrace_LIBRARIES})
src/platform_posix.cc uses libthr
target_link_libraries(ccls PRIVATE thr)
endif()
if(LLVM_ENABLE_ZLIB)
find_package(ZLIB)
endif()
Definitions
Find Clang resource directory with Clang executable.
if(NOT CLANG_RESOURCE_DIR)
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()
endif()
set_property(SOURCE src/utils.cc APPEND PROPERTY COMPILE_DEFINITIONS
CLANG_RESOURCE_DIRECTORY=R"(${CLANG_RESOURCE_DIR})")
Includes
if(USE_SYSTEM_RAPIDJSON)
set(RapidJSON_MIN_VERSION "1.1.0")
find_package(RapidJSON ${RapidJSON_MIN_VERSION} QUIET)
if(NOT DEFINED RapidJSON_INCLUDE_DIRS AND DEFINED RAPIDJSON_INCLUDE_DIRS)
set(RapidJSON_INCLUDE_DIRS "${RAPIDJSON_INCLUDE_DIRS}")
endif()
endif()
if(NOT RapidJSON_FOUND)
if(EXISTS "${CMAKE_SOURCE_DIR}/third_party/rapidjson/include")
message(STATUS "Using local RapidJSON")
set(RapidJSON_INCLUDE_DIRS third_party/rapidjson/include)
else()
message(STATUS "Plase initialize rapidJSON git submodule as currently installed version is to old:")
message(STATUS "git submodule init && git submodule update")
message(FATAL_ERROR "RapidJSON version is likely too old. See https://github.com/MaskRay/ccls/issues/455")
endif()
endif()
target_include_directories(ccls PRIVATE src)
foreach(include_dir third_party
${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS} ${RapidJSON_INCLUDE_DIRS})
get_filename_component(include_dir_realpath ${include_dir} REALPATH)
Don't add as SYSTEM if they are in CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES.
It would reorder the system search paths and cause issues with libstdc++'s
use of #include_next. See https://github.com/MaskRay/ccls/pull/417
if(NOT "${include_dir_realpath}" IN_LIST CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES)
target_include_directories(ccls SYSTEM PRIVATE ${include_dir})
endif()
endforeach()
Install
install(TARGETS ccls RUNTIME DESTINATION bin)
Sources
target_sources(ccls PRIVATE third_party/siphash.cc)
target_sources(ccls PRIVATE
src/clang_tu.cc
src/config.cc
src/filesystem.cc
src/fuzzy_match.cc
src/main.cc
src/indexer.cc
src/log.cc
src/lsp.cc
src/message_handler.cc
src/pipeline.cc
src/platform_posix.cc
src/platform_win.cc
src/position.cc
src/project.cc
src/query.cc
src/sema_manager.cc
src/serializer.cc
src/test.cc
src/utils.cc
src/working_files.cc
)
target_sources(ccls PRIVATE
src/messages/ccls_call.cc
src/messages/ccls_info.cc
src/messages/ccls_inheritance.cc
src/messages/ccls_member.cc
src/messages/ccls_navigate.cc
src/messages/ccls_reload.cc
src/messages/ccls_vars.cc
src/messages/initialize.cc
src/messages/textDocument_code.cc
src/messages/textDocument_completion.cc
src/messages/textDocument_definition.cc
src/messages/textDocument_did.cc
src/messages/textDocument_foldingRange.cc
src/messages/textDocument_formatting.cc
src/messages/textDocument_document.cc
src/messages/textDocument_hover.cc
src/messages/textDocument_references.cc
src/messages/textDocument_rename.cc
src/messages/textDocument_signatureHelp.cc
src/messages/workspace.cc
)
Obtain CCLS version information from Git
This only happens when cmake is re-run!
if(NOT CCLS_VERSION)
execute_process(COMMAND git describe --tag --long HEAD
OUTPUT_VARIABLE CCLS_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
if(NOT CCLS_VERSION)
set(CCLS_VERSION "")
endif()
endif()
set_property(SOURCE src/main.cc APPEND PROPERTY
COMPILE_DEFINITIONS CCLS_VERSION="${CCLS_VERSION}")
set_property(SOURCE src/messages/initialize.cc APPEND PROPERTY
COMPILE_DEFINITIONS CCLS_VERSION="${CCLS_VERSION}")
File: .appveyor.yml
version: "{build}"
os: Visual Studio 2017
platform:
- x64
build:
parallel: true # enable MSBuild parallel builds
verbosity: minimal
install:
- if not exist llvm.tar.xz appveyor DownloadFile "https://ziglang.org/deps/llvm+clang-7.0.0-win64-msvc-release.tar.xz" -FileName llvm.tar.xz
- 7z e -txz llvm.tar.xz
- 7z x llvm.tar
- git submodule update --init --recursive
build_script: - cmake -G"Visual Studio 15 2017 Win64" -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=C:\projects\ccls\llvm+clang-7.0.0-win64-msvc-release
- cmake --build build --target ccls --config Release
artifacts:
- path: build\Release