Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/test-cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,27 @@ jobs:

- uses: ./.github/actions/setup-pixi

- name: Restore compiler cache
uses: actions/cache@v4
with:
path: ${{ runner.os == 'Windows' && '~\AppData\Local\Mozilla\sccache' || '~/.cache/ccache' }}
Comment thread
16bit-ykiko marked this conversation as resolved.
Outdated
key: ${{ runner.os }}-${{ matrix.build_type }}-ccache-${{ github.sha }}
restore-keys: |
${{ runner.os }}-${{ matrix.build_type }}-ccache-

- name: Build
run: pixi run build ${{ matrix.build_type }} ON

- name: Print cache stats
if: always()
run: |
if [ "$RUNNER_OS" = "Windows" ]; then
pixi run -- sccache --show-stats
else
pixi run -- ccache --show-stats
fi
shell: bash

- name: Unit Test
run: pixi run unit-test ${{ matrix.build_type }}

Expand Down
201 changes: 138 additions & 63 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,44 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")

option(CLICE_ENABLE_LTO "Enable ThinLTO for all targets" OFF)
option(CLICE_USE_LIBCXX "Use libc++ instead of libstdc++" OFF)
option(CLICE_OFFLINE_BUILD "Disable network downloads during configuration" OFF)
option(CLICE_ENABLE_TEST "Build unit tests" OFF)
option(CLICE_CI_ENVIRONMENT "Enable CI-specific configuration" OFF)
option(CLICE_ENABLE_BENCHMARK "Build benchmarks" OFF)
option(CLICE_RELEASE "Enable release packaging (LTO + strip + pack)" OFF)

# Global flags that apply to all targets (including FetchContent dependencies).
if(NOT MSVC)
add_compile_options(-ffunction-sections -fdata-sections)
endif()

if(APPLE)
# https://conda-forge.org/docs/maintainer/knowledge_base/#newer-c-features-with-old-sdk
add_compile_definitions(_LIBCPP_DISABLE_AVAILABILITY=1)
endif()

if(WIN32)
string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,/OPT:REF")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -Wl,/OPT:REF")
elseif(APPLE)
string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,-dead_strip")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -Wl,-dead_strip")
else()
string(APPEND CMAKE_EXE_LINKER_FLAGS " -static-libstdc++ -static-libgcc -Wl,--gc-sections")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -Wl,--gc-sections")
endif()
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

# Make sure all third libraries are affected by ABI related options
if(CLICE_USE_LIBCXX)
string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++")
string(APPEND CMAKE_EXE_LINKER_FLAGS " -stdlib=libc++")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -stdlib=libc++")
endif()

if(CLICE_RELEASE)
set(CLICE_ENABLE_LTO ON)
endif()

if(CLICE_ENABLE_LTO)
string(APPEND CMAKE_C_FLAGS " -flto=thin")
string(APPEND CMAKE_CXX_FLAGS " -flto=thin")
Expand All @@ -33,7 +63,6 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_options(-fsanitize=address)

if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
# clang-cl (MSVC frontend): manually link ASan runtime.
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} --print-resource-dir
OUTPUT_VARIABLE CLANG_RESOURCE_DIR
Expand All @@ -47,81 +76,50 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND ASAN_LINK_FLAGS "/wholearchive:clang_rt.asan_dynamic_runtime_thunk-x86_64.lib")

foreach(flag ${ASAN_LINK_FLAGS})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${flag}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${flag}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${flag}")
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${flag}")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " ${flag}")
string(APPEND CMAKE_MODULE_LINKER_FLAGS " ${flag}")
endforeach()
else()
# GNU frontend (clang++/gcc): -fsanitize=address handles linking automatically.
string(APPEND CMAKE_EXE_LINKER_FLAGS " -fsanitize=address")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -fsanitize=address")
endif()

if(WIN32)
# Disable Identical COMDAT Folding in Debug to avoid ASan ODR false positives.
string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,/OPT:NOICF")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -Wl,/OPT:NOICF")
endif()
endif()

if(APPLE)
# https://conda-forge.org/docs/maintainer/knowledge_base/#newer-c-features-with-old-sdk
string(APPEND CMAKE_CXX_FLAGS " -D_LIBCPP_DISABLE_AVAILABILITY=1")
endif()

include("${PROJECT_SOURCE_DIR}/cmake/package.cmake")

# Project-specific options (not applied to third-party deps).
add_library(clice_options INTERFACE)

if(CLICE_ENABLE_TEST)
target_compile_definitions(clice_options INTERFACE CLICE_ENABLE_TEST=1)
endif()

if(CLICE_CI_ENVIRONMENT)
target_compile_definitions(clice_options INTERFACE CLICE_CI_ENVIRONMENT=1)
endif()

if(WIN32)
target_link_libraries(clice_options INTERFACE version ntdll)
endif()

if(WIN32)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
target_link_options(clice_options INTERFACE
-fuse-ld=lld-link
-Wl,/OPT:REF
#,/OPT:NOICF
)
elseif(APPLE)
target_link_options(clice_options INTERFACE
-fuse-ld=lld
-Wl,-dead_strip
)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_options(clice_options INTERFACE
-fuse-ld=lld
-static-libstdc++ -static-libgcc
-Wl,--gc-sections
)
endif()

if(MSVC OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
target_compile_options(clice_options INTERFACE
/GR-
/EHsc-
/Zc:preprocessor
)
target_compile_options(clice_options INTERFACE /GR- /EHsc- /Zc:preprocessor)
else()
target_compile_options(clice_options INTERFACE
-fno-rtti
-fno-exceptions
Comment thread
16bit-ykiko marked this conversation as resolved.
-Wno-deprecated-declarations
-ffunction-sections
-fdata-sections
$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wno-undefined-inline>
)
endif()

if(WIN32)
target_link_libraries(clice_options INTERFACE version ntdll)
endif()

if(CLICE_ENABLE_TEST)
target_compile_definitions(clice_options INTERFACE CLICE_ENABLE_TEST=1)
endif()

if(CLICE_CI_ENVIRONMENT)
target_compile_definitions(clice_options INTERFACE CLICE_CI_ENVIRONMENT=1)
endif()

set(FBS_SCHEMA_FILE "${PROJECT_SOURCE_DIR}/src/index/schema.fbs")
set(GENERATED_HEADER "${PROJECT_BINARY_DIR}/generated/schema_generated.h")

Expand Down Expand Up @@ -154,7 +152,6 @@ add_library(clice-core STATIC
"${PROJECT_SOURCE_DIR}/src/syntax/scan.cpp"
"${PROJECT_SOURCE_DIR}/src/syntax/include_resolver.cpp"
"${PROJECT_SOURCE_DIR}/src/syntax/dependency_graph.cpp"
"${PROJECT_SOURCE_DIR}/src/syntax/include_resolver.cpp"
"${PROJECT_SOURCE_DIR}/src/feature/semantic_tokens.cpp"
"${PROJECT_SOURCE_DIR}/src/feature/document_links.cpp"
"${PROJECT_SOURCE_DIR}/src/feature/document_symbols.cpp"
Expand Down Expand Up @@ -203,10 +200,11 @@ add_executable(clice "${PROJECT_SOURCE_DIR}/src/clice.cc")
target_link_libraries(clice PRIVATE clice::core eventide::deco)
install(TARGETS clice RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

message(STATUS "Copying resource directory for development build")
file(
COPY "${LLVM_INSTALL_PATH}/lib/clang"
DESTINATION "${PROJECT_BINARY_DIR}/lib"
add_custom_target(copy_clang_resource ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${LLVM_INSTALL_PATH}/lib/clang"
"${PROJECT_BINARY_DIR}/lib/clang"
COMMENT "Copying clang resource directory"
)
install(
DIRECTORY "${LLVM_INSTALL_PATH}/lib/clang"
Expand Down Expand Up @@ -234,10 +232,87 @@ if(CLICE_ENABLE_TEST)
target_link_libraries(unit_tests PRIVATE clice::core eventide::zest eventide::deco)
endif()

add_executable(scan_benchmark
"${PROJECT_SOURCE_DIR}/benchmarks/scan_benchmark.cpp"
)
target_include_directories(scan_benchmark PRIVATE
"${PROJECT_SOURCE_DIR}/src"
)
target_link_libraries(scan_benchmark PRIVATE clice::core eventide::deco)
if(CLICE_ENABLE_BENCHMARK)
add_executable(scan_benchmark
"${PROJECT_SOURCE_DIR}/benchmarks/scan_benchmark.cpp"
)
target_include_directories(scan_benchmark PRIVATE
"${PROJECT_SOURCE_DIR}/src"
)
target_link_libraries(scan_benchmark PRIVATE clice::core eventide::deco)
endif()

if(CLICE_RELEASE)
set(CLICE_PACK_DIR "${PROJECT_BINARY_DIR}/pack")
set(CLICE_SYMBOL_DIR "${PROJECT_BINARY_DIR}/pack-symbol")

if(WIN32)
set(CLICE_ARCHIVE_EXT ".zip")
else()
set(CLICE_ARCHIVE_EXT ".tar.gz")
endif()

if(WIN32)
set(CLICE_EXE_NAME "clice.exe")
set(CLICE_SYMBOL_NAME "clice.pdb")
elseif(APPLE)
set(CLICE_EXE_NAME "clice")
set(CLICE_SYMBOL_NAME "clice.dSYM")
else()
set(CLICE_EXE_NAME "clice")
set(CLICE_SYMBOL_NAME "clice.debug")
endif()

if(WIN32)
add_custom_target(clice-strip ALL
COMMAND ${CMAKE_COMMAND} -E make_directory "${CLICE_SYMBOL_DIR}"
DEPENDS clice
COMMENT "Collecting PDB for clice"
)
elseif(APPLE)
add_custom_target(clice-strip ALL
COMMAND ${CMAKE_COMMAND} -E make_directory "${CLICE_SYMBOL_DIR}"
COMMAND dsymutil "$<TARGET_FILE:clice>" -o "${CLICE_SYMBOL_DIR}/${CLICE_SYMBOL_NAME}"
COMMAND strip -x "$<TARGET_FILE:clice>"
DEPENDS clice
COMMENT "Extracting dSYM and stripping clice"
)
else()
add_custom_target(clice-strip ALL
COMMAND ${CMAKE_COMMAND} -E make_directory "${CLICE_SYMBOL_DIR}"
COMMAND ${CMAKE_OBJCOPY} --only-keep-debug "$<TARGET_FILE:clice>" "${CLICE_SYMBOL_DIR}/${CLICE_SYMBOL_NAME}"
COMMAND ${CMAKE_STRIP} --strip-debug --strip-unneeded "$<TARGET_FILE:clice>"
COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink="${CLICE_SYMBOL_DIR}/${CLICE_SYMBOL_NAME}" "$<TARGET_FILE:clice>"
DEPENDS clice
COMMENT "Extracting debug symbols and stripping clice"
)
endif()

add_custom_target(clice-pack ALL
DEPENDS clice-strip copy_clang_resource
COMMAND ${CMAKE_COMMAND} -E rm -rf "${CLICE_PACK_DIR}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${CLICE_PACK_DIR}/clice/bin"
COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:clice>" "${CLICE_PACK_DIR}/clice/bin/"
COMMAND ${CMAKE_COMMAND} -E copy_directory "${LLVM_INSTALL_PATH}/lib/clang" "${CLICE_PACK_DIR}/clice/lib/clang"
COMMAND ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/docs/clice.toml" "${CLICE_PACK_DIR}/clice/"
COMMAND ${CMAKE_COMMAND}
-DARCHIVE_DIR="${CLICE_PACK_DIR}/clice"
-DOUTPUT="${PROJECT_BINARY_DIR}/clice${CLICE_ARCHIVE_EXT}"
-DWORK_DIR="${CLICE_PACK_DIR}"
-P "${PROJECT_SOURCE_DIR}/cmake/archive.cmake"
COMMENT "Packaging clice distribution"
)

add_custom_target(clice-pack-symbol ALL
DEPENDS clice-strip
COMMAND ${CMAKE_COMMAND} -E rm -rf "${CLICE_SYMBOL_DIR}/pack"
COMMAND ${CMAKE_COMMAND} -E make_directory "${CLICE_SYMBOL_DIR}/pack"
COMMAND ${CMAKE_COMMAND} -E copy "${CLICE_SYMBOL_DIR}/${CLICE_SYMBOL_NAME}" "${CLICE_SYMBOL_DIR}/pack/"
COMMAND ${CMAKE_COMMAND}
-DARCHIVE_DIR="${CLICE_SYMBOL_DIR}/pack"
-DOUTPUT="${PROJECT_BINARY_DIR}/clice-symbol${CLICE_ARCHIVE_EXT}"
-DWORK_DIR="${CLICE_SYMBOL_DIR}/pack"
-P "${PROJECT_SOURCE_DIR}/cmake/archive.cmake"
COMMENT "Packaging clice debug symbols"
)
endif()
17 changes: 17 additions & 0 deletions cmake/archive.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
if(OUTPUT MATCHES "\\.tar\\.gz$")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar czf "${OUTPUT}" .
WORKING_DIRECTORY "${WORK_DIR}"
COMMAND_ERROR_IS_FATAL ANY
)
elseif(OUTPUT MATCHES "\\.zip$")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar cf "${OUTPUT}" --format=zip .
WORKING_DIRECTORY "${WORK_DIR}"
COMMAND_ERROR_IS_FATAL ANY
)
else()
message(FATAL_ERROR "Unsupported archive format: ${OUTPUT}")
endif()
Comment thread
16bit-ykiko marked this conversation as resolved.

message(STATUS "Created: ${OUTPUT}")
51 changes: 32 additions & 19 deletions cmake/toolchain.cmake
Original file line number Diff line number Diff line change
@@ -1,36 +1,49 @@
cmake_minimum_required(VERSION 3.30)

set(CMAKE_C_COMPILER clang CACHE STRING "C compiler")
set(CMAKE_CXX_COMPILER clang++ CACHE STRING "C++ compiler")
set(AR_PROGRAM_NAME "llvm-ar")
set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "Executable linker flags")
set(CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "Shared library linker flags")
set(CMAKE_MODULE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "Module linker flags")
set(CMAKE_C_COMPILER clang CACHE STRING "")
set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")

if(WIN32)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL" CACHE STRING "MSVC runtime")
endif()

find_program(LLVM_AR_PATH ${AR_PROGRAM_NAME})
find_program(LLVM_AR_PATH "llvm-ar")
if(LLVM_AR_PATH)
set(CMAKE_AR "${LLVM_AR_PATH}" CACHE FILEPATH "Archiver")
set(CMAKE_C_COMPILER_AR "${LLVM_AR_PATH}" CACHE FILEPATH "C archiver")
set(CMAKE_CXX_COMPILER_AR "${LLVM_AR_PATH}" CACHE FILEPATH "C++ archiver")
set(CMAKE_AR "${LLVM_AR_PATH}" CACHE FILEPATH "")
set(CMAKE_C_COMPILER_AR "${LLVM_AR_PATH}" CACHE FILEPATH "")
set(CMAKE_CXX_COMPILER_AR "${LLVM_AR_PATH}" CACHE FILEPATH "")
endif()

find_program(LLVM_RANLIB_PATH "llvm-ranlib")
if(LLVM_RANLIB_PATH)
set(CMAKE_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "Ranlib")
set(CMAKE_C_COMPILER_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "C ranlib")
set(CMAKE_CXX_COMPILER_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "C++ ranlib")
set(CMAKE_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "")
set(CMAKE_C_COMPILER_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "")
set(CMAKE_CXX_COMPILER_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "")
endif()

find_program(LLVM_NM_PATH "llvm-nm")
if(LLVM_NM_PATH)
set(CMAKE_NM "${LLVM_NM_PATH}" CACHE FILEPATH "Symbol lister")
set(CMAKE_NM "${LLVM_NM_PATH}" CACHE FILEPATH "")
endif()

find_program(LLVM_RC_PATH "llvm-rc")
if(LLVM_RC_PATH)
set(CMAKE_RC_COMPILER "${LLVM_RC_PATH}" CACHE FILEPATH "Resource compiler")
set(CMAKE_RC_COMPILER "${LLVM_RC_PATH}" CACHE FILEPATH "")
endif()

if(WIN32)
find_program(SCCACHE_PATH "sccache")
if(SCCACHE_PATH)
set(CMAKE_C_COMPILER_LAUNCHER "${SCCACHE_PATH}" CACHE FILEPATH "")
set(CMAKE_CXX_COMPILER_LAUNCHER "${SCCACHE_PATH}" CACHE FILEPATH "")
endif()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL" CACHE STRING "")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld-link")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld-link")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld-link")
else()
find_program(CCACHE_PATH "ccache")
if(CCACHE_PATH)
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PATH}" CACHE FILEPATH "")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PATH}" CACHE FILEPATH "")
endif()
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld")
endif()
Loading
Loading