diff --git a/.github/workflows/build-all.yml b/.github/workflows/build-all.yml index dc8de06..462ac32 100644 --- a/.github/workflows/build-all.yml +++ b/.github/workflows/build-all.yml @@ -9,9 +9,6 @@ on: - main workflow_dispatch: -env: - VCPKG_COMMIT_ID: 'ad25766aefb5313b6bc4e2a4b78a2946f84fbf66' - jobs: build_and_test: name: ${{ matrix.os }}-${{ github.workflow }} @@ -23,12 +20,6 @@ jobs: include: - os: windows-latest cmake_preset: msvc22 - # extra_args: -D ZQ_WITH_PROTO=OFF - # there was this odd error that could not be reproduced locally on Windos 10 or 11 - # -> Running cpp protocol buffer compiler on D:/a/zq/zq/proto/pingpong.proto - # The system cannot find the batch label specified - VCEnd - # error MSB8066 - # need to look into it extra ,but for now, disable proto on Windows - os: ubuntu-latest cmake_preset: ninja - os: macos-latest @@ -50,23 +41,15 @@ jobs: - uses: lukka/get-cmake@latest with: - cmakeVersion: "~3.29.0" + cmakeVersion: "~4.0.0" ninjaVersion: "^1.12.0" - # it's not good to not test proto on Windows, but that accelerates the build for Windows - # - name: Remove protobuf from vcpkg.json on Windows - # run: | - # (Get-Content -path vcpkg.json) | Where-Object { $_ -notmatch '^\s*"protobuf",\s*$' } | Set-Content -Path vcpkg.json - # shell: pwsh - # if: matrix.os == 'windows-latest' - - name: Setup vcpkg - uses: lukka/run-vcpkg@v11 - id: runvcpkg - with: - vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg' - vcpkgGitCommitId: '${{ env.VCPKG_COMMIT_ID }}' - vcpkgJsonGlob: 'vcpkg.json' + - name: Update vcpkg + shell: bash + run: | + git -C "$VCPKG_INSTALLATION_ROOT" fetch origin master + git -C "$VCPKG_INSTALLATION_ROOT" reset --hard origin/master - name: Configure CMake run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index f9c0001..7e5176b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,18 +19,17 @@ endif() option(ZQ_WITH_PROTO "Build with protobuf tests" OFF) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) find_package(astr CONFIG REQUIRED) find_package(ZeroMQ CONFIG REQUIRED) -find_package(tl-expected CONFIG REQUIRED) - +find_package(commonCompilerWarnings CONFIG REQUIRED) list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") if (${ZQ_TEST_PROJECT}) include(CTest) - include(testing) + include(lib/testing) add_subdirectory(tests) endif() @@ -65,7 +64,6 @@ endif() target_link_libraries(zq INTERFACE libzmq - tl::expected # until C++23 a4z::astr ) diff --git a/CMakePresets.json b/CMakePresets.json index cf2c71c..8d5fb82 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -1,163 +1,9 @@ { - "version": 6, - "cmakeMinimumRequired": { - "major": 3, - "minor": 27, - "patch": 0 - }, - "configurePresets": [ - { - "name": "base", - "hidden": true, - "binaryDir": "${sourceDir}/build/${presetName}", - "toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", - "cacheVariables": { - "CMAKE_MODULE_PATH": "${sourceDir}/cmake", - "CMAKE_PROJECT_INCLUDE": "cmake-plugins" - } - }, - { - "inherits": "base", - "name": "ninja", - "displayName": "Ninja (multi-config)", - "description": "Default Ninja Multi-Config", - "generator": "Ninja Multi-Config" - }, - { - "inherits": "base", - "name": "msvc22", - "displayName": "VisualStudio", - "description": "Config for VisualStudio", - "generator": "Visual Studio 17 2022" - }, - { - "inherits": "base", - "name": "xcode", - "displayName": "XCode", - "description": "Config for Xcode", - "generator": "Xcode" - }, - { - "inherits": "base", - "name": "gcc14", - "displayName": "Gcc-14", - "description": "Gcc-14, Ninja Multi-Config", - "generator": "Ninja Multi-Config", - "cacheVariables": { - "VCPKG_CHAINLOAD_TOOLCHAIN_FILE": "${sourceDir}/cmake/gcc14-toolchain.cmake", - "VCPKG_OVERLAY_TRIPLETS": "${sourceDir}/cmake", - "VCPKG_TARGET_TRIPLET": "gcc14-triplet" - } - } - ], - "buildPresets": [ - { - "name": "ninja", - "configurePreset": "ninja", - "configuration": "Debug" - }, - { - "name": "ninja-release", - "configurePreset": "ninja", - "configuration": "Release" - }, - { - "name": "msvc22", - "configurePreset": "msvc22", - "configuration": "Debug" - }, - { - "name": "msvc22-release", - "configurePreset": "msvc22", - "configuration": "Release" - }, - { - "name": "xcode", - "configurePreset": "xcode", - "configuration": "Debug" - }, - { - "name": "xcode-release", - "configurePreset": "xcode", - "configuration": "Release" - }, - { - "name": "gcc14", - "configurePreset": "gcc14", - "configuration": "Debug" - }, - { - "name": "gcc14-release", - "configurePreset": "gcc14", - "configuration": "Release" - } - ], - "testPresets": [ - { - "name": "ninja", - "configurePreset": "ninja", - "configuration": "Debug", - "output": { - "outputOnFailure": true - }, - "execution": { - "noTestsAction": "error", - "stopOnFailure": true - } - }, - { - "name": "ninja-release", - "inherits": "ninja", - "configuration": "Release" - }, - { - "name": "msvc22", - "configurePreset": "msvc22", - "configuration": "Debug" - }, - { - "name": "msvc22-release", - "configurePreset": "msvc22", - "configuration": "Release" - }, - { - "name": "xcode", - "configurePreset": "xcode", - "configuration": "Debug" - }, - { - "name": "xcode-release", - "configurePreset": "xcode", - "configuration": "Release" - }, - { - "name": "gcc14", - "configurePreset": "gcc14", - "configuration": "Debug" - }, - { - "name": "gcc14-release", - "inherits": "gcc14", - "configuration": "Release" - } - ], - "workflowPresets": [ - { - "name": "xcode", - "steps": [ - { - "type": "configure", - "name": "xcode" - }, - { - "type": "build", - "name": "xcode" - }, - { - "type": "test", - "name": "xcode" - } - ] - } + "version": 10, + "include": [ + "cmake/preset/ninja.json", + "cmake/preset/xcode.json", + "cmake/preset/msvc22.json", + "cmake/preset/msvc26.json" ] -} +} \ No newline at end of file diff --git a/README.md b/README.md index 9a5ddf3..a2dcc21 100644 --- a/README.md +++ b/README.md @@ -39,11 +39,9 @@ After the project has been built, you are ready to run the tests: ctest --preset= ``` - - ## GitDiagram -Generated via: https://gitdiagram.com/a4z/zq +Generated via: ```mermaid graph TB @@ -143,4 +141,4 @@ graph TB ``` -😊 +😊 diff --git a/cmake/add-on/coverage-clang.cmake b/cmake/add-on/coverage-clang.cmake new file mode 100644 index 0000000..75fd906 --- /dev/null +++ b/cmake/add-on/coverage-clang.cmake @@ -0,0 +1,27 @@ +include_guard(GLOBAL) + +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + message(STATUS "-- Clang Coverage enabled, CMAKE_CXX_COMPILER:" ${CMAKE_CXX_COMPILER}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-instr-generate -fcoverage-mapping") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-instr-generate") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fprofile-instr-generate") +else() + message(FATAL_ERROR "Clang Coverage is only supported with Clang") +endif() + +set(COVERAGE_TOOL "llvm-profdata") + +add_custom_target(coverage + COMMAND ${CMAKE_COMMAND} -E env "PATH=$ENV{PATH}" + ${CMAKE_CURRENT_LIST_DIR}/coverage-report-clang.sh --build-dir ${CMAKE_BINARY_DIR} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating coverage report using coverage-report-clang.sh" +) + +add_custom_target(clean_coverage + COMMAND find . -name '*.profraw' -delete + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) + + diff --git a/cmake/add-on/coverage-gcov.cmake b/cmake/add-on/coverage-gcov.cmake new file mode 100644 index 0000000..0d95b64 --- /dev/null +++ b/cmake/add-on/coverage-gcov.cmake @@ -0,0 +1,46 @@ +include_guard(GLOBAL) + +# TODO , check that we are on GCC +if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + message(FATAL_ERROR "This coverage implementation requires the GCC compiler") +endif() + + +message(STATUS "----- GNU Coverage enabled") +# TODO, add -fprofile-abs-path when compiler is gcc +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage") + + + +find_program(LCOV lcov) +find_program(GCOV gcov) +if(NOT GCOV) + message(FATAL_ERROR "gcov tool not found for GCC version ${GCC_MAJOR_VERSION}") +endif() + +set(COVERAGE_BRANCHES "--rc branch_coverage=1") +# these warnings are ridiculous, they depend on the lcov genhtml version +set(COVERAGE_WARNINGS "--ignore-errors gcov --ignore-errors mismatch --ignore-errors unused") +set(GENHTML_WARNINGS "") + +set(COVERAGE_TOOL "lcov") + +separate_arguments(COVERAGE_BRANCHES) +separate_arguments(COVERAGE_WARNINGS) +separate_arguments(GENHTML_WARNINGS) +add_custom_target(coverage + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/coverage + COMMAND lcov --directory . --capture --output-file ${CMAKE_BINARY_DIR}/coverage/coverage.info ${COVERAGE_WARNINGS} ${COVERAGE_BRANCHES} + COMMAND lcov --remove ${CMAKE_BINARY_DIR}/coverage/coverage.info '/usr/*' '*/tests/*' '*/vcpkg_installed/*' '${CMAKE_BINARY_DIR}/_deps/*' '${CMAKE_SOURCE_DIR}/external/*' --output-file ${CMAKE_BINARY_DIR}/coverage/coverage.info.cleaned ${COVERAGE_WARNINGS} ${COVERAGE_BRANCHES} + COMMAND genhtml --branch-coverage ${CMAKE_BINARY_DIR}/coverage/coverage.info.cleaned --output-directory ${CMAKE_BINARY_DIR}/coverage ${GENHTML_WARNINGS} ${COVERAGE_BRANCHES} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) + + +add_custom_target(clean_coverage + COMMAND find . -name '*.gcda' -delete + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) diff --git a/cmake/add-on/coverage-report-clang.sh b/cmake/add-on/coverage-report-clang.sh new file mode 100644 index 0000000..5f54234 --- /dev/null +++ b/cmake/add-on/coverage-report-clang.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +# Directory containing the test binaries +set -e + +# Parse arguments +TEST_BIN_DIR="" +while [ "$#" -gt 0 ]; do + case "$1" in + --build-dir) + TEST_BIN_DIR="$2" + shift 2 + ;; + --build-dir=*) + TEST_BIN_DIR="${1#*=}" + shift 1 + ;; + *) + echo "Unknown option: $1" + exit 1 + ;; + esac +done + +if [ -z "${TEST_BIN_DIR}" ]; then + echo "Please provide the build directory by using the --build-dir option" + exit 1 +fi + +# Set XCRUN based on the output of uname +if [ "$(uname)" = "Darwin" ]; then + XCRUN="xcrun" +else + XCRUN="" +fi + +# Directory to store the coverage report +# TODO, add into build dir +COVERAGE_REPORT_DIR="${TEST_BIN_DIR}/coverage_report" + +# Remove any existing .profraw files +# find ${TEST_BIN_DIR} -name "*.profraw" -delete + +# Find all .profraw files +ALL_PROFILES=$(find ${TEST_BIN_DIR} -name '*.profraw') +ALL_BINARIES='' +for profile in ${ALL_PROFILES}; do + binary=$(basename -s .profraw "${profile}") + binary_path=$(find "${TEST_BIN_DIR}" -type f -name "${binary}" -print -quit) + if [ -z "${binary_path}" ]; then + echo "Binary ${binary} for profile ${profile} not found in ${TEST_BIN_DIR}" + # exit 1 + else + ALL_BINARIES="${ALL_BINARIES} ${binary_path}" + fi +done + +COVERAGE_COMBINED_FILE="${TEST_BIN_DIR}/coverage-all.profraw" + +# Merge all .profraw files into a single .profdata file +rm -f ${COVERAGE_COMBINED_FILE} +echo "Merging profiles into ${COVERAGE_COMBINED_FILE}" +${XCRUN} llvm-profdata merge -sparse ${ALL_PROFILES} -o ${COVERAGE_COMBINED_FILE} + +IGNORE_REGEX="${TEST_BIN_DIR}/_deps/.*|tests/.*" +echo "Generating plain coverage report" +# Generate the plain text coverage report for each binary +for binary in ${ALL_BINARIES}; do + ${XCRUN} llvm-cov show ${binary} \ + -instr-profile=${COVERAGE_COMBINED_FILE} \ + -ignore-filename-regex=${IGNORE_REGEX} \ + -output-dir=${COVERAGE_REPORT_DIR}/plain +done + +# Generate an HTML coverage report for each binary +echo "Generating HTML coverage report" +for binary in ${ALL_BINARIES}; do + ${XCRUN} llvm-cov show ${binary} \ + -instr-profile=${COVERAGE_COMBINED_FILE} \ + -ignore-filename-regex=${IGNORE_REGEX} \ + -format=html \ + -output-dir=${COVERAGE_REPORT_DIR}/html +done + +# Open the HTML report +echo "Opening the HTML coverage report: ${COVERAGE_REPORT_DIR}/html/index.html" +#open ${COVERAGE_REPORT_DIR}/html/index.html + diff --git a/cmake/add-on/fetch-dependencies.cmake b/cmake/add-on/fetch-dependencies.cmake new file mode 100644 index 0000000..748814d --- /dev/null +++ b/cmake/add-on/fetch-dependencies.cmake @@ -0,0 +1,29 @@ + +include(FetchContent) +FetchContent_Declare( + astr + GIT_REPOSITORY https://github.com/a4z/astr.git + GIT_TAG v0.3.1 + OVERRIDE_FIND_PACKAGE +) + +FetchContent_Declare( + commonCompilerWarnings + GIT_REPOSITORY https://github.com/a4z/commonCompilerWarnings.git + GIT_TAG main + OVERRIDE_FIND_PACKAGE +) + +FetchContent_Declare( + doctest + SYSTEM + GIT_REPOSITORY "https://github.com/onqtam/doctest" + GIT_TAG "dev" + OVERRIDE_FIND_PACKAGE +) + +set(DOCTEST_NO_INSTALL TRUE) + +set(commonCompilerWarnings_NO_INSTALL TRUE) +# now with this problem solved, we probably should always fetch that internally +# so for users, this just works diff --git a/cmake/clang-tools.cmake b/cmake/clang-tools.cmake deleted file mode 100644 index 9d2fdda..0000000 --- a/cmake/clang-tools.cmake +++ /dev/null @@ -1,40 +0,0 @@ -add_custom_target( - clang-tidy - COMMAND git ls-files | grep -E "^(include|src)/.*\.(c|cpp|h|hpp)$" | xargs clang-tidy --extra-arg=-std=c++${CMAKE_CXX_STANDARD} -p ${CMAKE_BINARY_DIR} --header-filter='^$' - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - VERBATIM - USES_TERMINAL -) - -add_custom_target( - clang_tidy - COMMAND ${CMAKE_SOURCE_DIR}/run_clang_tidy.sh ${CMAKE_CXX_STANDARD} ${CMAKE_BINARY_DIR} - COMMENT "Running clang-tidy on each file individually" - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - USES_TERMINAL -) - -if(WIN32) - set(FORMAT_COMMAND powershell -Command "git ls-files | Where-Object {$_ -match '.*\\.(c|h|cpp|hpp)$'} | ForEach-Object {clang-format -i $_}") - set(FORMAT_CHECK_COMMAND powershell -Command "git ls-files | Where-Object {$_ -match '.*\\.(c|h|cpp|hpp)$'} | ForEach-Object {clang-format --Werror --dry-run $_}") -else() - set(FORMAT_COMMAND git ls-files | grep -E ".*\\.(c|h|cpp|hpp)$" | xargs clang-format -i) - set(FORMAT_CHECK_COMMAND git ls-files | grep -E ".*\\.(c|h|cpp|hpp)$" | xargs clang-format --Werror --dry-run) -endif() - -add_custom_target( - clang-format - # COMMAND git ls-files | grep -E ".*\\.(c|h|cpp|hpp)$" | xargs clang-format -i - COMMAND ${FORMAT_COMMAND} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - VERBATIM -) - -add_custom_target( - clang-format-check - # COMMAND git ls-files | grep -E ".*\\.(c|h|cpp|hpp)$" | xargs clang-format --Werror --dry-run - COMMAND ${FORMAT_CHECK_COMMAND} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - VERBATIM - USES_TERMINAL -) diff --git a/cmake/cmake-plugins.cmake b/cmake/cmake-plugins.cmake deleted file mode 100644 index dcf27d1..0000000 --- a/cmake/cmake-plugins.cmake +++ /dev/null @@ -1,5 +0,0 @@ - - -include(setup_compiler) -include(default_flags) -include(clang-tools) diff --git a/cmake/default_coverage.cmake b/cmake/default_coverage.cmake deleted file mode 100644 index a7dcb91..0000000 --- a/cmake/default_coverage.cmake +++ /dev/null @@ -1,48 +0,0 @@ -include_guard(GLOBAL) - -option(COVERAGE "Enable coverage reporting" OFF) - -add_library(_zq_DefaultCoverage INTERFACE) - -if (COVERAGE) - - message("Enable code coverage") - - target_compile_options(_zq_DefaultCoverage - INTERFACE - $<$: --coverage> - - $<$: --coverage> - ) - - target_link_options(_zq_DefaultCoverage - INTERFACE - $<$: --coverage> - - $<$: --coverage> - ) - - set(COVERAGE_BRANCHES "--rc branch_coverage=1") - set(COVERAGE_WARNINGS "--ignore-errors gcov") - set(GENHTML_WARNINGS "") - if(APPLE) - set(COVERAGE_WARNINGS "--ignore-errors gcov --ignore-errors inconsistent --ignore-errors unused --ignore-errors range --ignore-errors empty") - set(GENHTML_WARNINGS "--ignore-errors inconsistent --ignore-errors empty") - endif() - separate_arguments(COVERAGE_BRANCHES) - separate_arguments(COVERAGE_WARNINGS) - separate_arguments(GENHTML_WARNINGS) - add_custom_target(coverage - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/coverage - COMMAND lcov --directory . --capture --output-file ${CMAKE_BINARY_DIR}/coverage/coverage.info ${COVERAGE_WARNINGS} ${COVERAGE_BRANCHES} - COMMAND lcov --remove ${CMAKE_BINARY_DIR}/coverage/coverage.info '/usr/*' '*/tests/*' '*/vcpkg_installed/*' '${CMAKE_SOURCE_DIR}/external/*' --output-file ${CMAKE_BINARY_DIR}/coverage/coverage.info.cleaned ${COVERAGE_WARNINGS} ${COVERAGE_BRANCHES} - COMMAND genhtml --branch-coverage ${CMAKE_BINARY_DIR}/coverage/coverage.info.cleaned --output-directory ${CMAKE_BINARY_DIR}/coverage ${GENHTML_WARNINGS} ${COVERAGE_BRANCHES} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - - - - -endif(COVERAGE) - -add_library(zq_default::coverage ALIAS _zq_DefaultCoverage) diff --git a/cmake/default_flags.cmake b/cmake/default_flags.cmake deleted file mode 100644 index 410a29c..0000000 --- a/cmake/default_flags.cmake +++ /dev/null @@ -1,23 +0,0 @@ -include_guard(GLOBAL) - -include(default_warnings) -include(default_libs) -include(default_coverage) - -add_library(_zq_DefaultFlags INTERFACE) - -target_link_libraries(_zq_DefaultFlags - INTERFACE zq_default::libs zq_default::warnings zq_default::coverage -) - -# TODO , this Windows part is of course totally untested -# and it does not work if the dependencies are not adjusted accordently, -# todo , if this is wanted, a custom tripplet is needed -# target_compile_options(_zq_DefaultFlags -# INTERFACE -# $<$,$>: /MTd> -# $<$,$>: /MT> -# ) -add_library(zq_default::flags ALIAS _zq_DefaultFlags) - - diff --git a/cmake/default_libs.cmake b/cmake/default_libs.cmake deleted file mode 100644 index cc7f4fc..0000000 --- a/cmake/default_libs.cmake +++ /dev/null @@ -1,11 +0,0 @@ -include_guard(GLOBAL) - -find_package (Threads) - -add_library(_zq_DefaultLibs INTERFACE) - -target_link_libraries(_zq_DefaultLibs - INTERFACE Threads::Threads -) - -add_library(zq_default::libs ALIAS _zq_DefaultLibs) diff --git a/cmake/default_warnings.cmake b/cmake/default_warnings.cmake deleted file mode 100644 index d26e4f3..0000000 --- a/cmake/default_warnings.cmake +++ /dev/null @@ -1,59 +0,0 @@ -include_guard(GLOBAL) - - -add_library(_zq_DefaultWarnings INTERFACE) -target_compile_options(_zq_DefaultWarnings - INTERFACE - $<$,$,$>: - -Wall -Wextra -pedantic - -Wdeprecated - -Wformat-security - -Wimplicit-fallthrough - -Wmissing-braces - -Wmissing-field-initializers - -Wnon-virtual-dtor - -Wnull-dereference - -Wold-style-cast -# -Wpadded # want that only for protocols where memcp on stucts in used - -Wparentheses - -Wpointer-arith - -Wredundant-decls - -Wreturn-type - -Wsequence-point - -Wshadow - -Wswitch - -Wuninitialized - -Wunused-function - -Wunused-variable - -Wunused-variable - -Wconversion - -Wsign-conversion - -Wsign-promo - -Wfloat-conversion - -pthread - > - - $<$: -ferror-limit=3> - - $<$: -Wduplicated-branches - -Wduplicated-cond - -Wlogical-op - -Wcast-align - # -Wno-missing-field-initializers - > - - $<$:/W4> -) - -# since cmake 3.24 we use COMPILE_WARNING_AS_ERROR -# option(WARN_ERROR "Thread warnings as errors" OFF) - -# if(WARN_ERROR) -# target_compile_options(_zq_DefaultWarnings -# INTERFACE -# $<$,$,$>:-Werror> -# $<$:/WX> -# ) -# endif(WARN_ERROR) - -add_library(zq_default::warnings ALIAS _zq_DefaultWarnings) diff --git a/cmake/gcc14-toolchain.cmake b/cmake/gcc14-toolchain.cmake deleted file mode 100644 index c58e666..0000000 --- a/cmake/gcc14-toolchain.cmake +++ /dev/null @@ -1,21 +0,0 @@ -find_program(GCC_PATH gcc-14) -find_program(GPP_PATH g++-14) - -if(NOT GCC_PATH) - message(FATAL_ERROR "${GCC_PATH} not found") -endif() - -if(NOT GPP_PATH) - message(FATAL_ERROR "GPP_PATH not found") -endif() - - -message("Tripplet: set CMAKE_C_COMPILER " ${GCC_PATH}) -message("Tripplet: set CMAKE_CXX_COMPILER " ${GPP_PATH}) - -SET(CMAKE_C_COMPILER ${GCC_PATH}) -SET(CMAKE_CXX_COMPILER ${GPP_PATH}) - -if (APPLE) - set(CMAKE_EXE_LINKER_FLAGS "-Wl,-ld_classic") -endif() diff --git a/cmake/gcc14-triplet.cmake b/cmake/gcc14-triplet.cmake deleted file mode 100644 index 9cf6789..0000000 --- a/cmake/gcc14-triplet.cmake +++ /dev/null @@ -1,14 +0,0 @@ -get_filename_component(TRIPLET_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) -set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${TRIPLET_DIR}/gcc14-toolchain.cmake) - -set(VCPKG_CRT_LINKAGE dynamic) -set(VCPKG_LIBRARY_LINKAGE static) - -if (APPLE) - set(CMAKE_EXE_LINKER_FLAGS "-Wl,-ld_classic") - set(VCPKG_TARGET_ARCHITECTURE arm64) - set(VCPKG_CMAKE_SYSTEM_NAME Darwin) -else() - set(VCPKG_TARGET_ARCHITECTURE x64) - set(VCPKG_CMAKE_SYSTEM_NAME Linux) -endif() diff --git a/cmake/lib/debug.cmake b/cmake/lib/debug.cmake new file mode 100644 index 0000000..ddcc12b --- /dev/null +++ b/cmake/lib/debug.cmake @@ -0,0 +1,21 @@ + +function(print_all_variables) + message(STATUS "CMake Variables:") + #get_cmake_property(_variableNames VARIABLES) + get_cmake_property(_variableNames CACHE_VARIABLES) + list(SORT _variableNames) + foreach (_variableName ${_variableNames}) + message(STATUS "${_variableName}=${${_variableName}}") + endforeach() +endfunction() + +# Call the function to print all variables +# print_all_variables() + +function(print_variable var_name) + if(DEFINED ${var_name}) + message(STATUS "${var_name}=${${var_name}}") + else() + message(STATUS "${var_name} is not defined") + endif() +endfunction() diff --git a/cmake/lib/doxydoc.cmake b/cmake/lib/doxydoc.cmake new file mode 100644 index 0000000..3f92b11 --- /dev/null +++ b/cmake/lib/doxydoc.cmake @@ -0,0 +1,32 @@ +include_guard(GLOBAL) + +find_package( Doxygen QUIET ) +if(NOT DOXYGEN_FOUND) + message(STATUS "Doxygen not found, doc target not available") + return() +endif() + +include(FetchContent) +FetchContent_Declare( + doxygen-awesome-css + URL https://github.com/jothepro/doxygen-awesome-css/archive/refs/tags/v2.4.0.zip +) +FetchContent_MakeAvailable(doxygen-awesome-css) + +FetchContent_GetProperties(doxygen-awesome-css SOURCE_DIR AWESOME_CSS_DIR) + +if(DOT) + set(HAVE_DOT YES) +else(DOT) + set(HAVE_DOT NO) +endif(DOT) + +configure_file(${PROJECT_SOURCE_DIR}/doc/doxyfile.cmake + ${PROJECT_BINARY_DIR}/doc/${PROJECT_NAME}.doxyfile +) + +#todo, naming, would like to have doxydoc in all projects +#add_custom_target(doc${PROJECT_NAME} ${DOXYGEN} +add_custom_target(doc ${DOXYGEN} + ${PROJECT_BINARY_DIR}/doc/${PROJECT_NAME}.doxyfile +) diff --git a/cmake/lib/find_sqlite.cmake b/cmake/lib/find_sqlite.cmake new file mode 100644 index 0000000..55db1b5 --- /dev/null +++ b/cmake/lib/find_sqlite.cmake @@ -0,0 +1,62 @@ + +#[[ + +in an optimal world, this would just work: + + find_package(SQLite3 REQUIRED) + target_link_libraries(sl3 PUBLIC ${SQLite3_LIBRARIES}) + target_include_directories(sl3 SYSTEM BEFORE PRIVATE ${SQLite3_INCLUDE_DIRS}) + +but it does not + +this happened on Mac CI, + +/Users/runner/work/libsl3/libsl3/tests/version/versiontest.cpp:6: + Scenario: check sqlite versions for library and app + Given: cmake genertated config + When: comparing the compile/runtime version numbers + Then: they are the same + +/Users/runner/work/libsl3/libsl3/tests/version/versiontest.cpp:27: ERROR: CHECK_EQ( sl3::sqliteCompiledVersionNumber (), sl3::sqliteRuntimeVersionNumber () ) is NOT correct! + values: CHECK_EQ( 3026000, 3043002 ) + +~~~~~ +~~~~~ + +package-manager could be helpful, but are sometimes not + +vcpkg, for example, does the following: +------ +sqlite3 provides pkgconfig bindings. +sqlite3 provides CMake targets: + + find_package(unofficial-sqlite3 CONFIG REQUIRED) + target_link_libraries(main PRIVATE unofficial::sqlite3::sqlite3) +------ + +How to deliver a library that should work / be able to recompile in multiple contexts + +What if conan is used, instead of vcpkg +Or someone whats to rely whats on the system (root fs on x compile for yocto) + +# ]] + + +include(lib/debug) +#print_all_variables() + +if (sl3_USE_INTERNAL_SQLITE3) + include( sqlite/setup_sqlite3.cmake ) +else(sl3_USE_INTERNAL_SQLITE3) + if (_VCPKG_INSTALLED_DIR) + find_package(unofficial-sqlite3 REQUIRED) + set(SQLITE_LINK_NAME unofficial::sqlite3::sqlite3) + else() + find_package(SQLite3 REQUIRED) + set(SQLITE_LINK_NAME SQLite::SQLite3) + endif() +endif(sl3_USE_INTERNAL_SQLITE3) + +# print_variable(SQLite3_INCLUDE_DIR) +# print_variable(SQLite3_LIBRARY) + diff --git a/cmake/lib/install.cmake b/cmake/lib/install.cmake new file mode 100644 index 0000000..98e7cfb --- /dev/null +++ b/cmake/lib/install.cmake @@ -0,0 +1,34 @@ +include_guard(GLOBAL) + +include(GNUInstallDirs) + +install(TARGETS sl3 EXPORT sl3Targets) +INSTALL(FILES ${sl3_HDR} DESTINATION include/sl3) +INSTALL(FILES include/sl3.hpp DESTINATION include/sl3) + +install(EXPORT sl3Targets + FILE sl3Targets.cmake + NAMESPACE a4z:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" +) + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/sl3ConfigVersion.cmake + COMPATIBILITY AnyNewerVersion +) +configure_package_config_file( + ${CMAKE_CURRENT_LIST_DIR}/sl3Config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/sl3Config.cmake + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" +) + +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/sl3Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/sl3ConfigVersion.cmake + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" + +) + + diff --git a/cmake/lib/setup-warnings.cmake b/cmake/lib/setup-warnings.cmake new file mode 100644 index 0000000..e0b9039 --- /dev/null +++ b/cmake/lib/setup-warnings.cmake @@ -0,0 +1,2 @@ +include_guard(GLOBAL) + diff --git a/cmake/lib/sl3Config.cmake.in b/cmake/lib/sl3Config.cmake.in new file mode 100644 index 0000000..95443ea --- /dev/null +++ b/cmake/lib/sl3Config.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/sl3Targets.cmake") + +check_required_components("sl3") diff --git a/cmake/testing.cmake b/cmake/lib/testing.cmake similarity index 80% rename from cmake/testing.cmake rename to cmake/lib/testing.cmake index 2b18522..2b82cbb 100644 --- a/cmake/testing.cmake +++ b/cmake/lib/testing.cmake @@ -1,11 +1,5 @@ include_guard(GLOBAL) -# include(simpletargets) - - -# this is obviously a requirements, tests... -# TODO , find that file, in test and tests -# add_library(doctest_main OBJECT ${PROJECT_SOURCE_DIR}/tests/test_main.cpp) find_package(doctest CONFIG REQUIRED) @@ -30,7 +24,7 @@ function (add_doctest NAME) add_executable(${NAME} ${D_TEST_SOURCES}) target_link_libraries(${NAME} doctest_main) - target_link_libraries(${NAME} ${TEST_FRAMEWORK} zq zq_default::flags) + target_link_libraries(${NAME} ${TEST_FRAMEWORK} zq a4z::commonCompilerWarnings) if (ZQ_WITH_PROTO) target_link_libraries(${NAME} zqproto) endif() diff --git a/cmake/preset/base.json b/cmake/preset/base.json new file mode 100644 index 0000000..04a43b7 --- /dev/null +++ b/cmake/preset/base.json @@ -0,0 +1,34 @@ +{ + "version": 8, + "configurePresets": [ + { + "name": "base", + "hidden": true, + "generator": "Ninja Multi-Config", + "binaryDir": "${sourceDir}/build/${hostSystemName}/${presetName}", + "toolchainFile": "${sourceDir}/cmake/toolchain/router.cmake", + "cacheVariables": { + "CMAKE_COMPILE_WARNING_AS_ERROR": "ON", + "ACTIVE_PRESET_NAME": "${presetName}", + "CMAKE_MODULE_PATH": "${sourceDir}/cmake", + "CMAKE_PROJECT_INCLUDE": "project-setup", + "TOOLCHAIN_INCLUDES": "toolchain/use-vcpkg" + }, + "environment": {} + } + ], + "testPresets": [ + { + "name": "base", + "configurePreset": "base", + "configuration": "Debug", + "output": { + "outputOnFailure": true + }, + "execution": { + "noTestsAction": "error", + "stopOnFailure": true + } + } + ] +} \ No newline at end of file diff --git a/cmake/preset/msvc22.json b/cmake/preset/msvc22.json new file mode 100644 index 0000000..9e819df --- /dev/null +++ b/cmake/preset/msvc22.json @@ -0,0 +1,59 @@ +{ + "version": 8, + "include": ["base.json"], + "configurePresets": [ + { + "name": "msvc22", + "inherits": "base", + "generator": "Visual Studio 17 2022", + "cacheVariables": { + "TOOLCHAIN_INCLUDES": "toolchain/use-vcpkg" + } + } + ], + "buildPresets": [ + { + "name": "msvc22", + "configurePreset": "msvc22", + "configuration": "Debug", + "jobs": 0 + }, + { + "name": "msvc22-release", + "configurePreset": "msvc22", + "configuration": "Release", + "jobs": 0 + } + ], + "testPresets": [ + { + "name": "msvc22", + "inherits": "base", + "configurePreset": "msvc22" + }, + { + "name": "msvc22-release", + "inherits": "msvc22", + "configuration": "Release" + } + ], + "workflowPresets": [ + { + "name": "msvc22", + "steps": [ + { + "type": "configure", + "name": "msvc22" + }, + { + "type": "build", + "name": "msvc22" + }, + { + "type": "test", + "name": "msvc22" + } + ] + } + ] +} diff --git a/cmake/preset/msvc26.json b/cmake/preset/msvc26.json new file mode 100644 index 0000000..ab3260c --- /dev/null +++ b/cmake/preset/msvc26.json @@ -0,0 +1,61 @@ +{ + "version": 8, + "include": [ + "base.json" + ], + "configurePresets": [ + { + "name": "msvc26", + "inherits": "base", + "generator": "Visual Studio 18 2026", + "cacheVariables": { + "TOOLCHAIN_INCLUDES": "toolchain/use-vcpkg" + } + } + ], + "buildPresets": [ + { + "name": "msvc26", + "configurePreset": "msvc26", + "configuration": "Debug", + "jobs": 0 + }, + { + "name": "msvc26-release", + "configurePreset": "msvc26", + "configuration": "Release", + "jobs": 0 + } + ], + "testPresets": [ + { + "name": "msvc26", + "inherits": "base", + "configurePreset": "msvc26" + }, + { + "name": "msvc26-release", + "inherits": "msvc26", + "configuration": "Release" + } + ], + "workflowPresets": [ + { + "name": "msvc26", + "steps": [ + { + "type": "configure", + "name": "msvc26" + }, + { + "type": "build", + "name": "msvc26" + }, + { + "type": "test", + "name": "msvc26" + } + ] + } + ] +} \ No newline at end of file diff --git a/cmake/preset/ninja.json b/cmake/preset/ninja.json new file mode 100644 index 0000000..481319e --- /dev/null +++ b/cmake/preset/ninja.json @@ -0,0 +1,53 @@ +{ + "version": 8, + "include": ["base.json"], + "configurePresets": [ + { + "name": "ninja", + "inherits": "base" + } + ], + "buildPresets": [ + { + "name": "ninja", + "configurePreset": "ninja", + "configuration": "Debug" + }, + { + "name": "ninja-release", + "configurePreset": "ninja", + "configuration": "Release" + } + ], + "testPresets": [ + { + "name": "ninja", + "inherits": "base", + "configurePreset": "ninja" + }, + { + "name": "ninja-release", + "inherits": "ninja", + "configuration": "Release" + } + ], + "workflowPresets": [ + { + "name": "ninja", + "steps": [ + { + "type": "configure", + "name": "ninja" + }, + { + "type": "build", + "name": "ninja" + }, + { + "type": "test", + "name": "ninja" + } + ] + } + ] +} diff --git a/cmake/preset/xcode.json b/cmake/preset/xcode.json new file mode 100644 index 0000000..cb112a1 --- /dev/null +++ b/cmake/preset/xcode.json @@ -0,0 +1,54 @@ +{ + "version": 8, + "include": ["base.json"], + "configurePresets": [ + { + "name": "xcode", + "generator": "Xcode", + "inherits": "base" + } + ], + "buildPresets": [ + { + "name": "xcode", + "configurePreset": "xcode", + "configuration": "Debug" + }, + { + "name": "xcode-release", + "configurePreset": "xcode", + "configuration": "Release" + } + ], + "testPresets": [ + { + "name": "xcode", + "inherits": "base", + "configurePreset": "xcode" + }, + { + "name": "xcode-release", + "inherits": "xcode", + "configuration": "Release" + } + ], + "workflowPresets": [ + { + "name": "xcode", + "steps": [ + { + "type": "configure", + "name": "xcode" + }, + { + "type": "build", + "name": "xcode" + }, + { + "type": "test", + "name": "xcode" + } + ] + } + ] +} diff --git a/cmake/project-setup.cmake b/cmake/project-setup.cmake new file mode 100644 index 0000000..c67c136 --- /dev/null +++ b/cmake/project-setup.cmake @@ -0,0 +1,42 @@ +include_guard(GLOBAL) +# Keep this here for now, but add a CI test that builds with 20 or 17 +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD 23) + +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) +set(CMAKE_C_STANDARD 17) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +if(PROJECT_IS_TOP_LEVEL) + # make git ignore the build directory + file(WRITE ${CMAKE_BINARY_DIR}/.gitignore "*") + include(CTest) + option(sl3_BUILD_TESTING "Build the tests" ${BUILD_TESTING}) +endif() + + +if(DEFINED ACTIVE_PRESET_NAME) + message(STATUS "-- Running preset : ${ACTIVE_PRESET_NAME}") +endif() + + + +if(DEFINED PROJECT_ADDONS) + foreach(ADDON ${PROJECT_ADDONS}) + message(STATUS "Add project addon: ${ADDON}") + include(${ADDON}) + endforeach() +endif() + + +# TODO, do I want to allow env variables also? +# probably not since that might confuse +# if(DEFINED ENV{MY_CMAKE_PROJECT_ADDONS}) +# foreach(ADDON $ENV{MY_CMAKE_PROJECT_ADDONS}) +# message(STATUS "Add project addon (env): ${ADDON}") +# include(${ADDON}) +# endforeach() +# endif() diff --git a/cmake/setup_compiler.cmake b/cmake/setup_compiler.cmake deleted file mode 100644 index 94eb7dc..0000000 --- a/cmake/setup_compiler.cmake +++ /dev/null @@ -1,38 +0,0 @@ -include_guard(GLOBAL) - -# enable ccache only if it is there -find_program(CCACHE_BIN ccache) -if(CCACHE_BIN) - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_BIN}) - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_BIN}) - message("ccache binary foud, ccache enabled") -endif() - -get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -if(NOT isMultiConfig) - message("No multiconfig project") - if(NOT CMAKE_BUILD_TYPE) - message("No build type, fix it for you") - SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING - "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." - FORCE ) - endif(NOT CMAKE_BUILD_TYPE) -else(NOT isMultiConfig) - message("** Multi config project") -endif(NOT isMultiConfig) - -# Off, we do not want to annoy potential packager -# option(WARN_ERROR "Thread warnings as errors. Default OFF" OFF) - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_EXTENSIONS OFF) -SET(CMAKE_COMPILE_WARNING_AS_ERROR ON) # turn off with --compile-no-warning-as-error - -# set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=-*,readability-*) - - -if(APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - # https://stackoverflow.com/questions/77153800/xcode-15-c-compilation-errors - # TODO ... - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-ld_classic") -endif() diff --git a/cmake/simpletargets.cmake b/cmake/simpletargets.cmake deleted file mode 100644 index 069a16d..0000000 --- a/cmake/simpletargets.cmake +++ /dev/null @@ -1,14 +0,0 @@ -include_guard(GLOBAL) - -enable_testing() - -function(bin_from_file fname outname) - get_filename_component(bname ${fname} NAME_WE) - set(${outname} ${bname} PARENT_SCOPE) - add_executable(${bname} ${fname}) - target_link_libraries (${bname} - PRIVATE zq_default::flags - ) -endfunction(bin_from_file) - - diff --git a/cmake/toolchain/add-on-coverage-gcc.cmake b/cmake/toolchain/add-on-coverage-gcc.cmake new file mode 100644 index 0000000..7b375f8 --- /dev/null +++ b/cmake/toolchain/add-on-coverage-gcc.cmake @@ -0,0 +1,14 @@ +include_guard(GLOBAL) +# that might not be the elegant way to do it, but it works mosts simple +# alternative would be finding a way to inject coverage into every target +# and that would require much more + + message(STATUS "----- GNU Coverage enabled") + # TODO, add -fprofile-abs-path when compiler is gcc + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage") + + + diff --git a/cmake/toolchain/linux-clang-san-adr-ub.cmake b/cmake/toolchain/linux-clang-san-adr-ub.cmake new file mode 100644 index 0000000..a26cda5 --- /dev/null +++ b/cmake/toolchain/linux-clang-san-adr-ub.cmake @@ -0,0 +1,4 @@ + + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined -g -O1 -fno-omit-frame-pointer") + diff --git a/cmake/toolchain/linux-clang-san-mem.cmake b/cmake/toolchain/linux-clang-san-mem.cmake new file mode 100644 index 0000000..a188315 --- /dev/null +++ b/cmake/toolchain/linux-clang-san-mem.cmake @@ -0,0 +1,5 @@ + + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory -fsanitize-memory-track-origins=2 -g -O1 -fno-omit-frame-pointer") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=memory -fsanitize-memory-track-origins=2 -g -O1 -fno-omit-frame-pointer") + diff --git a/cmake/toolchain/linux-clang.cmake b/cmake/toolchain/linux-clang.cmake new file mode 100644 index 0000000..c9a3ec5 --- /dev/null +++ b/cmake/toolchain/linux-clang.cmake @@ -0,0 +1,17 @@ + +include_guard(GLOBAL) + +message(STATUS "-- Activate toolchain linux-clang.cmake") + +set(CMAKE_C_COMPILER /usr/bin/clang) +set(CMAKE_CXX_COMPILER /usr/bin/clang++) + +# Specify the path to the Clang linker +set(CMAKE_LINKER /usr/bin/clang++) +#set(CMAKE_LINKER /usr/bin/lld) +set(CMAKE_AR /usr/bin/llvm-ar) +set(CMAKE_RANLIB /usr/bin/llvm-ranlib) +set(CMAKE_NM /usr/bin/llvm-nm) +set(CMAKE_OBJCOPY /usr/bin/llvm-objcopy) +set(CMAKE_OBJDUMP /usr/bin/llvm-objdump) +set(CMAKE_STRIP /usr/bin/llvm-strip) diff --git a/cmake/toolchain/router.cmake b/cmake/toolchain/router.cmake new file mode 100644 index 0000000..79c5f41 --- /dev/null +++ b/cmake/toolchain/router.cmake @@ -0,0 +1,38 @@ +# set(CMAKE_CXX_STANDARD_REQUIRED ON) +# set(CMAKE_CXX_EXTENSIONS OFF) +# set(CMAKE_CXX_STANDARD 23) + +# set(CMAKE_C_STANDARD_REQUIRED ON) +# set(CMAKE_C_EXTENSIONS OFF) +# set(CMAKE_C_STANDARD 17) + +# set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +find_program(CCACHE_BIN ccache) +if(CCACHE_BIN) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_BIN}) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_BIN}) + message("ccache binary foud, ccache enabled") +endif() + + +if(DEFINED TOOLCHAIN_INCLUDES) + foreach(TOOLCHAIN_INCLUDE ${TOOLCHAIN_INCLUDES}) + message(STATUS "Include toolchain : ${TOOLCHAIN_INCLUDE}") + include(${TOOLCHAIN_INCLUDE}) + endforeach() +endif() + +message(STATUS "-- Done with the toolchain router") + +# TODO, do I want to allow env variables also? +# probably not since that might confuse +# if(DEFINED ENV{TOOLCHAIN_ADDONS}) +# foreach(TC $ENV{TOOLCHAIN_ADDONS}) +# message(STATUS "Add toolchain addon (env): ${TC}") +# include(${TC}) +# endforeach() +# endif() + + + diff --git a/cmake/toolchain/use-vcpkg.cmake b/cmake/toolchain/use-vcpkg.cmake new file mode 100644 index 0000000..d65557f --- /dev/null +++ b/cmake/toolchain/use-vcpkg.cmake @@ -0,0 +1,17 @@ + +if(DEFINED ENV{VCPKG_INSTALLATION_ROOT}) + set(VCPKG_ROOT $ENV{VCPKG_INSTALLATION_ROOT}) +elseif(DEFINED ENV{VCPKG_ROOT}) + set(VCPKG_ROOT $ENV{VCPKG_ROOT}) +else() + message(FATAL_ERROR "Neither VCPKG_INSTALLATION_ROOT nor VCPKG_ROOT environment variables are defined.") +endif() + +set(_overlay "${CMAKE_SOURCE_DIR}/cmake/overlay-ports") +if(EXISTS "${_overlay}") + list(APPEND VCPKG_OVERLAY_PORTS "${_overlay}") +endif() +unset(_overlay) + +include(${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake) + diff --git a/include/zq/config.hpp b/include/zq/config.hpp index 9eb9771..69ef8a9 100644 --- a/include/zq/config.hpp +++ b/include/zq/config.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #ifdef NDEBUG constexpr bool debug_build = false; diff --git a/include/zq/context.hpp b/include/zq/context.hpp index 9cd6897..f71c004 100644 --- a/include/zq/context.hpp +++ b/include/zq/context.hpp @@ -1,8 +1,8 @@ #pragma once #include +#include #include -#include #include "config.hpp" #include "error.hpp" @@ -35,7 +35,7 @@ namespace zq { class Context { // The actual constructor - friend tl::expected mk_context( + friend std::expected mk_context( ContextOptions auto const& options) noexcept; void* z_ctx{nullptr}; @@ -54,21 +54,21 @@ namespace zq { * @param con * @param type * @param endpoint - * @return tl::expected + * @return std::expected */ - [[nodiscard]] tl::expected bind_or_connect( + [[nodiscard]] std::expected bind_or_connect( SocketCon con, SocketType type, std::string_view endpoint) noexcept { auto z_socket = zmq_socket(z_ctx, static_cast(type)); if (z_socket == nullptr) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } const int err_code = con == SocketCon::BIND ? zmq_bind(z_socket, endpoint.data()) : zmq_connect(z_socket, endpoint.data()); if (err_code != 0) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } // ZMQ_LINGER { @@ -80,14 +80,14 @@ namespace zq { zmq_setsockopt(z_socket, static_cast(SocketOptionName::LINGER), std::addressof(opt_value), opt_len); if (rc != 0) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } } SocketPointer sp{z_socket}; /* Explicitly create the expected objects, otherwise, the return value optimization will not be invoked and the Socket's move constructor and destructor will be called. */ - return tl::expected{std::move(sp)}; + return std::expected{std::move(sp)}; } public: @@ -125,9 +125,9 @@ namespace zq { * * @param type * @param endpoint - * @return tl::expected + * @return std::expected */ - [[nodiscard]] tl::expected bind( + [[nodiscard]] std::expected bind( SocketType type, std::string_view endpoint) noexcept { return bind_or_connect(SocketCon::BIND, type, endpoint); @@ -139,9 +139,9 @@ namespace zq { * * @param type * @param endpoint - * @return tl::expected + * @return std::expected */ - [[nodiscard]] tl::expected connect( + [[nodiscard]] std::expected connect( SocketType type, std::string_view endpoint) noexcept { return bind_or_connect(SocketCon::CONNECT, type, endpoint); @@ -153,20 +153,20 @@ namespace zq { * @brief Factory function for creating a context * This version takes a list of options * @param options - * @return tl::expected + * @return std::expected */ [[nodiscard]] auto inline mk_context( ContextOptions auto const& options) noexcept - -> tl::expected { + -> std::expected { auto z_ctx = zmq_ctx_new(); if (z_ctx == nullptr) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } Context ctx{z_ctx}; for (auto const& option : options) { if (zmq_ctx_set(z_ctx, static_cast(option.name), option.value) != 0) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } } return ctx; @@ -175,10 +175,10 @@ namespace zq { /** * @brief Factory function for creating a context * This version uses the default options - * @return tl::expected + * @return std::expected */ [[nodiscard]] auto inline mk_context() noexcept - -> tl::expected { + -> std::expected { return mk_context(DefaultContextOptions); } diff --git a/include/zq/message.hpp b/include/zq/message.hpp index 13388eb..bfaa8e8 100644 --- a/include/zq/message.hpp +++ b/include/zq/message.hpp @@ -167,7 +167,7 @@ namespace zq { // restore typed messages template - using restore_result = tl::expected; + using restore_result = std::expected; // This is the default template function for restore_as. // Will trigger a static assert for unsupported types @@ -183,7 +183,7 @@ namespace zq { -> restore_result { const auto having_name = as_string_view(msg.type); if (having_name != str_type_name) { - return tl::make_unexpected(ZqError("Message type does not match")); + return std::unexpected(ZqError("Message type does not match")); } return as_string(msg.payload); } @@ -205,7 +205,7 @@ namespace zq { }; auto unexpected = [](std::string_view err_msg) { - return tl::make_unexpected(ZqError(err_msg.data())); + return std::unexpected(ZqError(err_msg.data())); }; if (!check_type_name()) { diff --git a/include/zq/message_proto.hpp b/include/zq/message_proto.hpp index 1f4422e..dbe42c6 100644 --- a/include/zq/message_proto.hpp +++ b/include/zq/message_proto.hpp @@ -34,7 +34,7 @@ namespace zq { }; auto unexpected = [](std::string_view err_msg) { - return tl::make_unexpected(ZqError{err_msg.data()}); + return std::unexpected(ZqError{err_msg.data()}); }; if (!check_type_name()) { diff --git a/include/zq/socket.hpp b/include/zq/socket.hpp index 3a592b8..768e663 100644 --- a/include/zq/socket.hpp +++ b/include/zq/socket.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace zq { @@ -114,10 +115,10 @@ namespace zq { * @tparam Messages * @param first * @param messages - * @return tl::expected Number of bytes sent, or an error + * @return std::expected Number of bytes sent, or an error */ template - [[nodiscard]] tl::expected send( + [[nodiscard]] std::expected send( const Message& first, const Messages&... messages) { size_t bytes_sent = 0; @@ -126,14 +127,14 @@ namespace zq { auto rc = zmq_send(socket_ptr.get(), first.data(), first.size(), ZMQ_DONTWAIT); if (rc < 0) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } bytes_sent += static_cast(rc); } else { auto rc = zmq_send(socket_ptr.get(), first.data(), first.size(), ZMQ_SNDMORE); if (rc < 0) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } auto maybe_rc = send(messages...); if (!maybe_rc) { @@ -148,9 +149,10 @@ namespace zq { * @brief Send a typed message * * @param msg - * @return tl::expected + * @return std::expected */ - [[nodiscard]] tl::expected send(const TypedMessage& msg) { + [[nodiscard]] std::expected send( + const TypedMessage& msg) { return send(msg.type, msg.payload); } @@ -159,10 +161,10 @@ namespace zq { * * @tparam Container (std::vector or std::array) * @param msg - * @return tl::expected + * @return std::expected */ template - [[nodiscard]] tl::expected send(const Container& msg) { + [[nodiscard]] std::expected send(const Container& msg) { size_t bytes_sent = 0; size_t total_messages = msg.size(); for (size_t i = 0; i < total_messages; ++i) { @@ -171,7 +173,7 @@ namespace zq { auto& m = msg[i]; auto rc = zmq_send(socket_ptr.get(), m.data(), m.size(), flags); if (rc < 0) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } bytes_sent += static_cast(rc); } @@ -189,9 +191,9 @@ namespace zq { * case of messages that have more then two parts. In case it's not 100% * sure TypeMessage is communicated, better use one of them. * - * @return std::optional> + * @return std::optional> */ - [[nodiscard]] std::optional> recv() { + [[nodiscard]] std::optional> recv() { TypedMessage typed_message; auto rc = zmq_msg_recv(std::addressof(typed_message.type.msg), @@ -201,23 +203,23 @@ namespace zq { if (zmq_errno() == EAGAIN) { return std::nullopt; } else { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } } int more = 0; size_t more_size = sizeof(more); rc = zmq_getsockopt(socket_ptr.get(), ZMQ_RCVMORE, &more, &more_size); if (rc == -1) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } if (more) { rc = zmq_msg_recv(std::addressof(typed_message.payload.msg), socket_ptr.get(), 0); if (rc == -1) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } } else { - return tl::make_unexpected(ZqError("no more message")); + return std::unexpected(ZqError("no more message")); } return typed_message; @@ -226,9 +228,9 @@ namespace zq { /** * @brief Receive as many message parts as there are on the socket * - * @return std::optional> + * @return std::optional> */ - [[nodiscard]] std::optional, ZmqError>> + [[nodiscard]] std::optional, ZmqError>> recv_all() { std::vector messages; int more = 1; @@ -242,12 +244,12 @@ namespace zq { if (zmq_errno() == EAGAIN) { return std::nullopt; } else { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } } rc = zmq_getsockopt(socket_ptr.get(), ZMQ_RCVMORE, &more, &more_size); if (rc == -1) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } } return messages; @@ -262,15 +264,15 @@ namespace zq { * If no message is available, returns nullopt * * @param timeout - * @return std::optional> + * @return std::optional> */ - [[nodiscard]] std::optional> await( + [[nodiscard]] std::optional> await( std::chrono::milliseconds timeout) { zmq_pollitem_t poll_item[] = {{socket_ptr.get(), 0, ZMQ_POLLIN, 0}}; long tm = static_cast(timeout.count()); auto rc = zmq_poll(poll_item, 1, tm); if (rc == -1) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } return recv(); @@ -282,15 +284,15 @@ namespace zq { * Returns true if there is data to receive, false otherwise * * @param timeout - * @return tl::expected + * @return std::expected */ - [[nodiscard]] tl::expected poll( + [[nodiscard]] std::expected poll( std::chrono::milliseconds timeout) { zmq_pollitem_t poll_item[] = {{socket_ptr.get(), 0, ZMQ_POLLIN, 0}}; long tm = static_cast(timeout.count()); auto rc = zmq_poll(poll_item, 1, tm); if (rc == -1) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } return rc > 0; } @@ -301,10 +303,10 @@ namespace zq { * todo, overflow underflow description here * * @tparam N - * @return std::optional, ZmqError>> + * @return std::optional, ZmqError>> */ template - auto recv_n() -> std::optional, ZmqError>> { + auto recv_n() -> std::optional, ZmqError>> { RecvData data{}; auto rc = zmq_msg_recv(std::addressof(data.messages[0].msg), @@ -314,7 +316,7 @@ namespace zq { if (zmq_errno() == EAGAIN) { return std::nullopt; } else { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } } data.msg_count++; @@ -325,7 +327,7 @@ namespace zq { for (size_t i = 1; i < N; ++i) { rc = zmq_getsockopt(socket_ptr.get(), ZMQ_RCVMORE, &more, &more_size); if (rc == -1) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } if (!more) { return data; @@ -333,14 +335,14 @@ namespace zq { rc = zmq_msg_recv(std::addressof(data.messages[i].msg), socket_ptr.get(), 0); if (rc == -1) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } data.msg_count++; } // one more 'more' check for the overflow case is required rc = zmq_getsockopt(socket_ptr.get(), ZMQ_RCVMORE, &more, &more_size); if (rc == -1) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } if (more) { data.msg_count++; @@ -359,9 +361,9 @@ namespace zq { * * @param subscriber * @param topic_filters - * @return tl::expected + * @return std::expected */ - [[nodiscard]] inline tl::expected subscribe( + [[nodiscard]] inline std::expected subscribe( Socket& subscriber, std::initializer_list topic_filters) { // subscribe to all topics, todo, maybe overload this function with 1 or 2 @@ -372,10 +374,10 @@ namespace zq { int rc = zmq_getsockopt(subscriber.socket_ptr.get(), ZMQ_TYPE, std::addressof(val), std::addressof(size)); if (rc != 0) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } if (val != ZMQ_SUB) { - return tl::make_unexpected(ZqError("socket is not a subscriber")); + return std::unexpected(ZqError("socket is not a subscriber")); } } @@ -383,7 +385,7 @@ namespace zq { auto rc = zmq_setsockopt(subscriber.socket_ptr.get(), ZMQ_SUBSCRIBE, "", 0); if (rc != 0) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } return std::numeric_limits::max(); } @@ -393,7 +395,7 @@ namespace zq { auto rc = zmq_setsockopt(subscriber.socket_ptr.get(), ZMQ_SUBSCRIBE, t.data(), t.size()); if (rc != 0) { - return tl::make_unexpected(currentZmqError()); + return std::unexpected(currentZmqError()); } topicCount++; } diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json new file mode 100644 index 0000000..bcd7648 --- /dev/null +++ b/vcpkg-configuration.json @@ -0,0 +1,16 @@ +{ + "default-registry": { + "kind": "builtin", + "baseline": "7853666070b656d9a46fb755a3fe55530d846ade" + }, + "registries": [ + { + "kind": "git", + "baseline": "e9273e2613b55f3fef3d0cf57a4e98d60aa72b02", + "repository": "https://github.com/a4z/vcpkg-ports", + "packages": [ + "common-compiler-warnings" + ] + } + ] +} \ No newline at end of file diff --git a/vcpkg.json b/vcpkg.json index 86340d3..c568913 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,11 +1,13 @@ { "dependencies": [ + "common-compiler-warnings", "astr", "doctest", - "tl-expected", { "name": "zeromq", - "features": [ "websockets" ] + "features": [ + "websockets" + ] } ] -} +} \ No newline at end of file