Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
8 changes: 4 additions & 4 deletions .github/workflows/cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ jobs:

test:
needs: formatting-check
name: "Test (${{ matrix.toolchain.os }}/${{ matrix.toolchain.compiler }}, ${{ matrix.build-type }})"
name: "Test (${{ matrix.toolchain.os }}/${{ matrix.toolchain.compiler-id }}, ${{ matrix.build-type }})"

strategy:
fail-fast: false
matrix:
toolchain:
- { os: Linux, compiler: GCC, runner-label: gcc-14 }
- { os: Linux, compiler: Clang, runner-label: clang-19 }
- { os: Linux, compiler-id: GCC, runner-label: gcc-14 }
- { os: Linux, compiler-id: Clang, runner-label: clang-19 }
build-type:
- Release
- Debug
Expand All @@ -42,7 +42,7 @@ jobs:
runs-on: [self-hosted, ubuntu, base, "${{ matrix.toolchain.runner-label }}"]

env:
CT_CMAKE_PRESET: "CI-${{ matrix.toolchain.compiler }}-${{ matrix.build-type }}"
CT_CMAKE_PRESET: "CI-${{ matrix.toolchain.compiler-id }}-${{ matrix.build-type }}"

defaults:
run:
Expand Down
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.21...3.31)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(SetupToolchain)
include(ConfigureTarget)
include(ConfigureVcpkg)
include(CompilerWarnings)

project(template LANGUAGES CXX)
Expand All @@ -12,6 +12,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

ct_configure_vcpkg()

# Setup a 'solution' target
file(GLOB SOLUTION_SRC CONFIGURE_DEPENDS src/*.cpp src/*.h)
add_library(solution ${SOLUTION_SRC})
Expand Down
20 changes: 8 additions & 12 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
"name": "Base",
"description": "General preset that applies to all configurations",
"hidden": true,
"binaryDir": "${sourceDir}/build/${presetName}"
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CT_TOOLCHAIN_TEMPLATE": "${sourceDir}/cmake/templates/toolchain.cmake.in",
"CT_TRIPLET_TEMPLATE": "${sourceDir}/cmake/templates/vcpkg-triplet.cmake.in"
}
},
{
"name": "Default-Release",
Expand Down Expand Up @@ -57,21 +61,15 @@
"name": "CI-Linux",
"description": "Base preset for CI builds on Linux",
"hidden": true,
"inherits": "Base",
"cacheVariables": {
"CT_TRIPLET_TEMPLATE": "${sourceDir}/cmake/vcpkg-triplet-templates/ct-x64-linux.cmake.in",
"CT_TOOLCHAIN_TEMPLATE": "${sourceDir}/cmake/toolchain-templates/ci.cmake.in"
}
"inherits": "Base"
},
{
"name": "CI-GCC",
"description": "Base preset for Linux/GCC CI builds",
"hidden": true,
"inherits": "CI-Linux",
"cacheVariables": {
"CT_C_EXE": "gcc-14",
"CT_CXX_EXE": "gcc-14",
"CT_COMPILER_ID": "GNU"
"CMAKE_CXX_COMPILER": "g++-14"
}
},
{
Expand All @@ -80,9 +78,7 @@
"hidden": true,
"inherits": "CI-Linux",
"cacheVariables": {
"CT_C_EXE": "clang-19",
"CT_CXX_EXE": "clang++-19",
"CT_COMPILER_ID": "Clang"
"CMAKE_CXX_COMPILER": "clang++-19"
}
},
{
Expand Down
26 changes: 10 additions & 16 deletions cmake/ConfigureCompiler.cmake
Original file line number Diff line number Diff line change
@@ -1,43 +1,34 @@
function(ct_set_compiler C_EXE CXX_EXE)
find_program(C_EXE_PATH "${C_EXE}")
find_program(CXX_EXE_PATH "${CXX_EXE}")

if(NOT C_EXE_PATH OR NOT CXX_EXE_PATH)
message(FATAL_ERROR "Could not find a requested compiler (C_EXE=${C_EXE}, CXX_EXE=${CXX_EXE})")
endif()

set(CMAKE_C_COMPILER "${C_EXE_PATH}")
set(CMAKE_CXX_COMPILER "${CXX_EXE_PATH}")
endfunction()

function(ct_configure_compiler COMPILER_ID HARDENED SANITIZED STABLE_ABI)
function(ct_configure_compiler COMPILER_ID HARDENED SANITIZED)
set(IS_GCC OFF)
set(IS_CLANG OFF)
set(IS_MSVC OFF)

if(COMPILER_ID STREQUAL "GNU")
set(IS_GCC ON)
elseif(COMPILER_ID MATCHES "Clang")
set(IS_CLANG ON)
elseif(COMPILER_ID MATCHES "MSVC")
set(IS_MSVC ON)
endif()

set(CT_COMPILER_FLAGS "")
set(CT_LINKER_FLAGS "")

if(IS_CLANG AND NOT STABLE_ABI)
if(IS_CLANG)
set(CT_COMPILER_FLAGS "${CT_COMPILER_FLAGS} -stdlib=libc++")
set(CT_LINKER_FLAGS "${CT_LINKER_FLAGS} -stdlib=libc++")
message(STATUS "Using libc++ as a standard library")
endif()

if(HARDENED AND NOT STABLE_ABI)
if(HARDENED)
if(IS_GCC)
set(CT_COMPILER_FLAGS "${CT_COMPILER_FLAGS} -D_GLIBCXX_DEBUG")
message(STATUS "Enabled debug mode for libstdc++")
elseif(IS_CLANG)
set(CT_COMPILER_FLAGS "${CT_COMPILER_FLAGS} -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG")
message(STATUS "Enabled hardening mode for libc++")
else()
message(WARNING "Hardening is not supported for CXX compiler: '${COMPILER_ID}'")
message(STATUS "Hardening is not supported for CXX compiler: '${COMPILER_ID}'")
endif()
endif()

Expand All @@ -52,6 +43,9 @@ function(ct_configure_compiler COMPILER_ID HARDENED SANITIZED STABLE_ABI)
"-fno-omit-frame-pointer"
)
message(STATUS "Enabled UBSan and ASan")
elseif(IS_MSVC)
set(CT_COMPILER_FLAGS "${CT_COMPILER_FLAGS} /fsanitize=address")
message(STATUS "Enabled ASan")
else()
message(WARNING "Sanitized builds are not supported for CXX compiler: '${COMPILER_ID}'")
endif()
Expand Down
7 changes: 1 addition & 6 deletions cmake/ConfigureTarget.cmake
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
function(ct_configure_target TARGET)
if(CT_COMPILER_FLAGS OR CT_LINKER_FLAGS)
message(STATUS "No need to configure '${TARGET}': Using global toolchain options")
return()
endif()

include(ConfigureCompiler)
ct_configure_compiler("${CMAKE_CXX_COMPILER_ID}" "${CT_HARDENED}" "${CT_SANITIZED}" ON)
ct_configure_compiler("${CMAKE_CXX_COMPILER_ID}" "${CT_HARDENED}" "${CT_SANITIZED}")

separate_arguments(CT_COMPILER_FLAGS)
separate_arguments(CT_LINKER_FLAGS)
Expand Down
94 changes: 94 additions & 0 deletions cmake/ConfigureVcpkg.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
include(FetchContent)

function(_ct_fetch_vcpkg)
if (DEFINED ENV{CT_VCPKG_ROOT_DIR})
message(STATUS "Detected CT_VCPKG_ROOT_DIR environment variable")
set(CT_VCPKG_ROOT_DIR "$ENV{CT_VCPKG_ROOT_DIR}" CACHE PATH "")
endif()

if(DEFINED CT_VCPKG_ROOT_DIR)
message(STATUS "Using vcpkg at ${CT_VCPKG_ROOT_DIR}")
else()
message(STATUS "Fetching vcpkg...")
FetchContent_Declare(
vcpkg
URL https://github.com/microsoft/vcpkg/archive/refs/tags/2025.02.14.tar.gz
)
FetchContent_MakeAvailable(vcpkg)

set(CT_VCPKG_ROOT_DIR "${vcpkg_SOURCE_DIR}" CACHE PATH "")
endif()

if(NOT DEFINED CT_VCPKG_TOOLCHAIN_FILE)
set(CT_VCPKG_TOOLCHAIN_FILE "${CT_VCPKG_ROOT_DIR}/scripts/buildsystems/vcpkg.cmake" CACHE FILEPATH "")
endif()
endfunction()

function(_ct_bootstrap_vcpkg)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(CT_VCPKG_EXECUTABLE "${CT_VCPKG_ROOT_DIR}/vcpkg.exe")
set(CT_VCPKG_BOOTSTRAP_SCRIPT "${CT_VCPKG_ROOT_DIR}/bootstrap-vcpkg.bat")
else()
set(CT_VCPKG_EXECUTABLE "${CT_VCPKG_ROOT_DIR}/vcpkg")
set(CT_VCPKG_BOOTSTRAP_SCRIPT "${CT_VCPKG_ROOT_DIR}/bootstrap-vcpkg.sh")
endif()

if(NOT EXISTS "${CT_VCPKG_EXECUTABLE}")
message(STATUS "Bootstrapping vcpkg before install")

set(CT_VCPKG_BOOTSTRAP_LOG "${CMAKE_BINARY_DIR}/vcpkg-bootstrap.log")
file(TO_NATIVE_PATH "${CT_VCPKG_BOOTSTRAP_LOG}" CT_NATIVE_VCPKG_BOOTSTRAP_LOG)
execute_process(
COMMAND "${CT_VCPKG_BOOTSTRAP_SCRIPT}" -disableMetrics
OUTPUT_FILE "${CT_VCPKG_BOOTSTRAP_LOG}"
ERROR_FILE "${CT_VCPKG_BOOTSTRAP_LOG}"
RESULT_VARIABLE CT_VCPKG_BOOTSTRAP_RESULT)

if(CT_VCPKG_BOOTSTRAP_RESULT EQUAL "0")
message(STATUS "Bootstrapping vcpkg before install - done")
else()
message(STATUS "Bootstrapping vcpkg before install - failed")
message(FATAL_ERROR "vcpkg install failed. See logs for more information: ${CT_NATIVE_VCPKG_BOOTSTRAP_LOG}")
endif()
endif()
endfunction()

option(CT_HARDENED "Should the standard library be hardened" OFF)
option(CT_SANITIZED "Should the build be sanitized" OFF)

function(_ct_generate_toolchain_and_triplet)
cmake_path(GET CT_TOOLCHAIN_TEMPLATE STEM CT_TOOLCHAIN_NAME)
set(CT_GENERATED_TOOLCHAIN_FILE "${CMAKE_BINARY_DIR}/gen/toolchains/${CT_TOOLCHAIN_NAME}.cmake")

configure_file("${CT_TOOLCHAIN_TEMPLATE}" "${CT_GENERATED_TOOLCHAIN_FILE}" @ONLY)
message(STATUS "Generated a toolchain '${CT_TOOLCHAIN_NAME}' from template")

if(DEFINED CT_TRIPLET_TEMPLATE)
message(STATUS "Running ${CT_VCPKG_ROOT_DIR}/vcpkg z-print-config")
execute_process(
COMMAND "${CT_VCPKG_ROOT_DIR}/vcpkg" z-print-config
COMMAND_ERROR_IS_FATAL ANY
OUTPUT_VARIABLE CT_VCPKG_CONFIG_OUTPUT
)
string(JSON CT_DEFAULT_TRIPLET_NAME GET "${CT_VCPKG_CONFIG_OUTPUT}" "default-triplet")
set(CT_DEFAULT_TRIPLET_FILE "${CT_VCPKG_ROOT_DIR}/triplets/${CT_DEFAULT_TRIPLET_NAME}.cmake")

cmake_path(GET CT_TRIPLET_TEMPLATE STEM CT_TRIPLET_TEMPLATE_NAME)
set(CT_GENERATED_TRIPLETS_DIR "${CMAKE_BINARY_DIR}/gen/vcpkg-triplets")
set(CT_GENERATED_TRIPLET_NAME "${CT_TRIPLET_TEMPLATE_NAME}-${CT_DEFAULT_TRIPLET_NAME}")
set(CT_GENERATED_TRIPLET_FILE "${CT_GENERATED_TRIPLETS_DIR}/${CT_GENERATED_TRIPLET_NAME}.cmake")

configure_file("${CT_TRIPLET_TEMPLATE}" "${CT_GENERATED_TRIPLET_FILE}" @ONLY)
message(STATUS "Generated a vcpkg triplet '${CT_GENERATED_TRIPLET_NAME}' from template")

set(VCPKG_TARGET_TRIPLET "${CT_GENERATED_TRIPLET_NAME}" CACHE STRING "")
set(VCPKG_OVERLAY_TRIPLETS "${CT_GENERATED_TRIPLETS_DIR}" CACHE PATH "")
endif()
endfunction()

macro(ct_configure_vcpkg)
_ct_fetch_vcpkg()
_ct_bootstrap_vcpkg()
_ct_generate_toolchain_and_triplet()
include("${CT_VCPKG_TOOLCHAIN_FILE}")
endmacro()
48 changes: 0 additions & 48 deletions cmake/FetchVcpkg.cmake

This file was deleted.

25 changes: 0 additions & 25 deletions cmake/GenerateToolchain.cmake

This file was deleted.

5 changes: 0 additions & 5 deletions cmake/SetupToolchain.cmake

This file was deleted.

11 changes: 11 additions & 0 deletions cmake/templates/toolchain.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
include("@CMAKE_SOURCE_DIR@/cmake/ConfigureCompiler.cmake")

ct_configure_compiler("@CMAKE_CXX_COMPILER_ID@" @CT_HARDENED@ @CT_SANITIZED@)

set(CMAKE_C_FLAGS_INIT "${CT_COMPILER_FLAGS}")
set(CMAKE_CXX_FLAGS_INIT "${CT_COMPILER_FLAGS}")

foreach(linker IN ITEMS "SHARED" "MODULE" "EXE")
set(CMAKE_${linker}_LINKER_FLAGS_INIT "${CT_LINKER_FLAGS}")
set(CMAKE_${linker}_LINKER_FLAGS "${CT_LINKER_FLAGS}")
endforeach()
3 changes: 3 additions & 0 deletions cmake/templates/vcpkg-triplet.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include("@CT_DEFAULT_TRIPLET_FILE@")

set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "@CT_GENERATED_TOOLCHAIN_FILE@")
12 changes: 0 additions & 12 deletions cmake/toolchain-templates/ci.cmake.in

This file was deleted.

7 changes: 0 additions & 7 deletions cmake/vcpkg-triplet-templates/ct-x64-linux.cmake.in

This file was deleted.