ccls Documentation

C/C++/ObjC language server supporting cross references, hierarchies, completion and semantic highlighting

4,091 stars C++ C++ 1 file ยท ~2,618 tokens #cpp#ide#language-server-protocol#lsp-server
RAW Doc

File: README.md

ccls


ccls, which originates from cquery, is a C/C++/Objective-C language server.

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>
)

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