diff --git a/.clang-format b/.clang-format index 01d5fac..74f95dc 100644 --- a/.clang-format +++ b/.clang-format @@ -85,6 +85,7 @@ BreakBeforeTernaryOperators: true BreakConstructorInitializers: BeforeColon BreakInheritanceList: BeforeColon BreakStringLiterals: true +# Please update .markdownlint.yaml if this line is to be updated ColumnLimit: 119 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false @@ -124,7 +125,7 @@ IndentCaseBlocks: false IndentCaseLabels: false IndentExternBlock: AfterExternBlock IndentGotoLabels: true -IndentPPDirectives: None +IndentPPDirectives: BeforeHash IndentRequiresClause: true IndentWidth: 4 IndentWrappedFunctionNames: false diff --git a/.cmake-format.json b/.cmake-format.json deleted file mode 100644 index f5120cc..0000000 --- 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/.codespellignore b/.codespellignore deleted file mode 100644 index e69de29..0000000 diff --git a/.exemplar_version b/.exemplar_version new file mode 100644 index 0000000..447909a --- /dev/null +++ b/.exemplar_version @@ -0,0 +1 @@ +ab5c7c0cbf1f67eb43b7be9c2d18acd4d6de1ea4 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..793dce7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +infra/** linguist-vendored +cookiecutter/** linguist-vendored +*.bib -linguist-detectable +*.tex -linguist-detectable +papers/* linguist-documentation diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9679d20..3956e64 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,5 +1,3 @@ -# .github/CODEOWNERS # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# Codeowners for reviews on PRs -* @camio @neatudarius @steve-downey @RaduNichita +* @steve-downey diff --git a/.github/ISSUE_TEMPLATE/implementation-deficiency.md b/.github/ISSUE_TEMPLATE/implementation-deficiency.md new file mode 100644 index 0000000..4a0ee77 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/implementation-deficiency.md @@ -0,0 +1,35 @@ +--- +name: Implementation Deficiency +about: Report a bug or performance issue of our implementation +title: '' +labels: bug +assignees: '' + +--- + + + +## Describe the deficiency + +A clear and concise description of what the deficiency is. +Link all relevant issues. +This could be a bug, or a performance problem. + +## To Reproduce + +```c++ +// Use case +``` + +## Expected Behavior + +A clear and concise description of what you expected to happen. + +## Additional Discussions + +Add any other context about the problem here. +If you believe your issue is platform dependent, +please post your compiler versions here. diff --git a/.github/ISSUE_TEMPLATE/infrastructure-issues.md b/.github/ISSUE_TEMPLATE/infrastructure-issues.md new file mode 100644 index 0000000..11fbd13 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/infrastructure-issues.md @@ -0,0 +1,29 @@ +--- +name: Infrastructure Issues +about: Report a bug or feature request with our Infrastructure +title: '' +labels: infra +assignees: '' + +--- + + + +## I am attempting to + +Describe what you were attempting to do. + +## Expected Behavior + +A clear and concise description of what you expected to happen. + +## Current Behavior + +A clear and concise description of what actually happened. + +## Additional Discussions + +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/paper-discussion.md b/.github/ISSUE_TEMPLATE/paper-discussion.md new file mode 100644 index 0000000..14c9e4f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/paper-discussion.md @@ -0,0 +1,33 @@ +--- +name: Paper Discussion +about: Provide feedback to current API +title: '' +labels: '' +assignees: '' + +--- + + + +## Use case + +Describe your concerns about adding this change to the C++ Standard Library. + +```c++ +// example snippet +``` + +## What I like + +Let us know what you find positive about current approach / design. + +## What I dislike + +Let us know what you find negative about current approach / design. + +## Discussion + +Let us know if you have any more remarks. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..071cb28 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,5 @@ + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index d8460cf..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,91 +0,0 @@ -# .github/workflows/ci.yml -*-yaml-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: CI Tests -on: - workflow_dispatch: - push: - branches: [main] - pull_request: - branches: [main] -jobs: - build: - name: ${{ matrix.config.name }} - runs-on: ${{ matrix.config.os }} - strategy: - 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\" "} - # 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\" "} - - steps: - - uses: actions/checkout@v4 - with: - submodules: 'true' - - name: Activate verbose shell - run: set -x - - name: Install LLVM+Clang - if: startsWith(matrix.config.name, 'Ubuntu Clang') - run: | - # Remove existing Clang installations. - sudo apt-get remove \ - clang-${{matrix.config.installed_clang_version}} \ - clang++-${{matrix.config.installed_clang_version}} \ - clangd-${{matrix.config.installed_clang_version}} \ - clang-tidy-${{matrix.config.installed_clang_version}} \ - clang-format-${{matrix.config.installed_clang_version}} \ - clang-tools-${{matrix.config.installed_clang_version}} \ - llvm-${{matrix.config.installed_clang_version}}-dev \ - lld-${{matrix.config.installed_clang_version}} \ - lldb-${{matrix.config.installed_clang_version}} \ - llvm-${{matrix.config.installed_clang_version}}-tools \ - libc++-${{matrix.config.installed_clang_version}}-dev \ - libc++abi-${{matrix.config.installed_clang_version}}-dev \ - libclang-common-${{matrix.config.installed_clang_version}}-dev \ - libclang-${{matrix.config.installed_clang_version}}-dev \ - libclang-cpp${{matrix.config.installed_clang_version}}-dev \ - libomp-${{matrix.config.installed_clang_version}}-dev \ - libunwind-${{matrix.config.installed_clang_version}}-dev \ - libc++-dev libc++1 libc++abi-dev libc++abi1 - # Install LLVM+Clang. - CLANG_VERSION=$(echo ${{matrix.config.toolchain}} | cut -d '-' -f2) - wget https://apt.llvm.org/llvm.sh - chmod +x llvm.sh - sudo ./llvm.sh ${CLANG_VERSION} all - # Link Clang libraries (if not done by llvm.sh - some links are already set). - sudo ln -fs /usr/lib/llvm-${CLANG_VERSION}/lib/lib* /usr/lib/x86_64-linux-gnu/ || true - # If Clang 17, install a newer version of libc++ and libc++abi. - [[ ${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 - - name: Install GCC - if: startsWith(matrix.config.name, 'Ubuntu GCC') - run: | - # Remove existing GCC installations. - sudo apt-get remove gcc-13 g++-13 gcc-14 g++-14 gcc g++ - sudo apt update - # Install GCC. - GCC_VERSION=$(echo ${{matrix.config.toolchain}} | cut -d '-' -f2) - echo "GCC_VERSION=$GCC_VERSION" - sudo apt-get install g++-${GCC_VERSION} gcc-${GCC_VERSION} - find /usr/lib/x86_64-linux-gnu/ -name libstdc++.so* - g++-${GCC_VERSION} --version - - name: CMake Configure - run: | - echo ${{ matrix.config.cmake_args }} - echo ${{ matrix.config.toolchain }} - cmake ${{ matrix.config.cmake_args }} -DCMAKE_TOOLCHAIN_FILE="etc/${{ matrix.config.toolchain }}-toolchain.cmake" -B .build -S . - - name: CMake Build - run: | - cmake --build .build --config Asan --target all -- -k 0 - - name: CMake Test - run: | - [[ ! -z "${{ matrix.config.asan_options }}" ]] && export ASAN_OPTIONS="${{ matrix.config.asan_options }}" - ctest --build-config Asan --output-on-failure --test-dir .build diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml new file mode 100644 index 0000000..431f009 --- /dev/null +++ b/.github/workflows/ci_tests.yml @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +name: Continuous Integration Tests + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + schedule: + - cron: '32 15 * * 4' + +jobs: + beman-submodule-check: + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-submodule-check.yml@1.5.3 + + preset-test: + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.5.3 + with: + matrix_config: > + [ + {"preset": "gcc-debug", "image": "ghcr.io/bemanproject/infra-containers-gcc:latest"}, + {"preset": "gcc-release", "image": "ghcr.io/bemanproject/infra-containers-gcc:latest"}, + {"preset": "llvm-debug", "image": "ghcr.io/bemanproject/infra-containers-clang:latest"}, + {"preset": "llvm-release", "image": "ghcr.io/bemanproject/infra-containers-clang:latest"} + ] + + build-and-test: + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-build-and-test.yml@1.5.3 + with: + matrix_config: > + { + "gcc": [ + { "versions": ["14"], + "tests": [ + { "cxxversions": ["c++26"], + "tests": [ + { "stdlibs": ["libstdc++"], + "tests": [ + "Debug.Default", "Release.Default", "Release.TSan", + "Release.MaxSan", "Debug.Werror", + "Debug.Coverage" + ] + } + ] + }, + { "cxxversions": ["c++23", "c++20"], + "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] + } + ] + }, + { "versions": ["13"], + "tests": [ + { "cxxversions": ["c++26", "c++23", "c++20"], + "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] + } + ] + }, + { + "versions": ["12"], + "tests": [ + { "cxxversions": ["c++23", "c++20"], + "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] + } + ] + } + ], + "clang": [ + { "versions": ["22"], + "tests": [ + {"cxxversions": ["c++26"], + "tests": [ + { "stdlibs": ["libstdc++", "libc++"], + "tests": [ + "Debug.Default", "Release.Default", "Release.TSan", + "Release.MaxSan", "Debug.Werror" + ] + } + ] + }, + { "cxxversions": ["c++23", "c++20"], + "tests": [ + {"stdlibs": ["libstdc++", "libc++"], "tests": ["Release.Default"]} + ] + } + ] + }, + { "versions": ["21", "20", "19"], + "tests": [ + { "cxxversions": ["c++26", "c++23", "c++20"], + "tests": [ + {"stdlibs": ["libstdc++", "libc++"], "tests": ["Release.Default"]} + ] + } + ] + }, + { "versions": ["18"], + "tests": [ + { "cxxversions": ["c++26", "c++23", "c++20"], + "tests": [{"stdlibs": ["libc++"], "tests": ["Release.Default"]}] + }, + { "cxxversions": ["c++23", "c++20"], + "tests": [{"stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] + } + ] + }, + { "versions": ["17"], + "tests": [ + { "cxxversions": ["c++26", "c++23", "c++20"], + "tests": [{"stdlibs": ["libc++"], "tests": ["Release.Default"]}] + }, + { "cxxversions": ["c++20"], + "tests": [{"stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] + } + ] + } + ] + } + + create-issue-when-fault: + needs: [preset-test, build-and-test] + if: failure() && github.event_name == 'schedule' + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-create-issue-when-fault.yml@1.5.3 diff --git a/.github/workflows/pre-commit-check.yml b/.github/workflows/pre-commit-check.yml new file mode 100644 index 0000000..980f6c5 --- /dev/null +++ b/.github/workflows/pre-commit-check.yml @@ -0,0 +1,19 @@ +name: Lint Check (pre-commit) + +on: + # We have to use pull_request_target here as pull_request does not grant + # enough permission for reviewdog + pull_request_target: + push: + branches: + - main + +permissions: + contents: read + checks: write + issues: write + pull-requests: write + +jobs: + pre-commit: + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-pre-commit.yml@1.5.3 diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml new file mode 100644 index 0000000..f21cd86 --- /dev/null +++ b/.github/workflows/pre-commit-update.yml @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +name: Weekly pre-commit autoupdate + +on: + workflow_dispatch: + schedule: + - cron: "45 17 * * 3" + +jobs: + auto-update-pre-commit: + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-update-pre-commit.yml@1.5.3 + secrets: + APP_ID: ${{ secrets.AUTO_PR_BOT_APP_ID }} + PRIVATE_KEY: ${{ secrets.AUTO_PR_BOT_PRIVATE_KEY }} diff --git a/.gitignore b/.gitignore index 89944aa..d293e3b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,27 +1,12 @@ -cmake.bld -compile_commands.json -/.build/ -/.cache/ -*.pyg -/.vscode/ -/papers/**/generated/ -/papers/**/.venv/ -/papers/**/_minted-*/ -/papers/**/*.aux -/papers/**/*.bbl -/papers/**/*.blg -/papers/**/*.dvi -/papers/**/*.fdb_latexmk -/papers/**/*.fls -/papers/**/*.log -/papers/**/*.out -/papers/**/*.pdf -/papers/**/*.toc -/papers/**/*.idx -/papers/**/*.xtr -/papers/**/.deps/ -/papers/**/_minted-view-maybe.work/ -/papers/**/.venv.work/ -/papers/**/_minted-optional_ref/ -/papers/**/_minted-optional_ref_wording/ -.update-submodules +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +/.cache +/compile_commands.json +/build + +# ignore emacs temp files +*~ +\#*\# + +# ignore vscode settings +.vscode diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29..0000000 diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..21c2849 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,10 @@ +# MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md033.md +# Disable inline html linter is needed for
+MD033: false + +# MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md013.md +# Conforms to .clang-format ColumnLimit +# Update the comment in .clang-format if we no-longer tie these two column limits. +MD013: + line_length: 119 + code_blocks: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a241b6e..eb01186 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,44 +2,47 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml - - id: check-added-large-files + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files # Clang-format for C++ # This brings in a portable version of clang-format. # See also: https://github.com/ssciwr/clang-format-wheel - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v19.1.4 + rev: v22.1.4 hooks: - - id: clang-format - types_or: [c++, c] + - id: clang-format + types_or: [c++, c] # CMake linting and formatting - - repo: https://github.com/BlankSpruce/gersemi - rev: 0.17.1 + - repo: https://github.com/BlankSpruce/gersemi-pre-commit + rev: 0.27.2 hooks: - - id: gersemi - name: CMake linting + - id: gersemi + name: CMake linting + exclude: ^.*/tests/.*/data/ # Exclude test data directories # Markdown linting # Config file: .markdownlint.yaml - - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.43.0 - hooks: - - id: markdownlint + # Commented out to disable this by default. Uncomment to enable markdown linting. + # - repo: https://github.com/igorshubovych/markdownlint-cli + # rev: v0.42.0 + # hooks: + # - id: markdownlint - repo: https://github.com/codespell-project/codespell - rev: v2.3.0 + rev: v2.4.2 hooks: - id: codespell - files: ^.*\.(cmake|cpp|hpp|txt|md|json|in|yaml|yml)$ - args: ["--ignore-words", ".codespellignore" ] + # Beman Standard checking via beman-tidy - repo: https://github.com/bemanproject/beman-tidy rev: v0.3.1 hooks: - - id: beman-tidy + - id: beman-tidy + +exclude: 'cookiecutter/|infra/' diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b0d091..1a761d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,40 +1,41 @@ -# cmake-format: off -# CMakeLists.txt -*-CMake-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on -cmake_minimum_required(VERSION 3.27...3.31) +cmake_minimum_required(VERSION 3.30...4.3) -project(beman.iterator_interface VERSION 0.0.0 LANGUAGES CXX) +project( + beman.iterator_interface # CMake Project Name, which is also the name of the top-level + # targets (e.g., library, executable, etc.). + DESCRIPTION "iterator creation mechanisms" + LANGUAGES CXX + VERSION 0.1.0 +) # Local helpers: required to include CompilerFeatureTest. list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") # Includes -include(CTest) -include(FetchContent) include(CompilerFeatureTest) # Prechecks. beman_iterator_check_deducing_this(COMPILER_SUPPORTS_DEDUCING_THIS) -set(TARGETS_EXPORT_NAME ${CMAKE_PROJECT_NAME}Targets) - option( BEMAN_ITERATOR_INTERFACE_USE_DEDUCING_THIS "Make use of C++23 \"deducing this\" feature (P0847R7). Turn this off for non-conforming compilers." ${COMPILER_SUPPORTS_DEDUCING_THIS} ) +# [CMAKE.SKIP_TESTS] option( BEMAN_ITERATOR_INTERFACE_BUILD_TESTS - "Enable building tests and test infrastructure. Default: ON. Values: {ON, OFF}." + "Enable building tests and test infrastructure. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." ${PROJECT_IS_TOP_LEVEL} ) +# [CMAKE.SKIP_EXAMPLES] option( BEMAN_ITERATOR_INTERFACE_BUILD_EXAMPLES - "Enable building examples. Default: ON. Values: {ON, OFF}." + "Enable building examples. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." ${PROJECT_IS_TOP_LEVEL} ) @@ -44,7 +45,7 @@ if( ) message( WARNING - "Building with C++23 \"deducing this\" feature (P0847R7) despite of the compiler's lack of actual support for it." + "Building with C++23 \"deducing this\" feature (P0847R7) despite of the compiler's lack of actual support for it." ) endif() @@ -54,34 +55,32 @@ configure_file( @ONLY ) -if(BEMAN_ITERATOR_INTERFACE_BUILD_TESTS) - # Fetch GoogleTest - FetchContent_Declare( - googletest - EXCLUDE_FROM_ALL - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG - e39786088138f2749d64e9e90e0f9902daa77c40 # release-1.15.0 - ) - FetchContent_MakeAvailable(googletest) -endif() +# for find of beman_install_library and configure_build_telemetry +include(infra/cmake/beman-install-library.cmake) +include(infra/cmake/BuildTelemetryConfig.cmake) -# Create the library target and named header set for beman.iterator_interface -add_library(beman.iterator_interface STATIC) +add_library(beman.iterator_interface INTERFACE) add_library(beman::iterator_interface ALIAS beman.iterator_interface) target_sources( beman.iterator_interface PUBLIC - FILE_SET beman_iterator_interface_headers - TYPE HEADERS - BASE_DIRS ${PROJECT_BINARY_DIR}/include ${PROJECT_SOURCE_DIR}/include - FILES ${PROJECT_BINARY_DIR}/include/beman/iterator_interface/config.hpp + FILE_SET HEADERS + BASE_DIRS + "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${PROJECT_BINARY_DIR}/include" +) + +set_target_properties( + beman.iterator_interface + PROPERTIES VERIFY_INTERFACE_HEADER_SETS ${PROJECT_IS_TOP_LEVEL} ) -add_subdirectory(src/beman/iterator_interface) add_subdirectory(include/beman/iterator_interface) +beman_install_library(beman.iterator_interface TARGETS beman.iterator_interface) +configure_build_telemetry() + if(BEMAN_ITERATOR_INTERFACE_BUILD_TESTS) enable_testing() add_subdirectory(tests/beman/iterator_interface) @@ -90,14 +89,3 @@ endif() if(BEMAN_ITERATOR_INTERFACE_BUILD_EXAMPLES) add_subdirectory(examples) endif() - -# Coverage -configure_file("cmake/gcovr.cfg.in" gcovr.cfg @ONLY) - -add_custom_target( - process_coverage - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Running gcovr to process coverage results" - COMMAND mkdir -p coverage - COMMAND gcovr --config gcovr.cfg . -) diff --git a/CMakePresets.json b/CMakePresets.json index ddf75df..483e1a3 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -5,16 +5,19 @@ "name": "_root-config", "hidden": true, "generator": "Ninja", - "binaryDir": "${sourceDir}/.build/${presetName}", + "binaryDir": "${sourceDir}/build/${presetName}", "cacheVariables": { - "CMAKE_CXX_STANDARD": "20" + "CMAKE_CXX_STANDARD": "20", + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", + "CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "./infra/cmake/use-fetch-content.cmake" } }, { "name": "_debug-base", "hidden": true, "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug" + "CMAKE_BUILD_TYPE": "Debug", + "BEMAN_BUILDSYS_SANITIZER": "MaxSan" } }, { @@ -32,7 +35,7 @@ "_debug-base" ], "cacheVariables": { - "CMAKE_CXX_COMPILER": "g++" + "CMAKE_TOOLCHAIN_FILE": "infra/cmake/gnu-toolchain.cmake" } }, { @@ -43,18 +46,137 @@ "_release-base" ], "cacheVariables": { - "CMAKE_CXX_COMPILER": "g++" + "CMAKE_TOOLCHAIN_FILE": "infra/cmake/gnu-toolchain.cmake" + } + }, + { + "name": "llvm-debug", + "displayName": "Clang Debug Build", + "inherits": [ + "_root-config", + "_debug-base" + ], + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "infra/cmake/llvm-toolchain.cmake" + } + }, + { + "name": "llvm-release", + "displayName": "Clang Release Build", + "inherits": [ + "_root-config", + "_release-base" + ], + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "infra/cmake/llvm-toolchain.cmake" + } + }, + { + "name": "appleclang-debug", + "displayName": "Appleclang Debug Build", + "inherits": [ + "_root-config", + "_debug-base" + ], + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "infra/cmake/appleclang-toolchain.cmake" + } + }, + { + "name": "appleclang-release", + "displayName": "Appleclang Release Build", + "inherits": [ + "_root-config", + "_release-base" + ], + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "infra/cmake/appleclang-toolchain.cmake" + } + }, + { + "name": "msvc-debug", + "displayName": "MSVC Debug Build", + "inherits": [ + "_root-config", + "_debug-base" + ], + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "infra/cmake/msvc-toolchain.cmake" + } + }, + { + "name": "msvc-release", + "displayName": "MSVC Release Build", + "inherits": [ + "_root-config", + "_release-base" + ], + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "infra/cmake/msvc-toolchain.cmake" } } ], "buildPresets": [ + { + "name": "_root-build", + "hidden": true, + "jobs": 0 + }, { "name": "gcc-debug", - "configurePreset": "gcc-debug" + "configurePreset": "gcc-debug", + "inherits": [ + "_root-build" + ] }, { "name": "gcc-release", - "configurePreset": "gcc-release" + "configurePreset": "gcc-release", + "inherits": [ + "_root-build" + ] + }, + { + "name": "llvm-debug", + "configurePreset": "llvm-debug", + "inherits": [ + "_root-build" + ] + }, + { + "name": "llvm-release", + "configurePreset": "llvm-release", + "inherits": [ + "_root-build" + ] + }, + { + "name": "appleclang-debug", + "configurePreset": "appleclang-debug", + "inherits": [ + "_root-build" + ] + }, + { + "name": "appleclang-release", + "configurePreset": "appleclang-release", + "inherits": [ + "_root-build" + ] + }, + { + "name": "msvc-debug", + "configurePreset": "msvc-debug", + "inherits": [ + "_root-build" + ] + }, + { + "name": "msvc-release", + "configurePreset": "msvc-release", + "inherits": [ + "_root-build" + ] } ], "testPresets": [ @@ -78,6 +200,36 @@ "name": "gcc-release", "inherits": "_test_base", "configurePreset": "gcc-release" + }, + { + "name": "llvm-debug", + "inherits": "_test_base", + "configurePreset": "llvm-debug" + }, + { + "name": "llvm-release", + "inherits": "_test_base", + "configurePreset": "llvm-release" + }, + { + "name": "appleclang-debug", + "inherits": "_test_base", + "configurePreset": "appleclang-debug" + }, + { + "name": "appleclang-release", + "inherits": "_test_base", + "configurePreset": "appleclang-release" + }, + { + "name": "msvc-debug", + "inherits": "_test_base", + "configurePreset": "msvc-debug" + }, + { + "name": "msvc-release", + "inherits": "_test_base", + "configurePreset": "msvc-release" } ], "workflowPresets": [ @@ -114,6 +266,108 @@ "name": "gcc-release" } ] + }, + { + "name": "llvm-debug", + "steps": [ + { + "type": "configure", + "name": "llvm-debug" + }, + { + "type": "build", + "name": "llvm-debug" + }, + { + "type": "test", + "name": "llvm-debug" + } + ] + }, + { + "name": "llvm-release", + "steps": [ + { + "type": "configure", + "name": "llvm-release" + }, + { + "type": "build", + "name": "llvm-release" + }, + { + "type": "test", + "name": "llvm-release" + } + ] + }, + { + "name": "appleclang-debug", + "steps": [ + { + "type": "configure", + "name": "appleclang-debug" + }, + { + "type": "build", + "name": "appleclang-debug" + }, + { + "type": "test", + "name": "appleclang-debug" + } + ] + }, + { + "name": "appleclang-release", + "steps": [ + { + "type": "configure", + "name": "appleclang-release" + }, + { + "type": "build", + "name": "appleclang-release" + }, + { + "type": "test", + "name": "appleclang-release" + } + ] + }, + { + "name": "msvc-debug", + "steps": [ + { + "type": "configure", + "name": "msvc-debug" + }, + { + "type": "build", + "name": "msvc-debug" + }, + { + "type": "test", + "name": "msvc-debug" + } + ] + }, + { + "name": "msvc-release", + "steps": [ + { + "type": "configure", + "name": "msvc-release" + }, + { + "type": "build", + "name": "msvc-release" + }, + { + "type": "test", + "name": "msvc-release" + } + ] } ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6cc5192 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,111 @@ +# Development + +## Configure and Build the Project Using CMake Presets + +The simplest way of configuring and building the project is to use [CMake +Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html). Appropriate +presets for major compilers have been included by default. You can use `cmake +--list-presets=workflow` to see all available presets. + +Here is an example of invoking the `gcc-debug` preset: + +```shell +cmake --workflow --preset gcc-debug +``` + +Generally, there are two kinds of presets, `debug` and `release`. + +The `debug` presets are designed to aid development, so they have debuginfo and sanitizers +enabled. + +> [!NOTE] +> +> The sanitizers that are enabled vary from compiler to compiler. See the toolchain files +> under ([`infra/cmake`](infra/cmake/)) to determine the exact configuration used for each +> preset. + +The `release` presets are designed for production use, and +consequently have the highest optimization turned on (e.g. `O3`). + +## Configure and Build Manually + +If the presets are not suitable for your use case, a traditional CMake invocation will +provide more configurability. + +To configure, build and test the project manually, you can run this set of commands. Note +that this requires GoogleTest to be installed. + +```bash +cmake \ + -B build \ + -S . \ + -DCMAKE_CXX_STANDARD=20 \ + # Your extra arguments here. +cmake --build build +ctest --test-dir build +``` + +> [!IMPORTANT] +> +> Beman projects are [passive projects]( +> https://github.com/bemanproject/beman/blob/main/docs/beman_standard.md#cmakepassive_projects), +> so you need to specify the C++ version via `CMAKE_CXX_STANDARD` when manually +> configuring the project. + +## Dependency Management + +### FetchContent + +Instead of installing the project's dependencies via a package manager, you can optionally +configure beman.iterator_interface to fetch them automatically via CMake FetchContent. + +To do so, specify +`-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake`. This will +bring in GoogleTest automatically along with any other dependency the project may require. + +Example commands: + +```shell +cmake \ + -B build \ + -S . \ + -DCMAKE_CXX_STANDARD=20 \ + -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake +cmake --build build +ctest --test-dir build +``` + +The file `./lockfile.json` configures the list of dependencies and versions that will be +acquired by FetchContent. + +## Project-specific configure arguments + +Project-specific options are prefixed with `BEMAN_ITERATOR_INTERFACE`. +You can see the list of available options with: + +```bash +cmake -LH -S . -B build | grep "BEMAN_ITERATOR_INTERFACE" -C 2 +``` + +
+ +Some project-specific configure arguments + +### `BEMAN_ITERATOR_INTERFACE_BUILD_TESTS` + +Enable building tests and test infrastructure. Default: `ON`. +Values: `{ ON, OFF }`. + +### `BEMAN_ITERATOR_INTERFACE_BUILD_EXAMPLES` + +Enable building examples. Default: `ON`. Values: `{ ON, OFF }`. + +### `BEMAN_ITERATOR_INTERFACE_INSTALL_CONFIG_FILE_PACKAGE` + +Enable installing the CMake config file package. Default: `ON`. +Values: `{ ON, OFF }`. + +This is required so that users of `beman.iterator_interface` can use +`find_package(beman.iterator_interface)` to locate the library. + +
diff --git a/Makefile b/Makefile deleted file mode 100644 index f675d76..0000000 --- a/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -#! /usr/bin/make -f -# /Makefile -*-makefile-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -INSTALL_PREFIX?=.install/ -PROJECT?=$(shell basename $(CURDIR)) -BUILD_DIR?=.build -DEST?=$(INSTALL_PREFIX) -CMAKE_FLAGS?= - -TARGETS := test clean all ctest - -export - -.update-submodules: - git submodule update --init --recursive - touch .update-submodules - -.gitmodules: .update-submodules - -CONFIG?=Asan - -export - -ifeq ($(strip $(TOOLCHAIN)),) - _build_name?=build-system/ - _build_dir?=.build/ - _configuration_types?="RelWithDebInfo;Debug;Tsan;Asan" - _cmake_args=-DCMAKE_TOOLCHAIN_FILE=$(CURDIR)/etc/toolchain.cmake -else - _build_name?=build-$(TOOLCHAIN) - _build_dir?=.build/ - _configuration_types?="RelWithDebInfo;Debug;Tsan;Asan" - _cmake_args=-DCMAKE_TOOLCHAIN_FILE=$(CURDIR)/etc/$(TOOLCHAIN)-toolchain.cmake -endif - - -_build_path?=$(_build_dir)/$(_build_name) - -define run_cmake = - cmake \ - -G "Ninja Multi-Config" \ - -DCMAKE_CONFIGURATION_TYPES=$(_configuration_types) \ - -DCMAKE_INSTALL_PREFIX=$(abspath $(INSTALL_PREFIX)) \ - -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ - $(_cmake_args) \ - $(CURDIR) -endef - -default: test - -$(_build_path): - mkdir -p $(_build_path) - -$(_build_path)/CMakeCache.txt: | $(_build_path) .gitmodules - cd $(_build_path) && $(run_cmake) - -rm compile_commands.json - ln -s $(_build_path)/compile_commands.json - -compile: $(_build_path)/CMakeCache.txt ## Compile the project - cmake --build $(_build_path) --config $(CONFIG) --target all -- -k 0 - -install: $(_build_path)/CMakeCache.txt ## Install the project - DESTDIR=$(abspath $(DEST)) ninja -C $(_build_path) -k 0 install - -ctest: $(_build_path)/CMakeCache.txt ## Run CTest on current build - cd $(_build_path) && ctest --output-on-failure - -ctest_ : compile - cd $(_build_path) && ctest --output-on-failure - -test: ctest_ ## Rebuild and run tests - -cmake: | $(_build_path) - cd $(_build_path) && ${run_cmake} - -clean: $(_build_path)/CMakeCache.txt ## Clean the build artifacts - cmake --build $(_build_path) --config $(CONFIG) --target clean - -realclean: ## Delete the build directory - rm -rf $(_build_path) - -env: - $(foreach v, $(.VARIABLES), $(info $(v) = $($(v)))) - -.PHONY : compile install ctest ctest_ test cmake clean realclean env - -.PHONY: papers -papers: - $(MAKE) -C papers papers - -# Help target -.PHONY: help -help: ## Show this help. - @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) targets.mk | sort diff --git a/README.md b/README.md index f2e4ec7..a629c02 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,23 @@ # beman.iterator_interface: iterator creation mechanisms - -![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg) ![CI Tests](https://github.com/bemanproject/iterator_interface/actions/workflows/ci.yml/badge.svg) ![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp29.svg) - + +![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg) ![Continuous Integration Tests](https://github.com/bemanproject/iterator_interface/actions/workflows/ci_tests.yml/badge.svg) ![Lint Check (pre-commit)](https://github.com/bemanproject/iterator_interface/actions/workflows/pre-commit-check.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/bemanproject/iterator_interface/badge.svg?branch=main)](https://coveralls.io/github/bemanproject/iterator_interface?branch=main) ![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp29.svg) **Implements**: [`std::iterator_interface` (P2727R4)](https://wg21.link/P2727R4) - **Status**: [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/beman_library_maturity_model.md#under-development-and-not-yet-ready-for-production-use) - ## License -beman.iterator_interface is licensed under the Apache License v2.0 with LLVM Exceptions. - -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -Documentation and associated papers are licensed with the Creative Commons -Attribution 4.0 International license. - -// SPDX-License-Identifier: CC-BY-4.0 - -The intent is that the source and documentation are available for use by people -implementing their iterator types. +`beman.iterator_interface` is licensed under the Apache License v2.0 with LLVM Exceptions. -The README itself is licensed with CC0 1.0 Universal. Copy the contents and -incorporate in your own work as you see fit. +## Usage -// SPDX-License-Identifier: CC0-1.0 - -## Examples - -Full runnable examples can be found in `examples/` - please check +Full runnable examples can be found in [`examples/`](examples/) - please check [examples/README.md](./examples/README.md) for building the code on local setup or on Compiler Explorer. @@ -133,343 +115,116 @@ std::cout << "\n"; ``` -## How to Build +## Dependencies -### Compiler Support +### Build Environment -This is a modern C++ project which can be compiled with the latest C++ standards -(**C++20 or later**). +This project requires at least the following to build: -Default build: `C++23`. Please check `etc/${compiler}-flags.cmake`. +* A C++ compiler that conforms to the C++20 standard or greater +* CMake 3.30 or later +* (Test Only) GoogleTest -### Dependencies +You can disable building tests by setting CMake option `BEMAN_ITERATOR_INTERFACE_BUILD_TESTS` to +`OFF` when configuring the project. -This project is mainly tested on `Ubuntu 22.04` and `Ubuntu 24.04`, but it -should be as portable as CMake is. This project has no C or C++ dependencies. +### Supported Platforms -Build-time dependencies: +| Compiler | Version | C++ Standards | Standard Library | +|----------|---------|---------------|-------------------| +| GCC | 14-13 | C++26-C++20 | libstdc++ | +| GCC | 12 | C++23, C++20 | libstdc++ | +| Clang | 22-19 | C++26-C++20 | libstdc++, libc++ | +| Clang | 18 | C++26-C++20 | libc++ | +| Clang | 18 | C++23, C++20 | libstdc++ | +| Clang | 17 | C++26-C++20 | libc++ | +| Clang | 17 | C++20 | libstdc++ | -* `cmake` -* `ninja`, `make`, or another CMake-supported build system - * CMake defaults to "Unix Makefiles" on POSIX systems +## Development -Example of installation on `Ubuntu 24.04`: +See the [Contributing Guidelines](CONTRIBUTING.md). -```shell -# Install tools: -apt-get install -y cmake make ninja-build +## Integrate beman.iterator_interface into your project -# Example of toolchains: -apt-get install \ - g++-14 gcc-14 gcc-13 g++-14 \ - clang-18 clang++-18 clang-17 clang++-17 -``` +### Build -### Instructions +You can build iterator_interface using a CMake workflow preset: -#### Preset CMake Workflows +```bash +cmake --workflow --preset gcc-release +``` -This project strives to be as normal and simple a CMake project as possible. This -build workflow in particular will work, producing a static -`beman.iterator_interface` library, ready to package: +To list available workflow presets, you can invoke: - -```shell -$ cmake --workflow --preset gcc-debug -$ cmake --workflow --preset gcc-release -$ cmake --install .build/gcc-release --prefix /opt/beman.iterator_interface - -$ tree /opt/beman.iterator_interface -├── bin # examples (check: BEMAN_ITERATOR_INTERFACE_BUILD_EXAMPLES - default: ON) -│   ├── beman.iterator_interface.examples.filter_int_iterator -│   └── beman.iterator_interface.examples.repeated_chars_iterator -├── include # public API -│   └── beman -│   └── iterator_interface -│   ├── config.hpp -│   ├── detail -│   │   └── stl_interfaces -│   │   ├── config.hpp -│   │   ├── fwd.hpp -│   │   └── iterator_interface.hpp -│   ├── iterator_interface.hpp -│   └── iterator_interface_access.hpp -└── lib # actual library implementation - └── libbeman.iterator_interface.a - -8 directories, 9 files +```bash +cmake --list-presets=workflow ``` -
- Build beman.iterator_interface (verbose logs - gcc-debug) - +For details on building beman.iterator_interface without using a CMake preset, refer to the +[Contributing Guidelines](CONTRIBUTING.md). -This should build and run the tests with system GCC with the address and -undefined behavior sanitizers enabled. +### Installation - -```shell -$ cmake --workflow --preset gcc-debug -Executing workflow step 1 of 3: configure preset "gcc-debug" - -Preset CMake variables: - - CMAKE_BUILD_TYPE="Debug" - CMAKE_CXX_COMPILER="g++" - CMAKE_CXX_FLAGS="-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=leak -fsanitize=undefined" - CMAKE_CXX_STANDARD="17" - --- The CXX compiler identification is GNU 13.2.0 --- Detecting CXX compiler ABI info --- Detecting CXX compiler ABI info - done --- Check for working CXX compiler: /usr/bin/g++ - skipped --- Detecting CXX compile features --- Detecting CXX compile features - done --- Performing Test HAVE_DEDUCING_THIS --- Performing Test HAVE_DEDUCING_THIS - Failed --- The C compiler identification is GNU 13.2.0 --- Detecting C compiler ABI info --- Detecting C compiler ABI info - done --- Check for working C compiler: /usr/bin/cc - skipped --- Detecting C compile features --- Detecting C compile features - done --- Performing Test CMAKE_HAVE_LIBC_PTHREAD --- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success --- Found Threads: TRUE --- Configuring done (2.7s) --- Generating done (0.0s) --- Build files have been written to: /path/to/repo/.build/gcc-debug - -Executing workflow step 2 of 3: build preset "gcc-debug" - -[15/15] Linking CXX executable tests/beman/iterator_interface/beman.iterator_interface.tests - -Executing workflow step 3 of 3: test preset "gcc-debug" - -Test project /path/to/repo/.build/gcc-debug - Start 1: IteratorTest.TestGTest -1/4 Test #1: IteratorTest.TestGTest ........... Passed 0.01 sec - Start 2: IteratorTest.TestRepeatedChars -2/4 Test #2: IteratorTest.TestRepeatedChars ... Passed 0.01 sec - Start 3: IteratorTest.TestFilteredIter -3/4 Test #3: IteratorTest.TestFilteredIter .... Passed 0.01 sec - Start 4: IteratorTest.OperatorArrow -4/4 Test #4: IteratorTest.OperatorArrow ....... Passed 0.01 sec - -100% tests passed, 0 tests failed out of 4 - -Total Test time (real) = 0.04 sec -``` - +To install beman.iterator_interface globally after building with the `gcc-release` preset, you can +run: -
+```bash +sudo cmake --install build/gcc-release +``` - -
- Install beman.iterator_interface (verbose logs - gcc-release) - -```shell -# Build release. -$ cmake --workflow --preset gcc-release -Executing workflow step 1 of 3: configure preset "gcc-release" - -Preset CMake variables: - - CMAKE_BUILD_TYPE="RelWithDebInfo" - CMAKE_CXX_COMPILER="g++" - CMAKE_CXX_FLAGS="-O3" - CMAKE_CXX_STANDARD="17" - --- The CXX compiler identification is GNU 13.2.0 --- Detecting CXX compiler ABI info --- Detecting CXX compiler ABI info - done --- Check for working CXX compiler: /usr/bin/g++ - skipped --- Detecting CXX compile features --- Detecting CXX compile features - done --- Performing Test HAVE_DEDUCING_THIS --- Performing Test HAVE_DEDUCING_THIS - Failed --- The C compiler identification is GNU 13.2.0 --- Detecting C compiler ABI info --- Detecting C compiler ABI info - done --- Check for working C compiler: /usr/bin/cc - skipped --- Detecting C compile features --- Detecting C compile features - done --- Performing Test CMAKE_HAVE_LIBC_PTHREAD --- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success --- Found Threads: TRUE --- Configuring done (2.7s) --- Generating done (0.0s) --- Build files have been written to: /path/to/repo/.build/gcc-release - -Executing workflow step 2 of 3: build preset "gcc-release" - -[15/15] Linking CXX executable tests/beman/iterator_interface/beman.iterator_interface.tests - -Executing workflow step 3 of 3: test preset "gcc-release" - -Test project /path/to/repo/.build/gcc-release - Start 1: IteratorTest.TestGTest -1/4 Test #1: IteratorTest.TestGTest ........... Passed 0.00 sec - Start 2: IteratorTest.TestRepeatedChars -2/4 Test #2: IteratorTest.TestRepeatedChars ... Passed 0.00 sec - Start 3: IteratorTest.TestFilteredIter -3/4 Test #3: IteratorTest.TestFilteredIter .... Passed 0.00 sec - Start 4: IteratorTest.OperatorArrow -4/4 Test #4: IteratorTest.OperatorArrow ....... Passed 0.00 sec - -100% tests passed, 0 tests failed out of 4 - -# Install build artifacts from `build` directory into `/opt/beman.iterator_interface` path. -$ cmake --install .build/gcc-release --prefix /opt/beman.iterator_interface --- Install configuration: "RelWithDebInfo" --- Installing: /opt/beman.iterator_interface/lib/libbeman.iterator_interface.a --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/iterator_interface.hpp --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/iterator_interface_access.hpp --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/detail/stl_interfaces/config.hpp --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/detail/stl_interfaces/fwd.hpp --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/detail/stl_interfaces/iterator_interface.hpp --- Installing: /opt/beman.iterator_interface/bin/beman.iterator_interface.examples.filter_int_iterator --- Installing: /opt/beman.iterator_interface/bin/beman.iterator_interface.examples.repeated_chars_iterator --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/config.hpp - - -# Check tree. -$ tree /opt/beman.iterator_interface -/opt/beman.iterator_interface -├── bin -│   ├── beman.iterator_interface.examples.filter_int_iterator -│   └── beman.iterator_interface.examples.repeated_chars_iterator -├── include -│   └── beman -│   └── iterator_interface -│   ├── config.hpp -│   ├── detail -│   │   └── stl_interfaces -│   │   ├── config.hpp -│   │   ├── fwd.hpp -│   │   └── iterator_interface.hpp -│   ├── iterator_interface.hpp -│   └── iterator_interface_access.hpp -└── lib - └── libbeman.iterator_interface.a +Alternatively, to install to a prefix, for example `/opt/beman`, you can run: -8 directories, 9 files +```bash +sudo cmake --install build/gcc-release --prefix /opt/beman ``` - -
- -#### Custom CMake Flows - -##### Default Build - -CI current build and test flows: - -```shell -# Configure. -$ cmake -G "Ninja Multi-Config" \ - -DCMAKE_CONFIGURATION_TYPES="RelWithDebInfo;Asan" \ - -DCMAKE_TOOLCHAIN_FILE=etc/clang-19-toolchain.cmake \ - -B .build -S . - -# Build with config Asan. -$ cmake --build .build --config Asan --target all -- -k 0 -# Build with config RelWithDebInfo. -$ cmake --build .build --config RelWithDebInfo --target all -- -k 0 - -# Run tests with config Asan.. -$ ctest --build-config Asan --output-on-failure --test-dir .build - -# Install library (default: config set to RelWithDebInfo). -$ cmake --install .build/ --prefix /opt/beman.iterator_interface --- Install configuration: "RelWithDebInfo" --- Installing: /opt/beman.iterator_interface/lib/libbeman.iterator_interface.a --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/iterator_interface.hpp --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/iterator_interface_access.hpp --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/detail/stl_interfaces/config.hpp --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/detail/stl_interfaces/fwd.hpp --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/detail/stl_interfaces/iterator_interface.hpp --- Installing: /opt/beman.iterator_interface/bin/beman.iterator_interface.examples.filter_int_iterator --- Installing: /opt/beman.iterator_interface/bin/beman.iterator_interface.examples.repeated_chars_iterator --- Installing: /opt/beman.iterator_interface/include/beman/iterator_interface/config.hpp -$ tree /opt/beman.iterator_interface -/opt/beman.iterator_interface -├── bin -│   ├── beman.iterator_interface.examples.filter_int_iterator -│   └── beman.iterator_interface.examples.repeated_chars_iterator +This will generate the following directory structure: + +```txt +/opt/beman ├── include -│   └── beman -│   └── iterator_interface -│   ├── config.hpp -│   ├── detail -│   │   └── stl_interfaces -│   │   ├── config.hpp -│   │   ├── fwd.hpp -│   │   └── iterator_interface.hpp -│   ├── iterator_interface.hpp -│   └── iterator_interface_access.hpp +│ └── beman +│ └── iterator_interface +│ ├── iterator_interface.hpp +│ └── ... └── lib - └── libbeman.iterator_interface.a - -8 directories, 9 files + └── cmake + └── beman.iterator_interface + ├── beman.iterator_interface-config-version.cmake + ├── beman.iterator_interface-config.cmake + └── beman.iterator_interface-targets.cmake ``` - -
- Build beman.iterator_interface and tests (verbose logs) - +### CMake Configuration -```shell -# Configure build: default build production code + tests (BEMAN_ITERATOR_INTERFACE_BUILD_TESTING=ON). -$ cmake -G "Ninja Multi-Config" \ - -DCMAKE_CONFIGURATION_TYPES="RelWithDebInfo;Asan" \ - -DCMAKE_TOOLCHAIN_FILE=etc/clang-19-toolchain.cmake \ - -B .build -S . --- The CXX compiler identification is Clang 19.0.0 -... --- Build files have been written to: /path/to/repo/.build - -# Build. -$ cmake --build .build --config Asan --target all -- -k 0 -... -[12/12] Linking CXX executable ... # Note: 12 targets here (including tests). - -# Run tests. -$ ctest --build-config Asan --output-on-failure --test-dir .build -Internal ctest changing into directory: /path/to/repo/.build -Test project /path/to/repo/.build -... -100% tests passed, 0 tests failed out of 82 - -Total Test time (real) = 0.67 sec -``` +If you installed beman.iterator_interface to a prefix, you can specify that prefix to your CMake +project using `CMAKE_PREFIX_PATH`; for example, `-DCMAKE_PREFIX_PATH=/opt/beman`. -
+You need to bring in the `beman.iterator_interface` package to define the `beman::iterator_interface` CMake +target: -##### Skip Tests +```cmake +find_package(beman.iterator_interface REQUIRED) +``` -By default, we build and run tests. You can provide -`-DBEMAN_ITERATOR_INTERFACE_BUILD_TESTING=OFF` and completely disable building tests: +You will then need to add `beman::iterator_interface` to the link libraries of any libraries or +executables that include `beman.iterator_interface` headers. -```shell -# Configure. -$ cmake -G "Ninja Multi-Config" \ - -DCMAKE_CONFIGURATION_TYPES="RelWithDebInfo;Asan" \ - -DCMAKE_TOOLCHAIN_FILE=etc/clang-19-toolchain.cmake \ - -DBEMAN_ITERATOR_INTERFACE_BUILD_TESTING=OFF \ - -B .build -S . +```cmake +target_link_libraries(yourlib PUBLIC beman::iterator_interface) ``` -##### Skip Examples +### Using beman.iterator_interface -By default, we build and run tests. You can provide -`-DBEMAN_ITERATOR_INTERFACE_BUILD_EXAMPLES=OFF` and completely disable building tests: +To use `beman.iterator_interface` in your C++ project, +include an appropriate `beman.iterator_interface` header from your source code. -```shell -# Configure. -$ cmake -G "Ninja Multi-Config" \ - -DCMAKE_CONFIGURATION_TYPES="RelWithDebInfo;Asan" \ - -DCMAKE_TOOLCHAIN_FILE=etc/clang-19-toolchain.cmake \ - -DBEMAN_ITERATOR_INTERFACE_BUILD_EXAMPLES=OFF \ - -B .build -S . +```c++ +#include ``` + +> [!NOTE] +> +> `beman.iterator_interface` headers are to be included with the `beman/iterator_interface/` prefix. +> Altering include search paths to spell the include target another way (e.g. +> `#include `) is unsupported. diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in deleted file mode 100644 index 783e878..0000000 --- a/cmake/Config.cmake.in +++ /dev/null @@ -1,9 +0,0 @@ -# cmake-format: off -# cmake/Config.cmake.in -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -@PACKAGE_INIT@ - -include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake") -check_required_components("@PROJECT_NAME@") diff --git a/cmake/gcovr.cfg.in b/cmake/gcovr.cfg.in deleted file mode 100644 index 9112efb..0000000 --- a/cmake/gcovr.cfg.in +++ /dev/null @@ -1,11 +0,0 @@ -root = @CMAKE_SOURCE_DIR@ -cobertura = @CMAKE_BINARY_DIR@/coverage/cobertura.xml -sonarqube = @CMAKE_BINARY_DIR@/coverage/sonarqube.xml -html-details = @CMAKE_BINARY_DIR@/coverage/coverage.html -gcov-executable = @GCOV_EXECUTABLE@ -gcov-parallel = yes -html-theme = github.dark-blue -html-self-contained = yes -print-summary = yes -filter = .*/beman/iterator_interface/.* -exclude = .*\.t\.cpp diff --git a/etc/ci-clang-toolchain.cmake b/etc/ci-clang-toolchain.cmake deleted file mode 100755 index ddbacd6..0000000 --- a/etc/ci-clang-toolchain.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# cmake-format: off -# etc/ci-clang-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER clang) -set(CMAKE_CXX_COMPILER clang++) - -set(CMAKE_CXX_FLAGS - "-std=c++20 \ - -Wall -Wextra \ - -stdlib=libc++ -fexperimental-library" - CACHE STRING - "CXX_FLAGS" - FORCE -) - -set(CMAKE_CXX_FLAGS_DEBUG - "-O0 -fno-inline -g3" - CACHE STRING - "C++ DEBUG Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELEASE - "-Ofast -g0 -DNDEBUG" - CACHE STRING - "C++ Release Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "-O3 -g -DNDEBUG" - CACHE STRING - "C++ RelWithDebInfo Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_TSAN - "-O3 -g -DNDEBUG -fsanitize=thread" - CACHE STRING - "C++ TSAN Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_ASAN - "-O3 -g -DNDEBUG -fsanitize=address -fsanitize=undefined -fsanitize=leak" - CACHE STRING - "C++ ASAN Flags" - FORCE -) diff --git a/etc/clang-16-toolchain.cmake b/etc/clang-16-toolchain.cmake deleted file mode 100755 index 9fe8f80..0000000 --- a/etc/clang-16-toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# cmake-format: off -# etc/clang-16-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER clang-16) -set(CMAKE_CXX_COMPILER clang++-16) - -include("${CMAKE_CURRENT_LIST_DIR}/clang-flags.cmake") diff --git a/etc/clang-17-toolchain.cmake b/etc/clang-17-toolchain.cmake deleted file mode 100755 index 528ed9e..0000000 --- a/etc/clang-17-toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# cmake-format: off -# etc/clang-17-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER clang-17) -set(CMAKE_CXX_COMPILER clang++-17) - -include("${CMAKE_CURRENT_LIST_DIR}/clang-flags.cmake") diff --git a/etc/clang-18-toolchain.cmake b/etc/clang-18-toolchain.cmake deleted file mode 100755 index d49019d..0000000 --- a/etc/clang-18-toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# cmake-format: off -# etc/clang-18-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER clang-18) -set(CMAKE_CXX_COMPILER clang++-18) - -include("${CMAKE_CURRENT_LIST_DIR}/clang-flags.cmake") diff --git a/etc/clang-19-toolchain.cmake b/etc/clang-19-toolchain.cmake deleted file mode 100755 index 64a26e0..0000000 --- a/etc/clang-19-toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# cmake-format: off -# etc/clang-19-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER clang-19) -set(CMAKE_CXX_COMPILER clang++-19) - -include("${CMAKE_CURRENT_LIST_DIR}/clang-flags.cmake") diff --git a/etc/clang-20-toolchain.cmake b/etc/clang-20-toolchain.cmake deleted file mode 100644 index b41013d..0000000 --- a/etc/clang-20-toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# cmake-format: off -# etc/clang-20-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER clang-20) -set(CMAKE_CXX_COMPILER clang++-20) - -include("${CMAKE_CURRENT_LIST_DIR}/clang-flags.cmake") diff --git a/etc/clang-flags.cmake b/etc/clang-flags.cmake deleted file mode 100644 index 30bbf65..0000000 --- a/etc/clang-flags.cmake +++ /dev/null @@ -1,46 +0,0 @@ -# cmake-format: off -# etc/clang-flags.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_CXX_STANDARD 23) - -set(CMAKE_CXX_FLAGS - "-stdlib=libc++ -Wall -Wextra " - CACHE STRING - "CXX_FLAGS" - FORCE -) - -set(CMAKE_CXX_FLAGS_DEBUG - "-O0 -fno-inline -g3" - CACHE STRING - "C++ DEBUG Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELEASE - "-Ofast -g0 -DNDEBUG" - CACHE STRING - "C++ Release Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "-O3 -g -DNDEBUG" - CACHE STRING - "C++ RelWithDebInfo Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_TSAN - "-O3 -g -DNDEBUG -fsanitize=thread" - CACHE STRING - "C++ TSAN Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_ASAN - "-O3 -g -DNDEBUG -fsanitize=address,undefined,leak" - CACHE STRING - "C++ ASAN Flags" - FORCE -) diff --git a/etc/gcc-11-toolchain.cmake b/etc/gcc-11-toolchain.cmake deleted file mode 100755 index c34c816..0000000 --- a/etc/gcc-11-toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# cmake-format: off -# etc/gcc-11-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -include("${CMAKE_CURRENT_LIST_DIR}/gcc-flags.cmake") - -set(CMAKE_C_COMPILER gcc-11) -set(CMAKE_CXX_COMPILER g++-11) diff --git a/etc/gcc-12-toolchain.cmake b/etc/gcc-12-toolchain.cmake deleted file mode 100755 index e36eca7..0000000 --- a/etc/gcc-12-toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# cmake-format: off -# etc/gcc-12-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -include("${CMAKE_CURRENT_LIST_DIR}/gcc-flags.cmake") - -set(CMAKE_C_COMPILER gcc-12) -set(CMAKE_CXX_COMPILER g++-12) diff --git a/etc/gcc-13-toolchain.cmake b/etc/gcc-13-toolchain.cmake deleted file mode 100755 index 54ecd60..0000000 --- a/etc/gcc-13-toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# cmake-format: off -# etc/gcc-13-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -include("${CMAKE_CURRENT_LIST_DIR}/gcc-flags.cmake") - -set(CMAKE_C_COMPILER gcc-13) -set(CMAKE_CXX_COMPILER g++-13) diff --git a/etc/gcc-14-toolchain.cmake b/etc/gcc-14-toolchain.cmake deleted file mode 100755 index f665810..0000000 --- a/etc/gcc-14-toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# cmake-format: off -# etc/gcc-14-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -include("${CMAKE_CURRENT_LIST_DIR}/gcc-flags.cmake") - -set(CMAKE_C_COMPILER gcc-14) -set(CMAKE_CXX_COMPILER g++-14) diff --git a/etc/gcc-flags.cmake b/etc/gcc-flags.cmake deleted file mode 100644 index e37ea9b..0000000 --- a/etc/gcc-flags.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# cmake-format: off -# etc/gcc-flags.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_CXX_STANDARD 23) - -set(CMAKE_CXX_FLAGS "-Wall -Wextra " CACHE STRING "CXX_FLAGS" FORCE) - -set(CMAKE_CXX_FLAGS_DEBUG - "-O0 -fno-inline -g3" - CACHE STRING - "C++ DEBUG Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELEASE - "-Ofast -g0 -DNDEBUG" - CACHE STRING - "C++ Release Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "-O3 -g -DNDEBUG" - CACHE STRING - "C++ RelWithDebInfo Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_TSAN - "-O3 -g -DNDEBUG -fsanitize=thread" - CACHE STRING - "C++ TSAN Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_ASAN - "-O3 -g -DNDEBUG -fsanitize=undefined" - CACHE STRING - "C++ ASAN Flags" - FORCE -) diff --git a/etc/gcc-toolchain.cmake b/etc/gcc-toolchain.cmake deleted file mode 100755 index 1119311..0000000 --- a/etc/gcc-toolchain.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# cmake-format: off -# etc/gcc-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER gcc) -set(CMAKE_CXX_COMPILER g++) - -set(CMAKE_CXX_FLAGS - "-std=c++20 \ - -Wall -Wextra " - CACHE STRING - "CXX_FLAGS" - FORCE -) - -set(CMAKE_CXX_FLAGS_DEBUG - "-O0 -fno-inline -g3" - CACHE STRING - "C++ DEBUG Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELEASE - "-Ofast -g0 -DNDEBUG" - CACHE STRING - "C++ Release Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "-O3 -g -DNDEBUG" - CACHE STRING - "C++ RelWithDebInfo Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_TSAN - "-O3 -g -DNDEBUG -fsanitize=thread" - CACHE STRING - "C++ TSAN Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_ASAN - "-O3 -g -DNDEBUG -fsanitize=address,undefined,leak" - CACHE STRING - "C++ ASAN Flags" - FORCE -) diff --git a/etc/llvm-16-toolchain.cmake b/etc/llvm-16-toolchain.cmake deleted file mode 100755 index d25ddf1..0000000 --- a/etc/llvm-16-toolchain.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# cmake-format: off -# etc/llvm-16-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER clang-16) -set(CMAKE_CXX_COMPILER clang++-16) - -set(CMAKE_CXX_FLAGS - "-std=c++20 \ - -Wall -Wextra \ - -stdlib=libc++ -fexperimental-library" - CACHE STRING - "CXX_FLAGS" - FORCE -) - -set(CMAKE_CXX_FLAGS_DEBUG - "-O0 -fno-inline -g3" - CACHE STRING - "C++ DEBUG Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELEASE - "-Ofast -g0 -DNDEBUG" - CACHE STRING - "C++ Release Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "-O3 -g -DNDEBUG" - CACHE STRING - "C++ RelWithDebInfo Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_TSAN - "-O3 -g -DNDEBUG -fsanitize=thread" - CACHE STRING - "C++ TSAN Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_ASAN - "-O3 -g -DNDEBUG -fsanitize=address -fsanitize=undefined -fsanitize=leak" - CACHE STRING - "C++ ASAN Flags" - FORCE -) diff --git a/etc/llvm-master-toolchain.cmake b/etc/llvm-master-toolchain.cmake deleted file mode 100644 index beeb5cb..0000000 --- a/etc/llvm-master-toolchain.cmake +++ /dev/null @@ -1,56 +0,0 @@ -# cmake-format: off -# etc/llvm-master-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -set(LLVM_ROOT "$ENV{LLVM_ROOT}" CACHE PATH "Path to LLVM installation") - -set(CMAKE_C_COMPILER ${LLVM_ROOT}/bin/clang) -set(CMAKE_CXX_COMPILER ${LLVM_ROOT}/bin/clang++) - -set(CMAKE_CXX_FLAGS - "-std=c++2a \ - -Wall -Wextra \ - -stdlib=libc++ " - CACHE STRING - "CXX_FLAGS" - FORCE -) - -set(CMAKE_EXE_LINKER_FLAGS - "-Wl,-rpath,${LLVM_ROOT}/lib" - CACHE STRING - "CMAKE_EXE_LINKER_FLAGS" - FORCE -) - -set(CMAKE_CXX_FLAGS_DEBUG - "-O0 -fno-inline -g3" - CACHE STRING - "C++ DEBUG Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELEASE - "-Ofast -g0 -DNDEBUG" - CACHE STRING - "C++ Release Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "-O3 -g -DNDEBUG" - CACHE STRING - "C++ Release Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_TSAN - "-O3 -g -DNDEBUG -fsanitize=thread" - CACHE STRING - "C++ TSAN Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_ASAN - "-O3 -g -DNDEBUG -fsanitize=address -fsanitize=undefined -fsanitize=leak" - CACHE STRING - "C++ ASAN Flags" - FORCE -) diff --git a/etc/llvm-toolchain.cmake b/etc/llvm-toolchain.cmake deleted file mode 100755 index c41f6cf..0000000 --- a/etc/llvm-toolchain.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# cmake-format: off -# etc/llvm-toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER clang-14) -set(CMAKE_CXX_COMPILER clang++-14) - -set(CMAKE_CXX_FLAGS - "-std=c++20 \ - -Wall -Wextra \ - -stdlib=libstdc++ " - CACHE STRING - "CXX_FLAGS" - FORCE -) - -set(CMAKE_CXX_FLAGS_DEBUG - "-O0 -fno-inline -g3" - CACHE STRING - "C++ DEBUG Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELEASE - "-Ofast -g0 -DNDEBUG" - CACHE STRING - "C++ Release Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "-O3 -g -DNDEBUG" - CACHE STRING - "C++ RelWithDebInfo Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_TSAN - "-O3 -g -DNDEBUG -fsanitize=thread" - CACHE STRING - "C++ TSAN Flags" - FORCE -) -set(CMAKE_CXX_FLAGS_ASAN - "-O3 -g -DNDEBUG -fsanitize=address -fsanitize=undefined -fsanitize=leak" - CACHE STRING - "C++ ASAN Flags" - FORCE -) diff --git a/etc/toolchain.cmake b/etc/toolchain.cmake deleted file mode 100644 index b0a47c2..0000000 --- a/etc/toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# cmake-format: off -# etc/toolchain.cmake -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -include_guard(GLOBAL) - -include("${CMAKE_CURRENT_LIST_DIR}/gcc-flags.cmake") - -set(CMAKE_C_COMPILER cc) -set(CMAKE_CXX_COMPILER c++) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 82cdf69..c1d1121 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,34 +1,16 @@ -# cmake-format: off -# examples/CMakeLists.txt -*-cmake-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on -# List of all buildable examples. -set(EXAMPLES filter_int_iterator repeated_chars_iterator) +set(ALL_EXAMPLES filter_int_iterator repeated_chars_iterator) +message("Examples to be built: ${ALL_EXAMPLES}") -foreach(example ${EXAMPLES}) - # Add example executable. - add_executable(beman.iterator_interface.examples.${example} "") - - # Add example source file. +foreach(example ${ALL_EXAMPLES}) + add_executable(beman.iterator_interface.examples.${example}) target_sources( beman.iterator_interface.examples.${example} PRIVATE ${example}.cpp ) - - # Link example with the library. target_link_libraries( beman.iterator_interface.examples.${example} - beman::iterator_interface - ) - - # Install. - install( - TARGETS - beman.iterator_interface.examples.${example} - COMPONENT - beman.iterator_interface.examples - DESTINATION - ${CMAKE_INSTALL_BINDIR} + PRIVATE beman::iterator_interface ) endforeach() diff --git a/include/beman/iterator_interface/CMakeLists.txt b/include/beman/iterator_interface/CMakeLists.txt index c71cc8d..fd546b1 100644 --- a/include/beman/iterator_interface/CMakeLists.txt +++ b/include/beman/iterator_interface/CMakeLists.txt @@ -1,18 +1,14 @@ -# cmake-format: off -# include/beman/iterator_interface/CMakeLists.txt -*-cmake-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on target_sources( beman.iterator_interface PUBLIC - FILE_SET beman_iterator_interface_headers - TYPE HEADERS - BASE_DIRS ${PROJECT_BINARY_DIR}/include ${PROJECT_SOURCE_DIR}/include - FILES - iterator_interface.hpp - iterator_interface_access.hpp - detail/stl_interfaces/config.hpp - detail/stl_interfaces/fwd.hpp - detail/stl_interfaces/iterator_interface.hpp + FILE_SET HEADERS + FILES + iterator_interface.hpp + iterator_interface_access.hpp + detail/stl_interfaces/config.hpp + detail/stl_interfaces/fwd.hpp + detail/stl_interfaces/iterator_interface.hpp + "${PROJECT_BINARY_DIR}/include/beman/iterator_interface/config.hpp" ) diff --git a/include/beman/iterator_interface/detail/stl_interfaces/config.hpp b/include/beman/iterator_interface/detail/stl_interfaces/config.hpp index cfc2c05..862d086 100644 --- a/include/beman/iterator_interface/detail/stl_interfaces/config.hpp +++ b/include/beman/iterator_interface/detail/stl_interfaces/config.hpp @@ -14,16 +14,16 @@ #if defined(__cpp_lib_concepts) && defined(__cpp_lib_ranges) && \ !defined(BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_DISABLE_CONCEPTS) -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS 1 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS 1 #else -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS 0 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS 0 #endif #if defined(__cpp_explicit_this_parameter) && BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS && \ !defined(BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_DISABLE_DEDUCED_THIS) -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS 1 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS 1 #else -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS 0 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS 0 #endif // The inline namespaces v1, v2, and v3 represent C++14, C++20, and C++23 and @@ -34,18 +34,18 @@ // contents. #if !BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS && \ !BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 inline namespace v1 -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2 -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 inline namespace v1 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3 #elif BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS && \ !BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_DEDUCED_THIS -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1 -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V2 inline namespace v2 -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V2 inline namespace v2 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V3 namespace v3 #else -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1 -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2 -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V3 inline namespace v3 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V1 namespace v1 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V2 namespace v2 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V3 inline namespace v3 #endif #endif diff --git a/include/beman/iterator_interface/detail/stl_interfaces/fwd.hpp b/include/beman/iterator_interface/detail/stl_interfaces/fwd.hpp index 4dbbb05..3e5784c 100644 --- a/include/beman/iterator_interface/detail/stl_interfaces/fwd.hpp +++ b/include/beman/iterator_interface/detail/stl_interfaces/fwd.hpp @@ -12,26 +12,26 @@ #include #if BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS -#include + #include #endif #if defined(__cpp_lib_three_way_comparison) -#include + #include #endif #ifndef BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_DOXYGEN -#if defined(_MSC_VER) || defined(__GNUC__) && __GNUC__ < 8 -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NO_HIDDEN_FRIEND_CONSTEXPR -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR -#else -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR constexpr -#endif - -#if defined(__GNUC__) && __GNUC__ < 9 -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_CONCEPT concept bool -#else -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_CONCEPT concept -#endif + #if defined(_MSC_VER) || defined(__GNUC__) && __GNUC__ < 8 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NO_HIDDEN_FRIEND_CONSTEXPR + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR + #else + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR constexpr + #endif + + #if defined(__GNUC__) && __GNUC__ < 9 + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_CONCEPT concept bool + #else + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_CONCEPT concept + #endif #endif diff --git a/include/beman/iterator_interface/detail/stl_interfaces/iterator_interface.hpp b/include/beman/iterator_interface/detail/stl_interfaces/iterator_interface.hpp index c107a10..2ec19a7 100644 --- a/include/beman/iterator_interface/detail/stl_interfaces/iterator_interface.hpp +++ b/include/beman/iterator_interface/detail/stl_interfaces/iterator_interface.hpp @@ -15,7 +15,7 @@ #include #include #if defined(__cpp_lib_three_way_comparison) -#include + #include #endif namespace beman::iterator_interface::detail { @@ -926,53 +926,53 @@ BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_NAMESPACE_V3 { #ifdef BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_DOXYGEN -/** `static_asserts` that type `type` models concept `concept_name`. This is - useful for checking that an iterator, view, etc. that you write using one - of the *`_interface` templates models the right C++ concept. + /** `static_asserts` that type `type` models concept `concept_name`. This is + useful for checking that an iterator, view, etc. that you write using one + of the *`_interface` templates models the right C++ concept. - For example: `BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_CONCEPT(my_iter, - std::input_iterator)`. + For example: `BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_CONCEPT(my_iter, + std::input_iterator)`. - \note This macro expands to nothing when `__cpp_lib_concepts` is not - defined. */ -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_CONCEPT(type, concept_name) + \note This macro expands to nothing when `__cpp_lib_concepts` is not + defined. */ + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_CONCEPT(type, concept_name) -/** `static_asserts` that the types of all typedefs in - `std::iterator_traits` match the remaining macro parameters. This - is useful for checking that an iterator you write using - `iterator_interface` has the correct iterator traits. + /** `static_asserts` that the types of all typedefs in + `std::iterator_traits` match the remaining macro parameters. This + is useful for checking that an iterator you write using + `iterator_interface` has the correct iterator traits. - For example: `BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(my_iter, - std::input_iterator_tag, std::input_iterator, int, int &, int *, std::ptrdiff_t)`. + For example: `BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(my_iter, + std::input_iterator_tag, std::input_iterator, int, int &, int *, std::ptrdiff_t)`. - \note This macro ignores the `concept` parameter when `__cpp_lib_concepts` - is not defined. */ -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS( \ - iter, category, concept, value_type, reference, pointer, difference_type) + \note This macro ignores the `concept` parameter when `__cpp_lib_concepts` + is not defined. */ + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS( \ + iter, category, concept, value_type, reference, pointer, difference_type) #else -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_CONCEPT_IMPL(type, concept_name) \ - static_assert(concept_name, ""); - -#if BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_CONCEPT(iter, concept_name) \ - BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_CONCEPT_IMPL(iter, concept_name) -#else -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_CONCEPT(iter, concept_name) -#endif - -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS_IMPL( \ - iter, category, value_t, ref, ptr, diff_t) \ - static_assert(std::is_same::value_type, value_t>::value, ""); \ - static_assert(std::is_same::reference, ref>::value, ""); \ - static_assert(std::is_same::pointer, ptr>::value, ""); \ - static_assert(std::is_same::difference_type, diff_t>::value, ""); - -#define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS( \ - iter, category, concept, value_type, reference, pointer, difference_type) \ - BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS_IMPL( \ - iter, category, value_type, reference, pointer, difference_type) + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_CONCEPT_IMPL(type, concept_name) \ + static_assert(concept_name, ""); + + #if BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_USE_CONCEPTS + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_CONCEPT(iter, concept_name) \ + BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_CONCEPT_IMPL(iter, concept_name) + #else + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_CONCEPT(iter, concept_name) + #endif + + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS_IMPL( \ + iter, category, value_t, ref, ptr, diff_t) \ + static_assert(std::is_same::value_type, value_t>::value, ""); \ + static_assert(std::is_same::reference, ref>::value, ""); \ + static_assert(std::is_same::pointer, ptr>::value, ""); \ + static_assert(std::is_same::difference_type, diff_t>::value, ""); + + #define BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS( \ + iter, category, concept, value_type, reference, pointer, difference_type) \ + BEMAN_ITERATOR_INTERFACE_DETAIL_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS_IMPL( \ + iter, category, value_type, reference, pointer, difference_type) #endif #endif diff --git a/include/beman/iterator_interface/iterator_interface.hpp b/include/beman/iterator_interface/iterator_interface.hpp index 1e5f1fc..c8471a5 100644 --- a/include/beman/iterator_interface/iterator_interface.hpp +++ b/include/beman/iterator_interface/iterator_interface.hpp @@ -7,7 +7,7 @@ #include #include #if !BEMAN_ITERATOR_INTERFACE_USE_DEDUCING_THIS() -#include + #include #endif #include diff --git a/infra/.beman_submodule b/infra/.beman_submodule new file mode 100644 index 0000000..56dbbcc --- /dev/null +++ b/infra/.beman_submodule @@ -0,0 +1,3 @@ +[beman_submodule] +remote=https://github.com/bemanproject/infra.git +commit_hash=ea3ef79f77fdcc378149ebc7406e81e9ceb04146 diff --git a/infra/.github/CODEOWNERS b/infra/.github/CODEOWNERS new file mode 100644 index 0000000..4ff90a4 --- /dev/null +++ b/infra/.github/CODEOWNERS @@ -0,0 +1 @@ +* @ednolan @neatudarius @rishyak @wusatosi @JeffGarland diff --git a/.github/workflows/pre-commit.yml b/infra/.github/workflows/pre-commit.yml similarity index 98% rename from .github/workflows/pre-commit.yml rename to infra/.github/workflows/pre-commit.yml index f3c4332..9646831 100644 --- a/.github/workflows/pre-commit.yml +++ b/infra/.github/workflows/pre-commit.yml @@ -5,6 +5,8 @@ on: # enough permission for reviewdog pull_request_target: push: + branches: + - main jobs: pre-commit-push: diff --git a/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml b/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml new file mode 100644 index 0000000..024a51f --- /dev/null +++ b/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +name: 'Beman issue creation workflow' +on: + workflow_call: + workflow_dispatch: +jobs: + create-issue: + runs-on: ubuntu-latest + steps: + # See https://github.com/cli/cli/issues/5075 + - uses: actions/checkout@v4 + - name: Create issue + run: | + issue_num=$(gh issue list -s open -S "[SCHEDULED-BUILD] infra repo CI job failure" -L 1 --json number | jq 'if length == 0 then -1 else .[0].number end') + body="**CI job failure Report** + - **Time of Failure**: $(date -u '+%B %d, %Y, %H:%M %Z') + - **Commit**: [${{ github.sha }}](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) + - **Action Run**: [View logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) + The scheduled job triggered by cron has failed. + Please investigate the logs and recent changes associated with this commit or rerun the workflow if you believe this is an error." + if [[ $issue_num -eq -1 ]]; then + gh issue create --repo ${{ github.repository }} --title "[SCHEDULED-BUILD] infra repo CI job failure" --body "$body" --assignee ${{ github.actor }} + else + gh issue comment --repo ${{ github.repository }} $issue_num --body "$body" + fi + env: + GH_TOKEN: ${{ github.token }} diff --git a/infra/.gitignore b/infra/.gitignore new file mode 100644 index 0000000..b7cdbb5 --- /dev/null +++ b/infra/.gitignore @@ -0,0 +1,59 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Python +__pycache__/ +.pytest_cache/ +*.pyc +*.pyo +*.pyd +*.pyw +*.pyz +*.pywz +*.pyzw +*.pyzwz +*.delete_me + +# MAC OS +*.DS_Store + +# Editor files +.vscode/ +.idea/ + +# Build directories +infra.egg-info/ +beman_tidy.egg-info/ +*.egg-info/ +build/ +dist/ diff --git a/infra/.pre-commit-config.yaml b/infra/.pre-commit-config.yaml new file mode 100644 index 0000000..8052e18 --- /dev/null +++ b/infra/.pre-commit-config.yaml @@ -0,0 +1,21 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + + - repo: https://github.com/codespell-project/codespell + rev: v2.4.2 + hooks: + - id: codespell + + # CMake linting and formatting + - repo: https://github.com/BlankSpruce/gersemi-pre-commit + rev: 0.27.2 + hooks: + - id: gersemi + name: CMake linting + exclude: ^.*/tests/.*/data/ # Exclude test data directories diff --git a/infra/LICENSE b/infra/LICENSE new file mode 100644 index 0000000..f6db814 --- /dev/null +++ b/infra/LICENSE @@ -0,0 +1,219 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +---- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. diff --git a/infra/README.md b/infra/README.md new file mode 100644 index 0000000..bf9bbb0 --- /dev/null +++ b/infra/README.md @@ -0,0 +1,88 @@ +# Beman Project Infrastructure Repository + + + +This repository contains the infrastructure for The Beman Project. This is NOT a library repository, +so it does not respect the usual structure of a Beman library repository nor The Beman Standard! + +## Description + +* `cmake/`: CMake modules and toolchain files used by Beman libraries. +* `containers/`: Containers used for CI builds and tests in the Beman org. + +## Usage + +This repository is intended to be used as a beman-submodule in other Beman repositories. See +[the beman-submodule documentation](https://github.com/bemanproject/beman-submodule) for details. + + +### CMake Modules + + +#### `beman_install_library` + +The CMake modules in this repository are intended to be used by Beman libraries. Use the +`beman_add_install_library_config()` function to install your library, along with header +files, any metadata files, and a CMake config file for `find_package()` support. + +```cmake +add_library(beman.something) +add_library(beman::something ALIAS beman.something) + +# ... configure your target as needed ... + +find_package(beman-install-library REQUIRED) +beman_install_library(beman.something) +``` + +Note that the target must be created before calling `beman_install_library()`. The module +also assumes that the target is named using the `beman.something` convention, and it +uses that assumption to derive the names to match other Beman standards and conventions. +If your target does not follow that convention, raise an issue or pull request to add +more configurability to the module. + +The module will configure the target to install: + +* The library target itself +* Any public headers associated with the target +* CMake files for `find_package(beman.something)` support + +Some options for the project and target will also be supported: + +* `BEMAN_INSTALL_CONFIG_FILE_PACKAGES` - a list of package names (e.g., `beman.something`) for which to install the config file + (default: all packages) +* `_INSTALL_CONFIG_FILE_PACKAGE` - a per-project option to enable/disable config file installation (default: `ON` if the project is top-level, `OFF` otherwise). For instance for `beman.something`, the option would be `BEMAN_SOMETHING_INSTALL_CONFIG_FILE_PACKAGE`. + +# BuildTelemetry + +The cmake modules in this library provide access to CMake instrumentation data in Google Trace format which is visualizable with chrome://tracing and https://ui.perfetto.dev. + +Telemetry may be enabled in several ways: + +## `include` + +```cmake +include (infra/cmake/BuildTelemetry.cmake) +configure_build_telemetry() +``` + +## `find_package` + +```cmake +find_package(BuildTelemetry) +configure_build_telemetry() +``` + +as long as [BuildTelemetryConfig.cmake](./cmake/BuildTelemetryConfig.cmake) is in your module path. + +## `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` +A non-invasive way to inject this telemetry into a CMake build you do not want to modify. +Add: +```sh +-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=infra/cmake/BuildTelemetry.cmake +``` +To the cmake invocation. + +In any form, CMake will call `telemetry.sh` which will copy the trace data in json format into a `.trace` subdirectory within the build directory. + +Multiple calls to `configure_build_telemetry` will only configure the callback hooks once, so it is safe to enable multiple times, including by TOP_LEVEL_INCLUDE. diff --git a/infra/cmake/BuildTelemetry.cmake b/infra/cmake/BuildTelemetry.cmake new file mode 100755 index 0000000..c2ff343 --- /dev/null +++ b/infra/cmake/BuildTelemetry.cmake @@ -0,0 +1,4 @@ +include_guard(GLOBAL) + +include(${CMAKE_CURRENT_LIST_DIR}/BuildTelemetryConfig.cmake) +configure_build_telemetry() diff --git a/infra/cmake/BuildTelemetryConfig.cmake b/infra/cmake/BuildTelemetryConfig.cmake new file mode 100755 index 0000000..15aae48 --- /dev/null +++ b/infra/cmake/BuildTelemetryConfig.cmake @@ -0,0 +1,58 @@ +include_guard(GLOBAL) + +set(BUILD_TELEMETRY_DIR ${CMAKE_CURRENT_LIST_DIR}) + +function(configure_build_telemetry) + if(NOT BUILD_TELEMETRY_CONFIGURATION) + # Check if the CMake version is at least 4.3 + if(CMAKE_VERSION VERSION_LESS "4.3") + message( + STATUS + "CMake version is less than 4.3, configuring cmake_instrumentation is unavailable." + ) + return() + else() + message(STATUS "Configuring Build Telemetry") + endif() + + # Find bash and jq for the telemetry callback script. + # On Windows, Git for Windows provides bash if available. + find_program(BEMAN_BASH bash) + find_program(BEMAN_JQ jq) + if(NOT BEMAN_BASH OR NOT BEMAN_JQ) + message( + STATUS + "bash or jq not found, build telemetry disabled on this platform." + ) + return() + endif() + + # Telemetry query + cmake_instrumentation( + API_VERSION 1 + DATA_VERSION 1 + OPTIONS staticSystemInformation dynamicSystemInformation trace + HOOKS + postGenerate + preBuild + postBuild + preCMakeBuild + postCMakeBuild + postCMakeInstall + postCTest + CALLBACK ${BEMAN_BASH} + ${BUILD_TELEMETRY_DIR}/telemetry.sh + ) + message( + DEBUG + "using callback script ${BUILD_TELEMETRY_DIR}/telemetry.sh via ${BEMAN_BASH}" + ) + + # Mark configuration as done in cache + set(BUILD_TELEMETRY_CONFIGURATION + TRUE + CACHE INTERNAL + "Flag to ensure Build Telemetry configured only once" + ) + endif() +endfunction(configure_build_telemetry) diff --git a/infra/cmake/Config.cmake.in b/infra/cmake/Config.cmake.in new file mode 100644 index 0000000..3f1341c --- /dev/null +++ b/infra/cmake/Config.cmake.in @@ -0,0 +1,12 @@ +# cmake/Config.cmake.in -*-makefile-*- +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +include(CMakeFindDependencyMacro) + +@BEMAN_INSTALL_FIND_DEPENDENCIES@ + +@PACKAGE_INIT@ + +include(${CMAKE_CURRENT_LIST_DIR}/@BEMAN_INSTALL_BASE_PKG_NAME@-targets.cmake) + +check_required_components(@BEMAN_INSTALL_BASE_PKG_NAME@) diff --git a/infra/cmake/appleclang-toolchain.cmake b/infra/cmake/appleclang-toolchain.cmake new file mode 100644 index 0000000..70ef548 --- /dev/null +++ b/infra/cmake/appleclang-toolchain.cmake @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This toolchain file is not meant to be used directly, +# but to be invoked by CMake preset and GitHub CI. +# +# This toolchain file configures for apple clang family of compiler. +# Note this is different from LLVM toolchain. +# +# BEMAN_BUILDSYS_SANITIZER: +# This optional CMake parameter is not meant for public use and is subject to +# change. +# Possible values: +# - MaxSan: configures clang and clang++ to use all available non-conflicting +# sanitizers. Note that apple clang does not support leak sanitizer. +# - TSan: configures clang and clang++ to enable the use of thread sanitizer. + +include_guard(GLOBAL) + +# Prevent PATH collision with an LLVM clang installation by using the system +# compiler shims +set(CMAKE_C_COMPILER cc) +set(CMAKE_CXX_COMPILER c++) + +if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") + set(SANITIZER_FLAGS + "-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined" + ) +elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") + set(SANITIZER_FLAGS "-fsanitize=thread") +endif() + +set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") +set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") + +set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") + +set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") + +set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") + +# Add this dir to the module path so that `find_package(beman-install-library)` works +list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/infra/cmake/beman-install-library.cmake b/infra/cmake/beman-install-library.cmake new file mode 100644 index 0000000..dc5a4d1 --- /dev/null +++ b/infra/cmake/beman-install-library.cmake @@ -0,0 +1,323 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +include_guard(GLOBAL) + +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) + +# beman_install_library +# ===================== +# +# Installs a library (or set of targets) along with headers, C++ modules, +# and optional CMake package configuration files. +# +# Usage: +# ------ +# beman_install_library( +# TARGETS [ ...] +# [DEPENDENCIES [ ...]] +# [NAMESPACE ] +# [EXPORT_NAME ] +# [DESTINATION ] +# ) +# +# Arguments: +# ---------- +# +# name +# Logical package name (e.g. "beman.utility"). +# Used to derive config file names and cache variable prefixes. +# +# TARGETS (required) +# List of CMake targets to install. +# +# DEPENDENCIES (optional) +# Semicolon-separated list, one dependency per entry. +# Each entry is a valid find_dependency() argument list. +# Note: you must use the bracket form for quoting if not only a package name is used! +# "[===[beman.inplace_vector 1.0.0]===] [===[beman.scope 0.0.1 EXACT]===] fmt" +# +# NAMESPACE (optional) +# Namespace for exported targets. +# Defaults to "beman::". +# +# EXPORT_NAME (optional) +# Name of the CMake export set. +# Defaults to "-targets". +# +# DESTINATION (optional) +# The install destination for CXX_MODULES. +# Defaults to ${CMAKE_INSTALL_LIBDIR}/cmake/${name}/modules. +# +# Brief +# ----- +# +# This function installs the specified project TARGETS and its FILE_SET +# HEADERS to the default CMAKE install destination. +# +# It also handles the installation of the CMake config package files if +# needed. If the given targets has a PUBLIC FILE_SET CXX_MODULE, it will also +# installed to the given DESTINATION +# +# Cache variables: +# ---------------- +# +# BEMAN_INSTALL_CONFIG_FILE_PACKAGES +# List of package names for which config files should be installed. +# +# _INSTALL_CONFIG_FILE_PACKAGE +# Per-package override to enable/disable config file installation. +# is the uppercased package name with dots replaced by underscores. +# +# Caveats +# ------- +# +# **Only one `PUBLIC FILE_SET CXX_MODULES` is yet supported to install with this +# function!** +# +# **Only header files contained in a `PUBLIC FILE_SET TYPE HEADERS` will be +# install with this function!** + +function(beman_install_library name) + # ---------------------------- + # Argument parsing + # ---------------------------- + set(oneValueArgs NAMESPACE EXPORT_NAME DESTINATION) + set(multiValueArgs TARGETS DEPENDENCIES) + + cmake_parse_arguments( + BEMAN_INSTALL + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + + if(NOT BEMAN_INSTALL_TARGETS) + message( + FATAL_ERROR + "beman_install_library(${name}): TARGETS must be specified" + ) + endif() + + if(CMAKE_SKIP_INSTALL_RULES) + message( + WARNING + "beman_install_library(${name}): not installing targets '${BEMAN_INSTALL_TARGETS}' due to CMAKE_SKIP_INSTALL_RULES" + ) + return() + endif() + + set(_config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${name}") + + # ---------------------------- + # Defaults + # ---------------------------- + if(NOT BEMAN_INSTALL_NAMESPACE) + set(BEMAN_INSTALL_NAMESPACE "beman::") + endif() + + if(NOT BEMAN_INSTALL_EXPORT_NAME) + set(BEMAN_INSTALL_EXPORT_NAME "${name}-targets") + endif() + + if(NOT BEMAN_INSTALL_DESTINATION) + set(BEMAN_INSTALL_DESTINATION "${_config_install_dir}/modules") + endif() + + string(REPLACE "beman." "" install_component_name "${name}") + message( + VERBOSE + "beman-install-library(${name}): COMPONENT '${install_component_name}'" + ) + + # -------------------------------------------------- + # Install each target with all of its file sets + # -------------------------------------------------- + foreach(_tgt IN LISTS BEMAN_INSTALL_TARGETS) + if(NOT TARGET "${_tgt}") + message( + WARNING + "beman_install_library(${name}): '${_tgt}' is not a target" + ) + continue() + endif() + + # Given foo.bar, the component name is bar + string(REPLACE "." ";" name_parts "${_tgt}") + # fail if the name doesn't look like foo.bar + list(LENGTH name_parts name_parts_length) + if(NOT name_parts_length EQUAL 2) + message( + FATAL_ERROR + "beman_install_library(${name}): expects a name of the form 'beman.', got '${_tgt}'" + ) + endif() + list(GET name_parts -1 component_name) + set_target_properties( + "${_tgt}" + PROPERTIES EXPORT_NAME "${component_name}" + ) + message( + VERBOSE + "beman_install_library(${name}): EXPORT_NAME ${component_name} for TARGET '${_tgt}'" + ) + + # Get the list of interface header sets, exact one expected! + set(_install_header_set_args) + get_target_property( + _available_header_sets + ${_tgt} + INTERFACE_HEADER_SETS + ) + if(_available_header_sets) + message( + VERBOSE + "beman-install-library(${name}): '${_tgt}' has INTERFACE_HEADER_SETS=${_available_header_sets}" + ) + foreach(_install_header_set IN LISTS _available_header_sets) + list( + APPEND _install_header_set_args + FILE_SET + "${_install_header_set}" + COMPONENT + "${install_component_name}_Development" + ) + endforeach() + else() + set(_install_header_set_args FILE_SET HEADERS) # Note: empty FILE_SET in this case! CK + endif() + + # Detect presence of PUBLIC C++ module file sets. Note: exact one is expected! + get_target_property(_module_sets "${_tgt}" INTERFACE_CXX_MODULE_SETS) + if(_module_sets) + message( + VERBOSE + "beman-install-library(${name}): '${_tgt}' has INTERFACE_CXX_MODULE_SETS=${_module_sets}" + ) + install( + TARGETS "${_tgt}" + EXPORT ${BEMAN_INSTALL_EXPORT_NAME} + ARCHIVE COMPONENT "${install_component_name}_Development" + LIBRARY + COMPONENT "${install_component_name}_Runtime" + NAMELINK_COMPONENT "${install_component_name}_Development" + RUNTIME COMPONENT "${install_component_name}_Runtime" + ${_install_header_set_args} + FILE_SET ${_module_sets} + DESTINATION "${BEMAN_INSTALL_DESTINATION}" + COMPONENT "${install_component_name}_Development" + # NOTE: There's currently no convention for this location! CK + CXX_MODULES_BMI + DESTINATION + ${_config_install_dir}/bmi-${CMAKE_CXX_COMPILER_ID}_$ + COMPONENT "${install_component_name}_Development" + ) + else() + install( + TARGETS "${_tgt}" + EXPORT ${BEMAN_INSTALL_EXPORT_NAME} + ARCHIVE COMPONENT "${install_component_name}_Development" + LIBRARY + COMPONENT "${install_component_name}_Runtime" + NAMELINK_COMPONENT "${install_component_name}_Development" + RUNTIME COMPONENT "${install_component_name}_Runtime" + ${_install_header_set_args} + ) + endif() + endforeach() + + # -------------------------------------------------- + # Export targets + # -------------------------------------------------- + # gersemi: off + install( + EXPORT ${BEMAN_INSTALL_EXPORT_NAME} + NAMESPACE ${BEMAN_INSTALL_NAMESPACE} + CXX_MODULES_DIRECTORY cxx-modules + DESTINATION ${_config_install_dir} + COMPONENT "${install_component_name}_Development" + ) + # gersemi: on + + # ---------------------------------------- + # Config file installation logic + # + # Precedence (highest to lowest): + # 1. Per-package variable _INSTALL_CONFIG_FILE_PACKAGE + # 2. Allow-list BEMAN_INSTALL_CONFIG_FILE_PACKAGES (if defined) + # 3. Default: ON + # ---------------------------------------- + string(TOUPPER "${name}" _pkg_upper) + string(REPLACE "." "_" _pkg_prefix "${_pkg_upper}") + + option( + ${_pkg_prefix}_INSTALL_CONFIG_FILE_PACKAGE + "Enable creating and installing a CMake config-file package. Default: ON. Values: { ON, OFF }." + ON + ) + + set(_pkg_var "${_pkg_prefix}_INSTALL_CONFIG_FILE_PACKAGE") + + # Default: install config files + set(_install_config ON) + + # If the allow-list is defined, only install for packages in the list + if(DEFINED BEMAN_INSTALL_CONFIG_FILE_PACKAGES) + if(NOT "${name}" IN_LIST BEMAN_INSTALL_CONFIG_FILE_PACKAGES) + set(_install_config OFF) + endif() + endif() + + # Per-package override takes highest precedence + if(DEFINED ${_pkg_var}) + set(_install_config ${${_pkg_var}}) + endif() + + # ---------------------------------------- + # expand dependencies + # ---------------------------------------- + set(_beman_find_deps "") + foreach(dep IN LISTS BEMAN_INSTALL_DEPENDENCIES) + message( + VERBOSE + "beman-install-library(${name}): Add find_dependency(${dep})" + ) + string(APPEND _beman_find_deps "find_dependency(${dep})\n") + endforeach() + set(BEMAN_INSTALL_FIND_DEPENDENCIES "${_beman_find_deps}") + + # ---------------------------------------- + # Generate + install config files + # ---------------------------------------- + if(_install_config) + set(BEMAN_INSTALL_BASE_PKG_NAME ${name}) + configure_package_config_file( + "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/Config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/${name}-config.cmake" + INSTALL_DESTINATION ${_config_install_dir} + ) + + write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${name}-config-version.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion + ) + + install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/${name}-config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${name}-config-version.cmake" + DESTINATION ${_config_install_dir} + COMPONENT "${install_component_name}_Development" + ) + else() + message( + WARNING + "beman-install-library(${name}): Not installing a config package for '${name}'" + ) + endif() +endfunction() + +set(CPACK_GENERATOR TGZ) +include(CPack) diff --git a/infra/cmake/gnu-toolchain.cmake b/infra/cmake/gnu-toolchain.cmake new file mode 100644 index 0000000..d3b9f92 --- /dev/null +++ b/infra/cmake/gnu-toolchain.cmake @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This toolchain file is not meant to be used directly, +# but to be invoked by CMake preset and GitHub CI. +# +# This toolchain file configures for GNU family of compiler. +# +# BEMAN_BUILDSYS_SANITIZER: +# This optional CMake parameter is not meant for public use and is subject to +# change. +# Possible values: +# - MaxSan: configures gcc and g++ to use all available non-conflicting +# sanitizers. +# - TSan: configures gcc and g++ to enable the use of thread sanitizer + +include_guard(GLOBAL) + +set(CMAKE_C_COMPILER gcc) +set(CMAKE_CXX_COMPILER g++) + +if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") + set(SANITIZER_FLAGS + "-fsanitize=address -fsanitize=leak -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined -fsanitize-undefined-trap-on-error" + ) +elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") + set(SANITIZER_FLAGS "-fsanitize=thread") +endif() + +set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") +set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") + +set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") + +set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") + +set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") + +# Add this dir to the module path so that `find_package(beman-install-library)` works +list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/infra/cmake/llvm-libc++-toolchain.cmake b/infra/cmake/llvm-libc++-toolchain.cmake new file mode 100644 index 0000000..76264c6 --- /dev/null +++ b/infra/cmake/llvm-libc++-toolchain.cmake @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: BSL-1.0 + +# This toolchain file is not meant to be used directly, +# but to be invoked by CMake preset and GitHub CI. +# +# This toolchain file configures for LLVM family of compiler. +# +# BEMAN_BUILDSYS_SANITIZER: +# This optional CMake parameter is not meant for public use and is subject to +# change. +# Possible values: +# - MaxSan: configures clang and clang++ to use all available non-conflicting +# sanitizers. +# - TSan: configures clang and clang++ to enable the use of thread sanitizer. + +include(${CMAKE_CURRENT_LIST_DIR}/llvm-toolchain.cmake) + +if(NOT CMAKE_CXX_FLAGS MATCHES "-stdlib=libc\\+\\+") + string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++") +endif() diff --git a/infra/cmake/llvm-toolchain.cmake b/infra/cmake/llvm-toolchain.cmake new file mode 100644 index 0000000..f1623b7 --- /dev/null +++ b/infra/cmake/llvm-toolchain.cmake @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This toolchain file is not meant to be used directly, +# but to be invoked by CMake preset and GitHub CI. +# +# This toolchain file configures for LLVM family of compiler. +# +# BEMAN_BUILDSYS_SANITIZER: +# This optional CMake parameter is not meant for public use and is subject to +# change. +# Possible values: +# - MaxSan: configures clang and clang++ to use all available non-conflicting +# sanitizers. +# - TSan: configures clang and clang++ to enable the use of thread sanitizer. + +include_guard(GLOBAL) + +set(CMAKE_C_COMPILER clang) +set(CMAKE_CXX_COMPILER clang++) + +if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") + set(SANITIZER_FLAGS + "-fsanitize=address -fsanitize=leak -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined -fsanitize-undefined-trap-on-error" + ) +elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") + set(SANITIZER_FLAGS "-fsanitize=thread") +endif() + +set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") +set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") + +set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") + +set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") + +set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") + +# Add this dir to the module path so that `find_package(beman-install-library)` works +list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/infra/cmake/msvc-toolchain.cmake b/infra/cmake/msvc-toolchain.cmake new file mode 100644 index 0000000..bdc24de --- /dev/null +++ b/infra/cmake/msvc-toolchain.cmake @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This toolchain file is not meant to be used directly, +# but to be invoked by CMake preset and GitHub CI. +# +# This toolchain file configures for MSVC family of compiler. +# +# BEMAN_BUILDSYS_SANITIZER: +# This optional CMake parameter is not meant for public use and is subject to +# change. +# Possible values: +# - MaxSan: configures cl to use all available non-conflicting sanitizers. +# +# Note that in other toolchain files, TSan is also a possible value for +# BEMAN_BUILDSYS_SANITIZER, however, MSVC does not support thread sanitizer, +# thus this value is omitted. + +include_guard(GLOBAL) + +set(CMAKE_C_COMPILER cl) +set(CMAKE_CXX_COMPILER cl) + +if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") + # /Zi flag (add debug symbol) is needed when using address sanitizer + # See C5072: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-c5072 + set(SANITIZER_FLAGS "/fsanitize=address /Zi") +endif() + +set(CMAKE_CXX_FLAGS_DEBUG_INIT "/EHsc /permissive- ${SANITIZER_FLAGS}") +set(CMAKE_C_FLAGS_DEBUG_INIT "/EHsc /permissive- ${SANITIZER_FLAGS}") + +set(RELEASE_FLAGS "/EHsc /permissive- /O2 ${SANITIZER_FLAGS}") + +set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") + +set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") + +# Add this dir to the module path so that `find_package(beman-install-library)` works +list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/infra/cmake/telemetry.sh b/infra/cmake/telemetry.sh new file mode 100755 index 0000000..307cc94 --- /dev/null +++ b/infra/cmake/telemetry.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash + +set -o nounset +set -o errexit +trap 'echo "Aborting due to errexit on line $LINENO. Exit code: $?" >&2' ERR +set -o errtrace +set -o pipefail +IFS=$'\n\t' + +############################################################################### +# Environment +############################################################################### + +# $_ME +# +# This program's basename. +_ME="$(basename "${0}")" + +############################################################################### +# Help +############################################################################### + +# _print_help() +# +# Usage: +# _print_help +# +# Print the program help information. +_print_help() { + cat <] + ${_ME} -h | --help + +Options: + -h --help Show this screen. + +Environment: + Setting DEBUG_TELEMETRY in the environment will enable DEBUG logging +HEREDOC +} + +############################################################################### +# Program Functions +############################################################################### +_debug_print() { + if [[ -n "${DEBUG_TELEMETRY:-}" ]]; then + printf "[DEBUG] $(date +'%H:%M:%S'): %s \n" "$1" >&2 + fi +} + +_check_file_exists() { + local file="$1" + if [[ ! -f "${file}" ]]; then + echo "Error: File not found: ${file}" >&2 + exit 1 # Exit the entire script with a non-zero status + fi +} + +_process_index() { + indexFile=${1:-} + _check_file_exists "${indexFile}" + _debug_print "$(cat "${indexFile}")" + + local buildDir + buildDir=$(jq -r '.buildDir' "${1:-}") + _debug_print "$(printf "buildDir is |%q|" "${buildDir}")" + + local dataDir + dataDir=$(jq -r '.dataDir' "${1:-}") + _debug_print "$(printf "dataDir is |%q|" "${dataDir}")" + + local hook + hook=$(jq -r '.hook' "${1:-}") + _debug_print "$(printf "hook is |%q|" "${hook}")" + + local trace + trace=$(jq -r '.trace' "${1:-}") + _debug_print "$(printf "trace is |%q|" "${trace}")" + + local outputDir + outputDir="${buildDir}/.trace" + _debug_print "$(printf "Copy trace to |%q|" "${outputDir}")" + mkdir -p "${outputDir}" + + local traceDestFile + traceDestFile="${outputDir}/${hook}-$(basename "${trace}")" + _debug_print "$(printf "traceDestFile: |%q|" "${traceDestFile}")" + cp "${dataDir}/${trace}" "${outputDir}/${hook}-$(basename "${trace}")" +} + +############################################################################### +# Main +############################################################################### + +# _main() +# +# Usage: +# _main [] [] +# +# Description: +# Entry point for the program, handling basic option parsing and dispatching. +_main() { + # Avoid complex option parsing when only one program option is expected. + if [[ "${1:-}" =~ ^-h|--help$ ]] + then + _print_help + else + _process_index "$@" + fi +} + +# Call `_main` after everything has been defined. +_main "$@" diff --git a/infra/cmake/use-fetch-content.cmake b/infra/cmake/use-fetch-content.cmake new file mode 100644 index 0000000..0564513 --- /dev/null +++ b/infra/cmake/use-fetch-content.cmake @@ -0,0 +1,231 @@ +cmake_minimum_required(VERSION 3.24) + +include(FetchContent) + +if(NOT BEMAN_EXEMPLAR_LOCKFILE) + set(BEMAN_EXEMPLAR_LOCKFILE + "lockfile.json" + CACHE FILEPATH + "Path to the dependency lockfile for the Beman Exemplar." + ) +endif() + +set(BemanExemplar_projectDir "${CMAKE_CURRENT_LIST_DIR}/../..") +message(TRACE "BemanExemplar_projectDir=\"${BemanExemplar_projectDir}\"") + +message(TRACE "BEMAN_EXEMPLAR_LOCKFILE=\"${BEMAN_EXEMPLAR_LOCKFILE}\"") +file( + REAL_PATH "${BEMAN_EXEMPLAR_LOCKFILE}" + BemanExemplar_lockfile + BASE_DIRECTORY "${BemanExemplar_projectDir}" + EXPAND_TILDE +) +message(DEBUG "Using lockfile: \"${BemanExemplar_lockfile}\"") + +# Force CMake to reconfigure the project if the lockfile changes +set_property( + DIRECTORY "${BemanExemplar_projectDir}" + APPEND + PROPERTY CMAKE_CONFIGURE_DEPENDS "${BemanExemplar_lockfile}" +) + +# For more on the protocol for this function, see: +# https://cmake.org/cmake/help/latest/command/cmake_language.html#provider-commands +function(BemanExemplar_provideDependency method package_name) + # Read the lockfile + file(READ "${BemanExemplar_lockfile}" BemanExemplar_rootObj) + + # Get the "dependencies" field and store it in BemanExemplar_dependenciesObj + string( + JSON BemanExemplar_dependenciesObj + ERROR_VARIABLE BemanExemplar_error + GET "${BemanExemplar_rootObj}" + "dependencies" + ) + if(BemanExemplar_error) + message(FATAL_ERROR "${BemanExemplar_lockfile}: ${BemanExemplar_error}") + endif() + + # Get the length of the libraries array and store it in BemanExemplar_dependenciesObj + string( + JSON BemanExemplar_numDependencies + ERROR_VARIABLE BemanExemplar_error + LENGTH "${BemanExemplar_dependenciesObj}" + ) + if(BemanExemplar_error) + message(FATAL_ERROR "${BemanExemplar_lockfile}: ${BemanExemplar_error}") + endif() + + if(BemanExemplar_numDependencies EQUAL 0) + return() + endif() + + # Loop over each dependency object + math(EXPR BemanExemplar_maxIndex "${BemanExemplar_numDependencies} - 1") + foreach(BemanExemplar_index RANGE "${BemanExemplar_maxIndex}") + set(BemanExemplar_errorPrefix + "${BemanExemplar_lockfile}, dependency ${BemanExemplar_index}" + ) + + # Get the dependency object at BemanExemplar_index + # and store it in BemanExemplar_depObj + string( + JSON BemanExemplar_depObj + ERROR_VARIABLE BemanExemplar_error + GET "${BemanExemplar_dependenciesObj}" + "${BemanExemplar_index}" + ) + if(BemanExemplar_error) + message( + FATAL_ERROR + "${BemanExemplar_errorPrefix}: ${BemanExemplar_error}" + ) + endif() + + # Get the "name" field and store it in BemanExemplar_name + string( + JSON BemanExemplar_name + ERROR_VARIABLE BemanExemplar_error + GET "${BemanExemplar_depObj}" + "name" + ) + if(BemanExemplar_error) + message( + FATAL_ERROR + "${BemanExemplar_errorPrefix}: ${BemanExemplar_error}" + ) + endif() + + # Get the "package_name" field and store it in BemanExemplar_pkgName + string( + JSON BemanExemplar_pkgName + ERROR_VARIABLE BemanExemplar_error + GET "${BemanExemplar_depObj}" + "package_name" + ) + if(BemanExemplar_error) + message( + FATAL_ERROR + "${BemanExemplar_errorPrefix}: ${BemanExemplar_error}" + ) + endif() + + # Get the "git_repository" field and store it in BemanExemplar_repo + string( + JSON BemanExemplar_repo + ERROR_VARIABLE BemanExemplar_error + GET "${BemanExemplar_depObj}" + "git_repository" + ) + if(BemanExemplar_error) + message( + FATAL_ERROR + "${BemanExemplar_errorPrefix}: ${BemanExemplar_error}" + ) + endif() + + # Get the "git_tag" field and store it in BemanExemplar_tag + string( + JSON BemanExemplar_tag + ERROR_VARIABLE BemanExemplar_error + GET "${BemanExemplar_depObj}" + "git_tag" + ) + if(BemanExemplar_error) + message( + FATAL_ERROR + "${BemanExemplar_errorPrefix}: ${BemanExemplar_error}" + ) + endif() + + if(method STREQUAL "FIND_PACKAGE") + if(package_name STREQUAL BemanExemplar_pkgName) + string( + APPEND BemanExemplar_debug + "Redirecting find_package calls for ${BemanExemplar_pkgName} " + "to FetchContent logic.\n" + ) + string( + APPEND BemanExemplar_debug + "Fetching ${BemanExemplar_repo} at " + "${BemanExemplar_tag} according to ${BemanExemplar_lockfile}." + ) + message(DEBUG "${BemanExemplar_debug}") + FetchContent_Declare( + "${BemanExemplar_name}" + GIT_REPOSITORY "${BemanExemplar_repo}" + GIT_TAG "${BemanExemplar_tag}" + EXCLUDE_FROM_ALL + ) + + # Apply per-dependency cmake_args from the lockfile + string( + JSON BemanExemplar_cmakeArgs + ERROR_VARIABLE BemanExemplar_cmakeArgsError + GET "${BemanExemplar_depObj}" + "cmake_args" + ) + if(NOT BemanExemplar_cmakeArgsError) + string( + JSON BemanExemplar_numCmakeArgs + LENGTH "${BemanExemplar_cmakeArgs}" + ) + if(BemanExemplar_numCmakeArgs GREATER 0) + math( + EXPR + BemanExemplar_maxArgIndex + "${BemanExemplar_numCmakeArgs} - 1" + ) + foreach( + BemanExemplar_argIndex + RANGE "${BemanExemplar_maxArgIndex}" + ) + string( + JSON BemanExemplar_argKey + MEMBER "${BemanExemplar_cmakeArgs}" + "${BemanExemplar_argIndex}" + ) + string( + JSON BemanExemplar_argValue + GET "${BemanExemplar_cmakeArgs}" + "${BemanExemplar_argKey}" + ) + message( + DEBUG + "Setting ${BemanExemplar_argKey}=${BemanExemplar_argValue} for ${BemanExemplar_name}" + ) + set("${BemanExemplar_argKey}" + "${BemanExemplar_argValue}" + ) + endforeach() + endif() + endif() + + FetchContent_MakeAvailable("${BemanExemplar_name}") + + # Catch2's CTest integration module isn't on CMAKE_MODULE_PATH + # when brought in via FetchContent. Add it so that + # `include(Catch)` works. + if(BemanExemplar_pkgName STREQUAL "Catch2") + list( + APPEND CMAKE_MODULE_PATH + "${${BemanExemplar_name}_SOURCE_DIR}/extras" + ) + set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE) + endif() + + # Important! _FOUND tells CMake that `find_package` is + # not needed for this package anymore + set("${BemanExemplar_pkgName}_FOUND" TRUE PARENT_SCOPE) + endif() + endif() + endforeach() +endfunction() + +cmake_language( + SET_DEPENDENCY_PROVIDER BemanExemplar_provideDependency + SUPPORTED_METHODS FIND_PACKAGE +) + +# Add this dir to the module path so that `find_package(beman-install-library)` works +list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/lockfile.json b/lockfile.json new file mode 100644 index 0000000..787b905 --- /dev/null +++ b/lockfile.json @@ -0,0 +1,13 @@ +{ + "dependencies": [ + { + "name": "googletest", + "package_name": "GTest", + "git_repository": "https://github.com/google/googletest.git", + "git_tag": "6910c9d9165801d8827d628cb72eb7ea9dd538c5", + "cmake_args": { + "INSTALL_GTEST": "OFF" + } + } + ] +} diff --git a/src/beman/iterator_interface/CMakeLists.txt b/src/beman/iterator_interface/CMakeLists.txt deleted file mode 100644 index fbad15c..0000000 --- a/src/beman/iterator_interface/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -# cmake-format: off -# src/beman/iterator_interface/CMakeLists.txt -*-cmake-*- -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on - -# Ensure that iterator_interface gets compiled at least once. -target_sources(beman.iterator_interface PUBLIC iterator_interface.cpp) - -# The library is empty -- exclude it -install( - TARGETS beman.iterator_interface - ARCHIVE - DESTINATION ${CMAKE_INSTALL_LIBDIR} - COMPONENT beman.iterator_interface.library - EXCLUDE_FROM_ALL -) - -install( - TARGETS beman.iterator_interface - FILE_SET beman_iterator_interface_headers - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - COMPONENT beman_iterator_interface_development -) diff --git a/src/beman/iterator_interface/iterator_interface.cpp b/src/beman/iterator_interface/iterator_interface.cpp deleted file mode 100644 index 5250763..0000000 --- a/src/beman/iterator_interface/iterator_interface.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// src/beman/iterator_interface/iterator_interface.cpp -*-C++-*- -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include diff --git a/tests/beman/iterator_interface/CMakeLists.txt b/tests/beman/iterator_interface/CMakeLists.txt index 14375ab..c379d80 100644 --- a/tests/beman/iterator_interface/CMakeLists.txt +++ b/tests/beman/iterator_interface/CMakeLists.txt @@ -1,31 +1,16 @@ -# cmake-format: off -# tests/beman/iterator_interface/CMakeLists.txt -*-cmake-*- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake-format: on -include(GoogleTest) +find_package(GTest REQUIRED) add_executable(beman.iterator_interface.tests) - target_sources( beman.iterator_interface.tests PRIVATE iterator_interface.test.cpp ) - -target_sources( - beman.iterator_interface.tests - PRIVATE FILE_SET beman_iterator_interface_tests_headers TYPE HEADERS -) - target_link_libraries( beman.iterator_interface.tests - PRIVATE beman::iterator_interface GTest::gtest GTest::gtest_main + PRIVATE beman::iterator_interface GTest::gtest_main ) -# [Issue #18](https://github.com/bemanproject/iterator_interface/issues/18): -# Re-enable ASAN run CI/clang-19. -# -# Note: clang-19 + gtest_discover_tests + Asan setup causes errors on some -# platforms. Temporary switch to gtest_add_tests and skip some Asan checks. -# Change also applied for CI flows. -gtest_add_tests(TARGET beman.iterator_interface.tests "" AUTO) +include(GoogleTest) +gtest_discover_tests(beman.iterator_interface.tests) diff --git a/tests/beman/iterator_interface/iterator_interface.test.cpp b/tests/beman/iterator_interface/iterator_interface.test.cpp index 86968f7..1edc550 100644 --- a/tests/beman/iterator_interface/iterator_interface.test.cpp +++ b/tests/beman/iterator_interface/iterator_interface.test.cpp @@ -162,10 +162,9 @@ struct AlwaysIterator auto operator-(AlwaysIterator other) const { return n_ - other.n_; } private: - ClassWithMemberFunction value_; - const char* first_; - difference_type size_; - difference_type n_; + ClassWithMemberFunction value_; + [[maybe_unused]] difference_type size_; + difference_type n_; }; // Confirm operator-> works as expected