diff --git a/.clang-format b/.clang-format index 01d5fac3..43e7cbc7 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,7 @@ --- +Language: Json +IndentWidth: 2 +--- Language: Cpp AccessModifierOffset: -2 AlignAfterOpenBracket: Align diff --git a/.cmake-format.json b/.cmake-format.json deleted file mode 100644 index f5120cc5..00000000 --- a/.cmake-format.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "parse": { - "additional_commands": { - "foo": { - "flags": [ - "BAR", - "BAZ" - ], - "kwargs": { - "HEADERS": "*", - "SOURCES": "*", - "DEPENDS": "*" - } - } - }, - "override_spec": {}, - "vartags": [], - "proptags": [] - }, - "format": { - "disable": false, - "line_width": 80, - "tab_size": 2, - "use_tabchars": false, - "fractional_tab_policy": "use-space", - "max_subgroups_hwrap": 2, - "max_pargs_hwrap": 6, - "max_rows_cmdline": 2, - "separate_ctrl_name_with_space": false, - "separate_fn_name_with_space": false, - "dangle_parens": false, - "dangle_align": "prefix", - "min_prefix_chars": 4, - "max_prefix_chars": 10, - "max_lines_hwrap": 2, - "line_ending": "unix", - "command_case": "canonical", - "keyword_case": "unchanged", - "always_wrap": [], - "enable_sort": true, - "autosort": false, - "require_valid_layout": false, - "layout_passes": {} - }, - "markup": { - "bullet_char": "*", - "enum_char": ".", - "first_comment_is_literal": false, - "literal_comment_pattern": null, - "fence_pattern": "^\\s*([`~]{3}[`~]*)(.*)$", - "ruler_pattern": "^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$", - "explicit_trailing_pattern": "#<", - "hashruler_min_length": 10, - "canonicalize_hashrulers": true, - "enable_markup": true - }, - "lint": { - "disabled_codes": [], - "function_pattern": "[0-9a-z_]+", - "macro_pattern": "[0-9A-Z_]+", - "global_var_pattern": "[A-Z][0-9A-Z_]+", - "internal_var_pattern": "_[A-Z][0-9A-Z_]+", - "local_var_pattern": "[a-z][a-z0-9_]+", - "private_var_pattern": "_[0-9a-z_]+", - "public_var_pattern": "[A-Z][0-9A-Z_]+", - "argument_var_pattern": "[a-z][a-z0-9_]+", - "keyword_pattern": "[A-Z][0-9A-Z_]+", - "max_conditionals_custom_parser": 2, - "min_statement_spacing": 1, - "max_statement_spacing": 2, - "max_returns": 6, - "max_branches": 12, - "max_arguments": 5, - "max_localvars": 15, - "max_statements": 50 - }, - "encode": { - "emit_byteorder_mark": false, - "input_encoding": "utf-8", - "output_encoding": "utf-8" - }, - "misc": { - "per_command": {} - } -} diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 2abc628d..30a36c12 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1 +1 @@ -907e040 +907e0406400ad008db3f724e8d255239471155b0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bafdbe83..58e104e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,14 +13,14 @@ jobs: fail-fast: false matrix: config: - - {name: "Ubuntu Clang 20", os: ubuntu-24.04, toolchain: "clang-20", clang_version: 20, installed_clang_version: 17, cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} + - {name: "Ubuntu Clang 20", os: ubuntu-24.04, toolchain: "clang-20", clang_version: 20, installed_clang_version: 17, cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Debug;Asan\" "} # Note: clang-19 + Asan setup causes errors on some platforms. Temporary skip some checks via .asan_options. - {name: "Ubuntu Clang 19", os: ubuntu-24.04, toolchain: "clang-19", clang_version: 19, installed_clang_version: 17, cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" ", asan_options: "new_delete_type_mismatch=0"} - {name: "Ubuntu Clang 18", os: ubuntu-24.04, toolchain: "clang-18", clang_version: 18, installed_clang_version: 17, cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} - {name: "Ubuntu Clang 17", os: ubuntu-24.04, toolchain: "clang-17", clang_version: 17, installed_clang_version: 17, cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} - - {name: "Ubuntu GCC 14", os: ubuntu-24.04, toolchain: "gcc-14", cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} - - {name: "Ubuntu GCC 13", os: ubuntu-24.04, toolchain: "gcc-13", cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} - - {name: "Ubuntu GCC 12", os: ubuntu-24.04, toolchain: "gcc-12", cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} + - {name: "Ubuntu GCC 14", os: ubuntu-24.04, toolchain: "gcc-14", cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan;Gcov\" ", coverage: true} + - {name: "Ubuntu GCC 13", os: ubuntu-24.04, toolchain: "gcc-13", cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} + - {name: "Ubuntu GCC 12", os: ubuntu-24.04, toolchain: "gcc-12", cmake_args: "-G \"Ninja Multi-Config\" -DCMAKE_CONFIGURATION_TYPES=\"RelWithDebInfo;Asan\" "} steps: - uses: actions/checkout@v3 with: @@ -64,6 +64,7 @@ jobs: [[ ${CLANG_VERSION} = 17 ]] && sudo apt-get install libc++-dev libc++1 libc++abi-dev libc++abi1 find /usr/lib/x86_64-linux-gnu/ -name libc++.so* || true clang++-${CLANG_VERSION} --version + type clang++-${CLANG_VERSION} - name: Install GCC if: startsWith(matrix.config.name, 'Ubuntu GCC') run: | @@ -77,13 +78,19 @@ jobs: sudo apt-get install g++-${GCC_VERSION} gcc-${GCC_VERSION} find /usr/lib/x86_64-linux-gnu/ -name libstdc++.so* g++-${GCC_VERSION} --version + type g++-${GCC_VERSION} + - name: Install Gcovr + if: matrix.config.coverage + run: | + set -x + sudo apt-get install gcovr - name: CMake Configure run: | set -x echo ${{ matrix.config.cmake_args }} echo ${{ matrix.config.toolchain }} rm -rf .build - cmake ${{ matrix.config.cmake_args }} -DCMAKE_INSTALL_PREFIX=.install -DCMAKE_TOOLCHAIN_FILE="etc/${{ matrix.config.toolchain }}-toolchain.cmake" -B .build -S . + cmake ${{ matrix.config.cmake_args }} -DCMAKE_INSTALL_PREFIX=.install -DCMAKE_PREFIX_PATH=.install -DCMAKE_TOOLCHAIN_FILE="etc/${{ matrix.config.toolchain }}-toolchain.cmake" -B .build -S . - name: CMake ASAN Build run: | set -x @@ -107,3 +114,29 @@ jobs: run: | set -x cmake --install .build --config RelWithDebInfo --component beman_optional26_development --verbose + - name: CMake Gcov Build + if: matrix.config.coverage + run: | + set -x + cmake --build .build --config Gcov --target all_verify_interface_header_sets -- -k 0 + cmake --build .build --config Gcov --target all -- -k 0 + - name: CMake Gcov Test + if: matrix.config.coverage + run: | + set -x + ctest --build-config Gcov --output-on-failure --test-dir .build + - name: Generate Coverage + if: matrix.config.coverage + run: | + set -x + cmake --build .build --config Gcov --target process_coverage -- -k 0 + - name: Coveralls + if: matrix.config.coverage + uses: coverallsapp/github-action@main + with: + file: ${{runner.workspace}}/optional26/.build/coverage.json + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: CMake Debug Workflow + run: | + set -x + cmake --workflow --preset ${{ matrix.config.toolchain }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c783148c..1329d454 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,9 @@ repos: hooks: - id: trailing-whitespace - id: end-of-file-fixer + - id: check-json - id: check-yaml + exclude: ^\.clang-format$ - id: check-added-large-files # Clang-format for C++ @@ -16,11 +18,11 @@ repos: rev: v18.1.8 hooks: - id: clang-format - types_or: [c++, c] + types_or: [c++, c, json] # CMake linting and formatting - repo: https://github.com/BlankSpruce/gersemi - rev: 0.15.1 + rev: 0.17.0 hooks: - id: gersemi name: CMake linting @@ -28,7 +30,18 @@ repos: # Markdown linting # Config file: .markdownlint.yaml - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.41.0 + rev: v0.43.0 hooks: - id: markdownlint exclude: ^papers/ + + # Config file: .codespell_ignore + - repo: https://github.com/codespell-project/codespell + rev: v2.3.0 + hooks: + - id: codespell + args: ['-I', '.codespell_ignore', '--uri-ignore-words-list'] + exclude: | + (?x)^( + papers/.* + )$ diff --git a/.shellcheckrc b/.shellcheckrc deleted file mode 100644 index 4ebc18ec..00000000 --- a/.shellcheckrc +++ /dev/null @@ -1,4 +0,0 @@ -# shellcheck -# allow for non-alphanumeric filenames -disable=SC2038 -external-sources=true diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b4897d8..e0e12144 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,15 +2,20 @@ # # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -cmake_minimum_required(VERSION 3.27) +set(CMAKE_SKIP_TEST_ALL_DEPENDENCY FALSE) -project(beman_optional26 VERSION 0.0.0 LANGUAGES CXX) +cmake_minimum_required(VERSION 3.29...3.31) + +project(beman_optional26 VERSION 0.0.1 LANGUAGES CXX) # Includes -include(CTest) -include(FetchContent) +include(CPack) +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) -set(TARGETS_EXPORT_NAME ${CMAKE_PROJECT_NAME}Targets) +set(TARGET_PACKAGE_NAME ${PROJECT_NAME}) +set(TARGETS_EXPORT_NAME ${TARGET_PACKAGE_NAME}-targets) +set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${TARGET_PACKAGE_NAME}) option( OPTIONAL26_ENABLE_TESTING @@ -20,6 +25,8 @@ option( # Build the tests if enabled via the option OPTIONAL26_ENABLE_TESTING if(OPTIONAL26_ENABLE_TESTING) + include(FetchContent) + # Fetch GoogleTest FetchContent_Declare( googletest @@ -29,12 +36,15 @@ if(OPTIONAL26_ENABLE_TESTING) e39786088138f2749d64e9e90e0f9902daa77c40 # release-1.15.0 ) FetchContent_MakeAvailable(googletest) + + enable_testing() endif() set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ON) # Create the library target and named header set for beman_optional26 add_library(beman_optional26 INTERFACE) +add_library(Beman::Optional26::beman_optional26 ALIAS beman_optional26) target_sources( beman_optional26 PUBLIC FILE_SET beman_optional26_headers TYPE HEADERS BASE_DIRS include @@ -59,23 +69,24 @@ add_subdirectory(include/beman/optional26) add_subdirectory(examples) -include(CMakePackageConfigHelpers) +# install +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}-config-version.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion +) -# This will be used to replace @PACKAGE_cmakeModulesDir@ -set(cmakeModulesDir cmake/beman) configure_package_config_file( cmake/Config.cmake.in - BemanOptional26Config.cmake - INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/beman/optional26/ - PATH_VARS cmakeModulesDir - NO_SET_AND_CHECK_MACRO - NO_CHECK_REQUIRED_COMPONENTS_MACRO + ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}-config.cmake + INSTALL_DESTINATION ${INSTALL_CONFIGDIR} ) install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/BemanOptional26Config.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/beman/optional26/ - COMPONENT beman_optional26_development + FILES + ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}-config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}-config-version.cmake + DESTINATION ${INSTALL_CONFIGDIR} ) # Coverage @@ -87,4 +98,5 @@ add_custom_target( COMMENT "Running gcovr to process coverage results" COMMAND mkdir -p coverage COMMAND gcovr --config gcovr.cfg . + DEPENDS test ) diff --git a/CMakePresets.json b/CMakePresets.json index 42d3d6c4..7e176ad2 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -14,7 +14,17 @@ "binaryDir": "${sourceDir}/.build/${presetName}", "installDir": "${sourceDir}/.install/${presetName}", "cacheVariables": { - "CMAKE_CONFIGURATION_TYPES": "RelWithDebInfo;Debug;Tsan;Asan" + "CMAKE_PREFIX_PATH": { + "type": "path", + "value": "${sourceDir}/.install/${presetName}" + }, + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_CONFIGURATION_TYPES": "RelWithDebInfo;Debug;Tsan;Asan", + "CMAKE_CXX_EXTENSIONS": false, + "CMAKE_CXX_STANDARD": "20", + "CMAKE_CXX_STANDARD_REQUIRED": true, + "CMAKE_EXPORT_COMPILE_COMMANDS": true, + "CMAKE_SKIP_TEST_ALL_DEPENDENCY": false } }, { @@ -85,38 +95,27 @@ { "name": "common", "hidden": true, - "configuration": "Asan", + "configuration": "Debug", "targets": [ "all_verify_interface_header_sets", - "all" + "all", + "install" ] }, { "name": "system", "inherits": "common", - "configurePreset": "system", - "targets": [ - "all_verify_interface_header_sets", - "all" - ] + "configurePreset": "system" }, { "name": "gcc-14", "inherits": "common", - "configurePreset": "gcc-14", - "targets": [ - "all_verify_interface_header_sets", - "all" - ] + "configurePreset": "gcc-14" }, { "name": "gcc-13", "inherits": "common", - "configurePreset": "gcc-13", - "targets": [ - "all_verify_interface_header_sets", - "all" - ] + "configurePreset": "gcc-13" }, { "name": "gcc-12", @@ -131,45 +130,29 @@ { "name": "clang-19", "inherits": "common", - "configurePreset": "clang-19", - "targets": [ - "all_verify_interface_header_sets", - "all" - ] + "configurePreset": "clang-19" }, { "name": "clang-18", "inherits": "common", - "configurePreset": "clang-18", - "targets": [ - "all_verify_interface_header_sets", - "all" - ] + "configurePreset": "clang-18" }, { "name": "clang-17", "inherits": "common", - "configurePreset": "clang-17", - "targets": [ - "all_verify_interface_header_sets", - "all" - ] + "configurePreset": "clang-17" }, { "name": "clang-16", "inherits": "common", "configurePreset": "clang-16" - "targets": [ - "all_verify_interface_header_sets", - "all" - ] } ], "testPresets": [ { "name": "common", "hidden": true, - "configuration": "Asan", + "configuration": "Debug", "output": { "outputOnFailure": true }, diff --git a/README.md b/README.md index 0919c27d..df5e9d4d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ SPDX-License-Identifier: 2.0 license with LLVM exceptions --> -![CI Tests](https://github.com/bemanproject/optional26/actions/workflows/ci.yml/badge.svg) +![CI Tests](https://github.com/bemanproject/optional26/actions/workflows/ci.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/bemanproject/optional26/badge.svg?branch=main)](https://coveralls.io/github/bemanproject/optional26?branch=main) This repository implements `std::optional` extensions targeting C++26. The `beman.optional26` library aims to evaluate the stability, the usability, and the performance of these proposed changes before they are officially adopted by WG21 @@ -141,7 +141,7 @@ apt-get install -y cmake make ninja-build # Example of toolchains: apt-get install \ - g++-14 gcc-14 gcc-13 g++-14 \ + g++-14 gcc-14 gcc-13 g++-13 \ clang-18 clang++-18 clang-17 clang++-17 ``` @@ -162,8 +162,12 @@ Available workflow presets: "system" "gcc-14" "gcc-13" + "gcc-12" + "clang-20" + "clang-19" "clang-18" "clang-17" + "clang-16" # Run examples: $ cmake --workflow --preset gcc-14 diff --git a/cmake/gcovr.cfg.in b/cmake/gcovr.cfg.in index 7dddd998..6b2523df 100644 --- a/cmake/gcovr.cfg.in +++ b/cmake/gcovr.cfg.in @@ -9,3 +9,5 @@ html-self-contained = yes print-summary = yes filter = .*/beman/optional26/.* exclude = .*\.t\.cpp +coveralls = coverage.json +coveralls-pretty = yes diff --git a/etc/clang-flags.cmake b/etc/clang-flags.cmake index 5b23bf7a..2f651cf7 100644 --- a/etc/clang-flags.cmake +++ b/etc/clang-flags.cmake @@ -1,6 +1,6 @@ include_guard(GLOBAL) -set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_FLAGS "-stdlib=libc++ -Wall -Wextra " diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b94bbaba..a2d10a43 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -3,9 +3,15 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # cmake-format: on -set(BEMAN_OPTIONAL26_LIBRARY "beman_optional26") +cmake_minimum_required(VERSION 3.29...3.31) -include(GNUInstallDirs) +project(beman_optional26_example VERSION 0.0.1 LANGUAGES CXX) + +set(BEMAN_OPTIONAL26_LIBRARY "Beman::Optional26::beman_optional26") + +if(PROJECT_IS_TOP_LEVEL) + find_package(beman_optional26 0.0.1 EXACT REQUIRED) +endif() # List of all buildable examples. set(EXAMPLES @@ -27,13 +33,15 @@ foreach(example ${EXAMPLES}) # Link example with the library. target_link_libraries(${example} "${BEMAN_OPTIONAL26_LIBRARY}") - # Install . - install( - TARGETS - ${example} - COMPONENT - beman_optional26_examples - DESTINATION - ${CMAKE_INSTALL_BINDIR} - ) + if(NOT PROJECT_IS_TOP_LEVEL) + # Install . + install( + TARGETS + ${example} + COMPONENT + beman_optional26_examples + DESTINATION + ${CMAKE_INSTALL_BINDIR} + ) + endif() endforeach() diff --git a/include/beman/optional26/CMakeLists.txt b/include/beman/optional26/CMakeLists.txt index e43fc935..e4c2028a 100644 --- a/include/beman/optional26/CMakeLists.txt +++ b/include/beman/optional26/CMakeLists.txt @@ -33,9 +33,9 @@ install( install( EXPORT beman_optional26_export - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/beman/optional26/ + DESTINATION ${INSTALL_CONFIGDIR} NAMESPACE Beman::Optional26:: - FILE beman_optional26.cmake + FILE beman_optional26-config-targets.cmake EXPORT_LINK_INTERFACE_LIBRARIES COMPONENT beman_optional26_development ) diff --git a/src/beman/optional26/tests/CMakeLists.txt b/src/beman/optional26/tests/CMakeLists.txt index 5a2c1ad8..2996ddab 100644 --- a/src/beman/optional26/tests/CMakeLists.txt +++ b/src/beman/optional26/tests/CMakeLists.txt @@ -29,7 +29,7 @@ target_sources( target_link_libraries( beman_optional26_test - PRIVATE beman_optional26 GTest::gtest GTest::gtest_main + PRIVATE Beman::Optional26::beman_optional26 GTest::gtest GTest::gtest_main ) # Issue #32: Re-enable ASAN run CI/clang-19. @@ -41,7 +41,10 @@ gtest_add_tests(TARGET beman_optional26_test "" AUTO) add_library(constructor_fails test_constructor_fail.cpp) -target_link_libraries(constructor_fails PRIVATE beman_optional26) +target_link_libraries( + constructor_fails + PRIVATE Beman::Optional26::beman_optional26 +) set_target_properties( constructor_fails @@ -59,3 +62,21 @@ set_tests_properties(constructor_fails PROPERTIES WILL_FAIL true) # Alternatively -- check for a particular regex to pass # set_tests_properties(constructor_fails PROPERTIES PASS_REGULAR_EXPRESSION # "Assert true") + +# test if the targets are findable from the build directory +if(CMAKE_BUILD_TYPE STREQUAL Debug) + add_test( + NAME find-package-test + COMMAND + ${CMAKE_CTEST_COMMAND} + # --verbose + --output-on-failure -C $ --build-and-test + "${PROJECT_SOURCE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}/find-package-test" --build-generator + ${CMAKE_GENERATOR} --build-makeprogram ${CMAKE_MAKE_PROGRAM} + --build-options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" + "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" + "-DCMAKE_BUILD_TYPE=$" + "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" + ) +endif()