diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c8219fe..d2cd7fbb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,9 +74,70 @@ jobs: exit 1 \ ) + checks: + runs-on: ${{ matrix.prests.os.name }} + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + presets: + - {os: {name: ubuntu-latest, type: linux}, compiler: {name: gcc, type: gcc}} + - {os: {name: ubuntu-latest, type: linux}, compiler: {name: llvm, type: clang}} + - {os: {name: macos-latest, type: osx}, compiler: {name: gcc, type: gcc}} + - {os: {name: macos-latest, type: osx}, compiler: {name: llvm, type: clang}} + - {os: {name: windows-latest, type: windows}, compiler: {name: msvc, type: msvc}} + arch: + - {name: x64, type: x64} + vcpkg: + - true + - false + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: aminya/setup-cpp@v1 + with: + compiler: ${{ matrix.presets.compiler.name }} + vcvarsall: ${{ contains(matrix.presets.os.type, 'windows' )}} + cmake: true + ninja: true + vcpkg: ${{ matrix.vcpkg }} + ccache: true + doxygen: true + graphviz: true + python: true + gcovr: true + opencppcoverage: true + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install -r docs/requirements.txt + + - name: Configure CMake + run: | + cmake -S . --preset=${{ matrix.arch.type }}-${{ matrix.presets.os.type }}-${{ matrix.presets.compiler.type }} -DCMAKE_BUILD_TYPE=Debug -DCODE_COVERAGE=ON -DBUILD_TESTING=ON + + - name: Coverage + run: | + cmake --build out/build/${{ matrix.arch.type }}-${{ matrix.presets.os.type }}-${{ matrix.presets.compiler.type }} --target ccov-all + + - name: Upload coverage report + uses: codecov/codecov-action@v4.1.0 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: out/build/${{ matrix.arch.type }}-${{ matrix.presets.os.type }}-${{ matrix.presets.compiler.type }}/code_coverage/coverage.xml + flags: ${{ matrix.arch.type }}-${{ matrix.presets.os.type }}-${{ matrix.presets.compiler.type }} + name: ${{ matrix.arch.type }}-${{ matrix.presets.os.type }}-${{ matrix.presets.compiler.type }}-coverage + pass: if: always() - needs: [pre-commit, consistency] + needs: [pre-commit, consistency, checks] runs-on: ubuntu-latest timeout-minutes: 2 steps: diff --git a/CMakeLists.txt b/CMakeLists.txt index b0a0aba3..2b7be046 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,24 +1,6 @@ cmake_minimum_required(VERSION 3.20) message(STATUS "CMAKE VERSION:${CMAKE_VERSION}") -# Vcpkg build environment -if(DEFINED ENV{VCPKG_ROOT}) - message(STATUS "VCPKG_ROOT:$ENV{VCPKG_ROOT}") - set(VCPKG_ROOT "$ENV{VCPKG_ROOT}") -else() - message( - FATAL_ERROR "Missing VCPKG_ROOT, please check the existence of VCPKG_ROOT") -endif() - -# set cmake tool chain -file(TO_CMAKE_PATH ${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake - vcpkg_toolchain_file) -set(CMAKE_TOOLCHAIN_FILE ${vcpkg_toolchain_file}) - -set(VCPKG_VERBOSE - ON - CACHE BOOL "Vcpkg VCPKG_VERBOSE") - # Project settings project( ss-cpp diff --git a/CMakePresets.json b/CMakePresets.json index f646b2de..92726f2c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -1,216 +1,15 @@ { "version": 6, - "configurePresets": [ - { - "name": "default", - "displayName": "Basic Config", - "description": "Basic build using Ninja generator", - "generator": "Ninja", - "hidden": true, - "binaryDir": "${sourceDir}/out/build/${presetName}", - "installDir": "${sourceDir}/out/install/${presetName}", - "cacheVariables": { - "CMAKE_VERBOSE_MAKEFILE": "FALSE" - } - }, - { - "name": "x64", - "architecture": { - "value": "x64", - "strategy": "external" - }, - "hidden": true - }, - { - "name": "x86", - "architecture": { - "value": "x86", - "strategy": "external" - }, - "hidden": true - }, - { - "name": "Debug", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug" - }, - "hidden": true - }, - { - "name": "Release", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithDebInfo" - }, - "hidden": true - }, - { - "name": "MSVC", - "hidden": true, - "cacheVariables": { - "CMAKE_C_COMPILER": "cl", - "CMAKE_CXX_COMPILER": "cl" - }, - "toolset": { - "value": "host=x64", - "strategy": "external" - }, - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Windows" - } - }, - { - "name": "Clang", - "hidden": true, - "cacheVariables": { - "CMAKE_C_COMPILER": "clang", - "CMAKE_CXX_COMPILER": "clang++" - }, - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Linux" - }, - "toolset": { - "value": "host=x64", - "strategy": "external" - } - }, - { - "name": "ClangCL", - "hidden": true, - "cacheVariables": { - "CMAKE_C_COMPILER": "clang-cl", - "CMAKE_CXX_COMPILER": "clang-cl" - }, - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Windows" - }, - "toolset": { - "value": "host=x64", - "strategy": "external" - } - }, - { - "name": "GNUC", - "hidden": true, - "cacheVariables": { - "CMAKE_C_COMPILER": "gcc", - "CMAKE_CXX_COMPILER": "g++" - }, - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Linux" - }, - "toolset": { - "value": "host=x64", - "strategy": "external" - } - }, - { - "name": "x64-Debug-MSVC", - "description": "MSVC for x64 (Debug)", - "inherits": [ - "default", - "x64", - "Debug", - "MSVC" - ] - }, - { - "name": "x64-Release-MSVC", - "description": "MSVC for x64 (Release)", - "inherits": [ - "default", - "x64", - "Release", - "MSVC" - ] - }, - { - "name": "x64-Debug-Clang", - "description": "Clang/LLVM for x64 (Debug)", - "inherits": [ - "default", - "x64", - "Debug", - "Clang" - ] - }, - { - "name": "x64-Release-Clang", - "description": "Clang/LLVM for x64 (Release)", - "inherits": [ - "default", - "x64", - "Release", - "Clang" - ] - }, - { - "name": "x64-Debug-ClangCL", - "description": "Clang/LLVM for x64 (Debug)", - "inherits": [ - "default", - "x64", - "Debug", - "ClangCL" - ] - }, - { - "name": "x64-Release-ClangCL", - "description": "ClangCL/LLVM for x64 (Release)", - "inherits": [ - "default", - "x64", - "Release", - "ClangCL" - ] - }, - { - "name": "x64-Debug-GNUC", - "description": "GNUC for x64 (Debug)", - "inherits": [ - "default", - "x64", - "Debug", - "GNUC" - ] - }, - { - "name": "x64-Release-GNUC", - "description": "GNUC for x64 (Release)", - "inherits": [ - "default", - "x64", - "Release", - "GNUC" - ] - } - ], - "buildPresets": [ - { - "name": "default", - "configurePreset": "default" - } - ], - "testPresets": [ - { - "name": "default", - "configurePreset": "default", - "output": { - "outputOnFailure": true - }, - "execution": { - "noTestsAction": "error", - "stopOnFailure": true, - "timeout": 180, - "jobs": 8 - } - } + "cmakeMinimumRequired": { + "major": 3, + "minor": 25, + "patch": 0 + }, + "include": [ + "cmake/presets/x64-windows-msvc.json", + "cmake/presets/x64-linux-clang.json", + "cmake/presets/x64-linux-gcc.json", + "cmake/presets/x64-osx-clang.json", + "cmake/presets/x64-osx-gcc.json" ] } diff --git a/cmake/presets/base.json b/cmake/presets/base.json new file mode 100644 index 00000000..004f2d9d --- /dev/null +++ b/cmake/presets/base.json @@ -0,0 +1,46 @@ +{ + "version": 6, + "include": [ + "generators/ninja.json", + "toolchains/vcpkg.json" + ], + "configurePresets": [ + { + "name": "base", + "hidden": true, + "inherits": [ + "ninja-multi-config", + "vcpkg" + ], + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "CMAKE_EXPORT_COMPILE_COMMANDS": true, + "CMAKE_COMPILE_WARNING_AS_ERROR": true, + "CMAKE_VERBOSE_MAKEFILE": "FALSE" + } + } + ], + "buildPresets": [ + { + "name": "base", + "hidden": true, + "inherits": "ninja-multi-config", + "configurePreset": "base" + } + ], + "testPresets": [ + { + "name": "base", + "hidden": true, + "inherits": "ninja-multi-config", + "configurePreset": "base", + "output": { + "outputOnFailure": true + }, + "execution": { + "noTestsAction": "error", + "stopOnFailure": true + } + } + ] +} diff --git a/cmake/presets/compilers/clang.json b/cmake/presets/compilers/clang.json new file mode 100644 index 00000000..a1398178 --- /dev/null +++ b/cmake/presets/compilers/clang.json @@ -0,0 +1,13 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "clang", + "hidden": true, + "cacheVariables": { + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++" + } + } + ] +} diff --git a/cmake/presets/compilers/gcc.json b/cmake/presets/compilers/gcc.json new file mode 100644 index 00000000..d920fb4c --- /dev/null +++ b/cmake/presets/compilers/gcc.json @@ -0,0 +1,13 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "gcc", + "hidden": true, + "cacheVariables": { + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "g++" + } + } + ] +} diff --git a/cmake/presets/compilers/msvc.json b/cmake/presets/compilers/msvc.json new file mode 100644 index 00000000..712dce12 --- /dev/null +++ b/cmake/presets/compilers/msvc.json @@ -0,0 +1,18 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "msvc", + "hidden": true, + "cacheVariables": { + "CMAKE_C_COMPILER": "cl", + "CMAKE_CXX_COMPILER": "cl" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + } + ] +} diff --git a/cmake/presets/generators/ninja.json b/cmake/presets/generators/ninja.json new file mode 100644 index 00000000..907ec805 --- /dev/null +++ b/cmake/presets/generators/ninja.json @@ -0,0 +1,40 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "ninja", + "hidden": true, + "generator": "Ninja" + }, + { + "name": "ninja-multi-config", + "hidden": true, + "generator": "Ninja Multi-Config" + } + ], + "buildPresets": [ + { + "name": "ninja", + "hidden": true + }, + { + "name": "ninja-multi-config", + "hidden": true, + "configurePreset": "ninja-multi-config", + "configuration": "Debug" + } + ], + "testPresets": [ + { + "name": "ninja", + "hidden": true, + "configurePreset": "ninja" + }, + { + "name": "ninja-multi-config", + "hidden": true, + "configurePreset": "ninja-multi-config", + "configuration": "Debug" + } + ] +} diff --git a/cmake/presets/os/darwin.json b/cmake/presets/os/darwin.json new file mode 100644 index 00000000..e3f3fbe9 --- /dev/null +++ b/cmake/presets/os/darwin.json @@ -0,0 +1,28 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "darwin", + "hidden": true, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Darwin" + } + } + ], + "buildPresets": [ + { + "name": "darwin", + "hidden": true, + "configurePreset": "darwin" + } + ], + "testPresets": [ + { + "name": "darwin", + "hidden": true, + "configurePreset": "darwin" + } + ] +} diff --git a/cmake/presets/os/linux.json b/cmake/presets/os/linux.json new file mode 100644 index 00000000..684e0786 --- /dev/null +++ b/cmake/presets/os/linux.json @@ -0,0 +1,28 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "linux", + "hidden": true, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + } + } + ], + "buildPresets": [ + { + "name": "linux", + "hidden": true, + "configurePreset": "linux" + } + ], + "testPresets": [ + { + "name": "linux", + "hidden": true, + "configurePreset": "linux" + } + ] +} diff --git a/cmake/presets/os/windows.json b/cmake/presets/os/windows.json new file mode 100644 index 00000000..9f78bad8 --- /dev/null +++ b/cmake/presets/os/windows.json @@ -0,0 +1,28 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "windows", + "hidden": true, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + } + ], + "buildPresets": [ + { + "name": "windows", + "hidden": true, + "configurePreset": "windows" + } + ], + "testPresets": [ + { + "name": "windows", + "hidden": true, + "configurePreset": "windows" + } + ] +} diff --git a/cmake/presets/toolchains/vcpkg.json b/cmake/presets/toolchains/vcpkg.json new file mode 100644 index 00000000..8536b5f9 --- /dev/null +++ b/cmake/presets/toolchains/vcpkg.json @@ -0,0 +1,15 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "vcpkg", + "hidden": true, + "toolchainFile": "${sourceDir}/cmake/vcpkg/vcpkg.toolchain.cmake", + "cacheVariables": { + "VCPKG_INSTALL_OPTIONS": "--no-print-usage", + "VCPKG_OVERLAY_TRIPLETS": "${sourceDir}/cmake/vcpkg/triplets", + "VCPKG_OVERLAY_PORTS": "${sourceDir}/cmake/vcpkg/ports" + } + } + ] +} diff --git a/cmake/presets/triplets/x64-linux.json b/cmake/presets/triplets/x64-linux.json new file mode 100644 index 00000000..79c0d428 --- /dev/null +++ b/cmake/presets/triplets/x64-linux.json @@ -0,0 +1,12 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "x64-linux", + "hidden": true, + "cacheVariables": { + "VCPKG_TARGET_TRIPLET": "x64-linux" + } + } + ] +} diff --git a/cmake/presets/triplets/x64-osx.json b/cmake/presets/triplets/x64-osx.json new file mode 100644 index 00000000..de54599b --- /dev/null +++ b/cmake/presets/triplets/x64-osx.json @@ -0,0 +1,12 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "x64-osx", + "hidden": true, + "cacheVariables": { + "VCPKG_TARGET_TRIPLET": "x64-osx" + } + } + ] +} diff --git a/cmake/presets/triplets/x64-windows.json b/cmake/presets/triplets/x64-windows.json new file mode 100644 index 00000000..9f8edc0b --- /dev/null +++ b/cmake/presets/triplets/x64-windows.json @@ -0,0 +1,12 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "x64-windows", + "hidden": true, + "cacheVariables": { + "VCPKG_TARGET_TRIPLET": "x64-windows" + } + } + ] +} diff --git a/cmake/presets/x64-linux-clang.json b/cmake/presets/x64-linux-clang.json new file mode 100644 index 00000000..4ab4155a --- /dev/null +++ b/cmake/presets/x64-linux-clang.json @@ -0,0 +1,51 @@ +{ + "version": 6, + "include": [ + "base.json", + "compilers/clang.json", + "triplets/x64-linux.json" + ], + "configurePresets": [ + { + "name": "x64-linux-clang", + "inherits": [ + "base", + "clang", + "x64-linux" + ] + } + ], + "buildPresets": [ + { + "name": "x64-linux-clang", + "inherits": "base", + "configurePreset": "x64-linux-clang" + } + ], + "testPresets": [ + { + "name": "x64-linux-clang", + "inherits": "base", + "configurePreset": "x64-linux-clang" + } + ], + "workflowPresets": [ + { + "name": "x64-linux-clang", + "steps": [ + { + "type": "configure", + "name": "x64-linux-clang" + }, + { + "type": "build", + "name": "x64-linux-clang" + }, + { + "type": "test", + "name": "x64-linux-clang" + } + ] + } + ] +} diff --git a/cmake/presets/x64-linux-gcc.json b/cmake/presets/x64-linux-gcc.json new file mode 100644 index 00000000..3fad2305 --- /dev/null +++ b/cmake/presets/x64-linux-gcc.json @@ -0,0 +1,51 @@ +{ + "version": 6, + "include": [ + "base.json", + "compilers/gcc.json", + "triplets/x64-linux.json" + ], + "configurePresets": [ + { + "name": "x64-linux-gcc", + "inherits": [ + "base", + "gcc", + "x64-linux" + ] + } + ], + "buildPresets": [ + { + "name": "x64-linux-gcc", + "inherits": "base", + "configurePreset": "x64-linux-gcc" + } + ], + "testPresets": [ + { + "name": "x64-linux-gcc", + "inherits": "base", + "configurePreset": "x64-linux-gcc" + } + ], + "workflowPresets": [ + { + "name": "x64-linux-gcc", + "steps": [ + { + "type": "configure", + "name": "x64-linux-gcc" + }, + { + "type": "build", + "name": "x64-linux-gcc" + }, + { + "type": "test", + "name": "x64-linux-gcc" + } + ] + } + ] +} diff --git a/cmake/presets/x64-osx-clang.json b/cmake/presets/x64-osx-clang.json new file mode 100644 index 00000000..da0298db --- /dev/null +++ b/cmake/presets/x64-osx-clang.json @@ -0,0 +1,51 @@ +{ + "version": 6, + "include": [ + "base.json", + "compilers/clang.json", + "triplets/x64-osx.json" + ], + "configurePresets": [ + { + "name": "x64-osx-clang", + "inherits": [ + "base", + "clang", + "x64-osx" + ] + } + ], + "buildPresets": [ + { + "name": "x64-osx-clang", + "inherits": "base", + "configurePreset": "x64-osx-clang" + } + ], + "testPresets": [ + { + "name": "x64-osx-clang", + "inherits": "base", + "configurePreset": "x64-osx-clang" + } + ], + "workflowPresets": [ + { + "name": "x64-osx-clang", + "steps": [ + { + "type": "configure", + "name": "x64-osx-clang" + }, + { + "type": "build", + "name": "x64-osx-clang" + }, + { + "type": "test", + "name": "x64-osx-clang" + } + ] + } + ] +} diff --git a/cmake/presets/x64-osx-gcc.json b/cmake/presets/x64-osx-gcc.json new file mode 100644 index 00000000..c2688bef --- /dev/null +++ b/cmake/presets/x64-osx-gcc.json @@ -0,0 +1,51 @@ +{ + "version": 6, + "include": [ + "base.json", + "compilers/gcc.json", + "triplets/x64-osx.json" + ], + "configurePresets": [ + { + "name": "x64-osx-gcc", + "inherits": [ + "base", + "gcc", + "x64-osx" + ] + } + ], + "buildPresets": [ + { + "name": "x64-osx-gcc", + "inherits": "base", + "configurePreset": "x64-osx-gcc" + } + ], + "testPresets": [ + { + "name": "x64-osx-gcc", + "inherits": "base", + "configurePreset": "x64-osx-gcc" + } + ], + "workflowPresets": [ + { + "name": "x64-osx-gcc", + "steps": [ + { + "type": "configure", + "name": "x64-osx-gcc" + }, + { + "type": "build", + "name": "x64-osx-gcc" + }, + { + "type": "test", + "name": "x64-osx-gcc" + } + ] + } + ] +} diff --git a/cmake/presets/x64-windows-msvc.json b/cmake/presets/x64-windows-msvc.json new file mode 100644 index 00000000..22f0d7b0 --- /dev/null +++ b/cmake/presets/x64-windows-msvc.json @@ -0,0 +1,51 @@ +{ + "version": 6, + "include": [ + "base.json", + "os/windows.json", + "compilers/msvc.json" + ], + "configurePresets": [ + { + "name": "x64-windows-msvc", + "inherits": [ + "base", + "windows", + "msvc" + ] + } + ], + "buildPresets": [ + { + "name": "x64-windows-msvc", + "inherits": "base", + "configurePreset": "x64-windows-msvc" + } + ], + "testPresets": [ + { + "name": "x64-windows-msvc", + "inherits": "base", + "configurePreset": "x64-windows-msvc" + } + ], + "workflowPresets": [ + { + "name": "x64-windows-msvc", + "steps": [ + { + "type": "configure", + "name": "x64-windows-msvc" + }, + { + "type": "build", + "name": "x64-windows-msvc" + }, + { + "type": "test", + "name": "x64-windows-msvc" + } + ] + } + ] +} diff --git a/cmake/vcpkg/bootstrap/vcpkg-config.cmake b/cmake/vcpkg/bootstrap/vcpkg-config.cmake new file mode 100644 index 00000000..b788223c --- /dev/null +++ b/cmake/vcpkg/bootstrap/vcpkg-config.cmake @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: Copyright 2023 Mikhail Svetkin +# SPDX-License-Identifier: MIT + +include_guard(GLOBAL) + +# CMAKE_HOST_* variables are not available during first configure on windows. +cmake_host_system_information(RESULT __vcpkg_bootstrap_host QUERY OS_NAME) +cmake_host_system_information(RESULT __vcpkg_bootstrap_arch QUERY OS_PLATFORM) + +set(__vcpkg_bootstrap_list_dir "${CMAKE_CURRENT_LIST_DIR}") + +include(${__vcpkg_bootstrap_list_dir}/vcpkg_skip_install_on_reconfigure.cmake) +include(${__vcpkg_bootstrap_list_dir}/vcpkg_bootstrap.cmake) +include(${__vcpkg_bootstrap_list_dir}/vcpkg_configure.cmake) diff --git a/cmake/vcpkg/bootstrap/vcpkg_bootstrap.cmake b/cmake/vcpkg/bootstrap/vcpkg_bootstrap.cmake new file mode 100644 index 00000000..e285663a --- /dev/null +++ b/cmake/vcpkg/bootstrap/vcpkg_bootstrap.cmake @@ -0,0 +1,172 @@ +# SPDX-FileCopyrightText: Copyright 2023 Mikhail Svetkin +# SPDX-License-Identifier: MIT + +# stash all local changes +function(_vcpkg_stash vcpkg_root) + message(STATUS "vcpkg stash all local changes") + + execute_process( + COMMAND ${GIT_EXECUTABLE} stash + WORKING_DIRECTORY ${vcpkg_root} + RESULT_VARIABLE result) + + if(NOT result EQUAL "0") + message(FATAL_ERROR "${GIT_EXECUTABLE} stash failed with ${result}") + endif() +endfunction() + +# checkout to a specific baseline +function(_vcpkg_checkout vcpkg_root vcpkg_ref) + message(STATUS "vcpkg checkout to ${vcpkg_ref}") + + execute_process( + COMMAND ${GIT_EXECUTABLE} checkout ${vcpkg_ref} + WORKING_DIRECTORY ${vcpkg_root} + RESULT_VARIABLE result) + + if(NOT result EQUAL "0") + message( + FATAL_ERROR + "${GIT_EXECUTABLE} checkout ${vcpkg_ref} failed with ${result}") + endif() +endfunction() # clone +function(_vcpkg_clone vcpkg_root vcpkg_repo vcpkg_ref) + execute_process( + COMMAND ${GIT_EXECUTABLE} clone ${vcpkg_repo} ${vcpkg_root} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + RESULT_VARIABLE result) + + if(NOT result EQUAL "0") + message(FATAL_ERROR "failed to clone ${vcpkg_repo} to ${vcpkg_root}") + endif() + + file(LOCK "${vcpkg_root}" DIRECTORY) + _vcpkg_checkout(${vcpkg_root} ${vcpkg_ref}) +endfunction() + +# bootstrap +function(_vcpkg_tool_bootstrap vcpkg_root) + message(STATUS "Bootstrap vckpg tool") + + if("${__vcpkg_bootstrap_host}" STREQUAL "Windows") + set(bootstrap_cmd "${vcpkg_root}/bootstrap-vcpkg.bat") + else() + set(bootstrap_cmd "${vcpkg_root}/bootstrap-vcpkg.sh") + endif() + + execute_process( + COMMAND ${bootstrap_cmd} -disableMetrics + WORKING_DIRECTORY ${vcpkg_root} + RESULT_VARIABLE result) + + if(NOT result EQUAL "0") + message(FATAL_ERROR "${bootstrap_cmd} failed with ${result}") + endif() +endfunction() + +# upgrade +function(_vcpkg_upgrade vcpkg_root vcpkg_repo vcpkg_ref) + file(LOCK "${vcpkg_root}" DIRECTORY) + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + WORKING_DIRECTORY ${vcpkg_root} + OUTPUT_VARIABLE current_git_hash + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE result) + + if(NOT result EQUAL "0") + message( + FATAL_ERROR "${GIT_EXECUTABLE} rev-parse HEAD failed with ${result}") + endif() + + if("${current_git_hash}" STREQUAL "${vcpkg_ref}") + return() + endif() + + message(STATUS "Upgrade vcpkg") + message(STATUS "vcpkg current commit: ${current_git_hash}") + message(STATUS "vcpkg release: ${vcpkg_ref}") + + execute_process( + COMMAND ${GIT_EXECUTABLE} remote set-url origin ${vcpkg_repo} + WORKING_DIRECTORY ${vcpkg_root} + RESULT_VARIABLE result) + + if(NOT result EQUAL "0") + message(FATAL_ERROR "failed to change origin to ${vcpkg_repo}") + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} fetch + WORKING_DIRECTORY ${vcpkg_root} + RESULT_VARIABLE result) + + if(NOT result EQUAL "0") + message(FATAL_ERROR "${GIT_EXECUTABLE} fetch failed with ${result}") + endif() + + _vcpkg_stash(${vcpkg_root}) + _vcpkg_checkout(${vcpkg_root} ${vcpkg_ref}) + _vcpkg_tool_bootstrap(${vcpkg_root}) +endfunction() + +# find root +function(_vcpkg_find_root cache_dir_name out_vcpkg_root) + if(DEFINED ENV{VCPKG_INSTALLATION_ROOT}) + set(root "$ENV{VCPKG_INSTALLATION_ROOT}") + elseif("${__vcpkg_bootstrap_host}" STREQUAL "Windows") + set(root "$ENV{LOCALAPPDATA}/vcpkg/projects/${cache_dir_name}/cache") + else() + set(root "$ENV{HOME}/.cache/vcpkg/projects/${cache_dir_name}") + endif() + + set(${out_vcpkg_root} + ${root} + PARENT_SCOPE) +endfunction() + +# set vcpkg_root/toolchain_file cache variables +function(_vcpkg_set_cache_variables vcpkg_root) + set(_VCPKG_ROOT + "${vcpkg_root}" + CACHE INTERNAL "vcpkg root") + + set(_VCPKG_TOOLCHAIN_FILE + "${vcpkg_root}/scripts/buildsystems/vcpkg.cmake" + CACHE INTERNAL "vcpkg toolchain file") +endfunction() + +# bootstrap +function(_vcpkg_bootstrap) + cmake_parse_arguments(PARSE_ARGV 0 "arg" "" "CACHE_DIR_NAME;REPO;REF" "") + + if(DEFINED arg_UNPARSED_ARGUMENTS) + message( + FATAL_ERROR "internal error: ${CMAKE_CURRENT_FUNCTION} passed extra args:" + "${arg_UNPARSED_ARGUMENTS}") + endif() + + find_package(Git QUIET REQUIRED) + + if(DEFINED CACHE{_VCPKG_ROOT}) + set(vcpkg_root $CACHE{_VCPKG_ROOT}) + else() + _vcpkg_find_root("${arg_CACHE_DIR_NAME}" vcpkg_root) + endif() + + if(NOT EXISTS ${vcpkg_root}) + message(STATUS "Setup vcpkg") + _vcpkg_clone(${vcpkg_root} ${arg_REPO} ${arg_REF}) + _vcpkg_tool_bootstrap(${vcpkg_root}) + else() + message(STATUS "Found vcpkg in: ${vcpkg_root}") + _vcpkg_upgrade(${vcpkg_root} ${arg_REPO} ${arg_REF}) + endif() + + if(DEFINED CACHE{_VCPKG_TOOLCHAIN_FILE}) + return() + endif() + + _vcpkg_set_cache_variables("${vcpkg_root}") +endfunction() diff --git a/cmake/vcpkg/bootstrap/vcpkg_configure.cmake b/cmake/vcpkg/bootstrap/vcpkg_configure.cmake new file mode 100644 index 00000000..2da4b844 --- /dev/null +++ b/cmake/vcpkg/bootstrap/vcpkg_configure.cmake @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: Copyright 2023 Mikhail Svetkin +# SPDX-License-Identifier: MIT + +# bootstrap and configure vcpkg +function(vcpkg_configure) + _vcpkg_bootstrap(${ARGN}) + _vcpkg_skip_install_on_reconfigure() +endfunction() diff --git a/cmake/vcpkg/bootstrap/vcpkg_skip_install_on_reconfigure.cmake b/cmake/vcpkg/bootstrap/vcpkg_skip_install_on_reconfigure.cmake new file mode 100644 index 00000000..3e31381b --- /dev/null +++ b/cmake/vcpkg/bootstrap/vcpkg_skip_install_on_reconfigure.cmake @@ -0,0 +1,46 @@ +# SPDX-FileCopyrightText: Copyright 2024 Mikhail Svetkin +# SPDX-License-Identifier: MIT + +function(_vcpkg_update_manifest_hash) + set(_VCPKG_MANIFEST_HASH + "$CACHE{__VCPKG_MANIFEST_HASH}" + CACHE INTERNAL "Hash of vcpkg manifest file") +endfunction() + +# disable vcpkg manifest install step on cmake reconfigure if vcpkg.json has not +# changed. +function(_vcpkg_skip_install_on_reconfigure) + if(DEFINED CACHE{VCPKG_MANIFEST_DIR}) + set(vcpkg_manifest_file "$CACHE{VCPKG_MANIFEST_DIR}/vcpkg.json") + else() + set(vcpkg_manifest_file "${CMAKE_SOURCE_DIR}/vcpkg.json") + endif() + + file(SHA512 "${vcpkg_manifest_file}" vcpkg_manifest_hash) + + if(DEFINED CACHE{_VCPKG_MANIFEST_HASH} AND _VCPKG_MANIFEST_HASH STREQUAL + vcpkg_manifest_hash) + set(VCPKG_MANIFEST_INSTALL + OFF + CACHE INTERNAL "") + set_property( + DIRECTORY + APPEND + PROPERTY CMAKE_CONFIGURE_DEPENDS "${vcpkg_manifest_file}") + else() + set(VCPKG_MANIFEST_INSTALL + ON + CACHE INTERNAL "") + endif() + + # I was not able to propgate vcpkg_manifest_hash via defer call, so workaround + # it with another cache variable. + set(__VCPKG_MANIFEST_HASH + "${vcpkg_manifest_hash}" + CACHE INTERNAL "") + + # set actual hash only when vcpkg install command succeed. The only way you to + # detect to assume that configuration step succeed. + cmake_language(DEFER DIRECTORY ${CMAKE_SOURCE_DIR} CALL + _vcpkg_update_manifest_hash) +endfunction() diff --git a/cmake/vcpkg/ports/.placeholder b/cmake/vcpkg/ports/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/cmake/vcpkg/triplets/.placeholder b/cmake/vcpkg/triplets/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/cmake/vcpkg/vcpkg.toolchain.cmake b/cmake/vcpkg/vcpkg.toolchain.cmake new file mode 100644 index 00000000..59de932b --- /dev/null +++ b/cmake/vcpkg/vcpkg.toolchain.cmake @@ -0,0 +1,39 @@ +# SPDX-FileCopyrightText: Copyright 2023 Mikhail Svetkin +# SPDX-License-Identifier: MIT + +include_guard(GLOBAL) + +cmake_minimum_required(VERSION 3.25) + +get_property(IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) + +if(IN_TRY_COMPILE) + return() +endif() + +unset(IN_TRY_COMPILE) + +# Vcpkg build environment +if(DEFINED ENV{VCPKG_ROOT}) + set(VCPKG_ROOT "$ENV{VCPKG_ROOT}") + # set cmake tool chain + file(TO_CMAKE_PATH ${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake + vcpkg_toolchain_file) +else() + include(${CMAKE_CURRENT_LIST_DIR}/bootstrap/vcpkg-config.cmake) + + file(READ ${CMAKE_SOURCE_DIR}/vcpkg.json _vcpkg_json) + string(JSON _builtin_baseline GET ${_vcpkg_json} builtin-baseline) + + vcpkg_configure( + CACHE_DIR_NAME ss-cpp REPO https://github.com/microsoft/vcpkg.git REF + ${_builtin_baseline}) + set(vcpkg_toolchain_file $CACHE{_VCPKG_TOOLCHAIN_FILE}) +endif() + +set(VCPKG_VERBOSE + ON + CACHE BOOL "Vcpkg VCPKG_VERBOSE") + +message(STATUS "vcpkg_toolchain_file:${vcpkg_toolchain_file}") +include(${vcpkg_toolchain_file}) diff --git a/vcpkg.json b/vcpkg.json index d4769049..520060ae 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -28,6 +28,12 @@ } ], "vcpkg-configuration": { + "overlay-ports": [ + "cmake/vcpkg/ports" + ], + "overlay-triplets": [ + "cmake/vcpkg/triplets" + ], "registries": [ { "kind": "git",