diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 7285f129..b8859d05 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -9,14 +9,18 @@ on: pull_request: workflow_dispatch: schedule: - - cron: '30 15 * * *' + - cron: '30 15 * * 6' + +concurrency: + group: ${{format('{0}:{1}', github.repository, github.ref)}} + cancel-in-progress: true jobs: beman-submodule-check: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-submodule-check.yml@1.3.0 + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-submodule-check.yml@1.7.3 preset-test: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.3.0 + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.7.3 with: matrix_config: > [ @@ -29,33 +33,45 @@ jobs: ] build-and-test: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-build-and-test.yml@1.3.0 + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-build-and-test.yml@1.7.3 with: matrix_config: > { "gcc": [ - { "versions": ["15"], + { "versions": ["16"], "tests": [ { "cxxversions": ["c++26"], "tests": [ { "stdlibs": ["libstdc++"], "tests": [ - "Debug.Default", "Release.Default", "Release.MaxSan", - "Debug.Coverage", "Debug.Werror", - "Debug.Dynamic", "Release.Dynamic" + "Debug.Default", "Release.Default", "Release.TSan", + "Release.MaxSan", "Debug.Werror", + "Debug.Coverage", "Debug.-DBEMAN_USE_MODULES=On" ] } ] }, { "cxxversions": ["c++23"], - "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] + "tests": [ + { "stdlibs": ["libstdc++"], + "tests": [ + "Release.Default", "Debug.-DBEMAN_USE_MODULES=On" + ] + } + ] } ] }, - { "versions": ["14"], + { "versions": ["15"], "tests": [ { "cxxversions": ["c++26", "c++23"], - "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] + "tests": [ + { "stdlibs": ["libstdc++"], + "tests": [ + "Release.Default", "Debug.-DBEMAN_USE_MODULES=On" + ] + } + ] } ] } @@ -67,15 +83,20 @@ jobs: "tests": [ { "stdlibs": ["libc++"], "tests": [ - "Debug.Default", "Release.Default", "Release.MaxSan", - "Debug.Dynamic", "Release.Dynamic" + "Debug.Default", "Release.Default", "Release.TSan", + "Release.MaxSan", "Debug.Werror", + "Debug.-DBEMAN_USE_MODULES=On" ] } ] }, { "cxxversions": ["c++23"], "tests": [ - {"stdlibs": ["libc++"], "tests": ["Release.Default"]} + { "stdlibs": ["libc++"], + "tests": [ + "Release.Default", "Debug.-DBEMAN_USE_MODULES=On" + ] + } ] } ] @@ -96,8 +117,9 @@ jobs: { "cxxversions": ["c++23"], "tests": [ { "stdlibs": ["stl"], - "tests": ["Debug.Default", "Release.Default", "Release.MaxSan", - "Debug.Dynamic", "Release.Dynamic" + "tests": [ + "Debug.Default", "Release.Default", "Release.MaxSan", + "Debug.-DBEMAN_USE_MODULES=On" ] } ] @@ -110,4 +132,4 @@ jobs: 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.3.0 + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-create-issue-when-fault.yml@1.7.3 diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml index 930b750c..53825d40 100644 --- a/.github/workflows/pre-commit-update.yml +++ b/.github/workflows/pre-commit-update.yml @@ -9,7 +9,7 @@ on: jobs: auto-update-pre-commit: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-update-pre-commit.yml@1.3.0 + uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-update-pre-commit.yml@1.7.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 bc32eb4a..3156a8c3 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ cmake-build-* .cache .vscode .idea +.init compile_commands.json stagedir diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 117f209e..2ff9a1b6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: # Config file: .codespellrc - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 + rev: v2.4.3 hooks: - id: codespell files: ^.*\.(cmake|cpp|cppm|hpp|txt|md|mds|json|js|in|yaml|yml|py|toml)$ @@ -49,7 +49,7 @@ repos: # Config file: pyproject.toml # first Python sort imports - repo: https://github.com/pycqa/isort - rev: 9.0.0a3 + rev: 9.0.0b1 hooks: - id: isort diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e01bc92..3d80e7dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,8 +19,6 @@ set(BEMAN_EXECUTION_TARGET_PREFIX ${PROJECT_NAME}) # NOTE: used in src, and docs #=============================================================================== if(BEMAN_USE_MODULES) - option(BUILD_SHARED_LIBS "Build using shared libraries" OFF) - set(CMAKE_CXX_SCAN_FOR_MODULES ON) set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) @@ -61,14 +59,6 @@ if(BEMAN_USE_MODULES) DLL_NAME_WITH_SOVERSION TRUE ) - # FIXME: Quickfix only to prevent linker problems on windows dll? CK - if(WIN32 AND BUILD_SHARED_LIBS) - set_target_properties( - ${BEMAN_EXECUTION_TARGET_PREFIX} - PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON - ) - endif() - find_package(Threads REQUIRED) target_link_libraries( ${BEMAN_EXECUTION_TARGET_PREFIX} diff --git a/CMakePresets.json b/CMakePresets.json index 224619b9..084d7180 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -90,7 +90,7 @@ "_release-base" ], "cacheVariables": { - "BEMAN_USE_STD_MODULE": false, + "BEMAN_USE_STD_MODULE": true, "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/infra/cmake/llvm-libc++-toolchain.cmake" }, "environment": { diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 00000000..c739feee --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,63 @@ +# GNUmakefile +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +MAKEFLAGS+= --no-builtin-rules # Disable the built-in implicit rules. +MAKEFLAGS+= --no-builtin-variables # Disable the built-in variable settings. +MAKEFLAGS+= --warn-undefined-variables # Warn when an undefined variable is referenced. +.SUFFIXES: # Disable all suffix rules. +################################################## + +PRESET ?= release +IMAGE ?= linux-clang:23 + +_build_path:=build/$(PRESET) + +.PHONY: all check distclean dockerbuild + +# default target rule +all: .init compile_commands.json ## Make all with cmake workflow preset + cmake --workflow --preset $(PRESET) + +.init: CMakeUserPresets.json CMakePresets.json CMakeLists.txt ## Configure cmake preset in VERBOSE mode + cmake --preset $(PRESET) --fresh --log-level=VERBOSE + touch $@ + +check: .init compile_commands.json ## Run clang-tidy on examples + run-clang-tidy examples + +.PHONY: compile_commands.json +compile_commands.json: $(_build_path)/compile_commands.json + if [ "$(shell readlink compile_commands.json)" != "$(_build_path)/compile_commands.json" ] ; then \ + ln -fs $< $@ + fi + +CMakeUserPresets.json:: cmake/CMakeUserPresets.json + ln -fs $< $@ + +distclean: ## Remove all build artifacts + rm -rf build .cache + rm -f CMakeUserPresets.json \ + compile_commands.json \ + .init + find . -name '*~' -delete + +dockerbuild: ## Start docker image interactive + docker run -it -v $(CURDIR):/home/builder/workdir $(IMAGE) + +# Helper targets +.PHONY: env info + +env: ## Show env + $(foreach v, $(.VARIABLES), $(info $(v) = $($(v)))) + +info: ## Show this help. + @awk 'BEGIN {FS = ":.*?## "} /^[.a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort + +# NOTE: double-colon targets which has no prerequisites must always remade by gmake? +# Prerequisite 'GNUmakefile' is newer than target '.init'. +# -> Must remake target '.init'. +# NOTE: impizit handled by gmake! GNUmakefile :: ; + +# Anything we don't know how to build will use this rule. +% :: + ninja -C $(_build_path) $(@) diff --git a/Makefile b/Makefile index 218730ec..ed03c97c 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ ifeq (${hostSystemName},Darwin) # export LDFLAGS=-L$(LLVM_DIR)/lib/c++ -lc++abi -lc++ # -lc++experimental # export GCOV="llvm-cov gcov" - ### TODO: to test g++-15: + ### TODO: to test g++-16: # export GCC_PREFIX:=$(shell brew --prefix gcc) # export GCC_DIR:=$(shell realpath ${GCC_PREFIX}) @@ -63,16 +63,16 @@ ifeq (${hostSystemName},Darwin) export CXX=clang++ CXXLIB=libc++ else - export CXX=g++-15 + export CXX=g++-16 CXXLIB=libstdc++ endif export CXX_FLAGS=-stdlib=$(CXXLIB) endif export GCOV="gcov" else ifeq (${hostSystemName},Linux) - export LLVM_DIR=/usr/lib/llvm-20 + export LLVM_DIR=/usr/lib/llvm-23 export PATH:=${LLVM_DIR}/bin:${PATH} - # export CXX=clang++-20 + # NO! export CXX=clang++-23 else export CXX=$(COMPILER) endif diff --git a/cmake/README.md b/cmake/README.md deleted file mode 100644 index 182a47a1..00000000 --- a/cmake/README.md +++ /dev/null @@ -1,393 +0,0 @@ - - -# CMake Support for Header-Only Libraries and C++ Modules - -This directory provides a small set of CMake helper modules that make it easier -to **build and install a library that works both with and without C++20 -modules**. - -The helpers wrap CMake’s evolving support for `FILE_SET CXX_MODULE` and package -installation so that: - -- consumers can use the library in **classic header-only mode**, or - -- consumers with a compatible toolchain can use **C++ modules**, including - optional `import std;` support. - -The goal is to keep project `CMakeLists.txt` files readable while hiding most of -the platform- and compiler-specific complexity. - ---- - -## Motivation - -Today, supporting C++ modules often requires duplicating targets and custom -install logic: - -- one target for headers only, -- another target that owns module interface units, -- conditional logic depending on compiler and CMake version, -- non-trivial install/export rules. - -The helpers in this directory centralize that logic and provide a single, -consistent API for projects that want to offer both usage models. - ---- - -## Provided CMake Modules - -The following modules are expected to live in `infra/cmake`: - -- `prelude.cmake` - Common project setup and option handling. - -- `cxx-modules-rules.cmake` - Compiler and CMake feature checks related to C++ modules. - -- `beman-install-library.cmake` - High-level helper to install libraries, headers, module interface units, and CMake package files. - -- `Config.cmake.in` - Template used to generate the `-config.cmake` file for consumers. - ---- - -## New Configuration Options - - * BEMAN_USE_MODULES:BOOL=ON - * BEMAN_USE_STD_MODULE:BOOL=OFF - * BEMAN_HAS_IMPORT_STD::BOOL=${CMAKE_CXX_SCAN_FOR_MODULES} # only if toolchain supports it. - -### The recommended usage in CMake code - -```cmake -if(CMAKE_CXX_STANDARD GREATER_EQUAL 20) - option(BEMAN_USE_MODULES "Build CXX_MODULES" ${CMAKE_CXX_SCAN_FOR_MODULES}) -endif() -if(BEMAN_USE_MODULES) - target_compile_definitions(beman.execution PUBLIC BEMAN_HAS_MODULES) -endif() - -BEMAN_USE_STD_MODULE:BOOL=ON -# -> "Check if 'import std;' is possible with the toolchain?" - -if(BEMAN_USE_MODULES AND BEMAN_HAS_IMPORT_STD) - target_compile_definitions(beman.execution PUBLIC BEMAN_HAS_IMPORT_STD) - set_target_properties(beman.execution PROPERTIES CXX_MODULE_STD ON) -endif() -``` - -Typical projects will only toggle `BEMAN_USE_MODULES`; the remaining options are -detected automatically. - ---- - -## Installing a Library - -Installation is handled by the `beman_install_library()` helper. - -### Function Signature - -```cmake -beman_install_library(name - 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** - Targets to install and export. - -- **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 imported targets. - Defaults to "beman::". - -- **EXPORT_NAME (optional)** - Name of the generated CMake export set. - Defaults to "-targets". - -- **DESTINATION (optional)** - Installation directory for C++ module interface units. - Defaults to `${CMAKE_INSTALL_INCLUDEDIR}/beman/modules`. - -This function installs the specified project TARGETS and its `FILE_SET -TYPE 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 `FILE_SET TYPE CXX_MODULE`, it will also -installed to the given DESTINATION - -- **Used 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 `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 - installed with this function!** - ---- - -## The possible usage in CMakeLists.txt - -```cmake -cmake_minimum_required(VERSION 3.30...4.2) - -include(./cmake/prelude.cmake) -project(beman.execution VERSION 0.2.0 LANGUAGES CXX) -include(./cmake/cxx-modules-rules.cmake) - -set(BEMAN_EXECUTION_TARGET_PREFIX ${PROJECT_NAME}) - -#=============================================================================== -if(BEMAN_USE_MODULES) - set(CMAKE_CXX_VISIBILITY_PRESET hidden) - set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) - - # CMake requires the language standard to be specified as compile feature - # when a target provides C++23 modules and the target will be installed - add_library(${BEMAN_EXECUTION_TARGET_PREFIX} STATIC) - add_library(beman::execution ALIAS ${BEMAN_EXECUTION_TARGET_PREFIX}) - target_compile_features( - ${BEMAN_EXECUTION_TARGET_PREFIX} - PUBLIC cxx_std_${CMAKE_CXX_STANDARD} - ) - - include(GenerateExportHeader) - generate_export_header( - ${BEMAN_EXECUTION_TARGET_PREFIX} - BASE_NAME ${BEMAN_EXECUTION_TARGET_PREFIX} - EXPORT_FILE_NAME beman/execution/modules_export.hpp - ) - target_sources( - ${BEMAN_EXECUTION_TARGET_PREFIX} - PUBLIC - FILE_SET HEADERS - BASE_DIRS include ${CMAKE_CURRENT_BINARY_DIR} - FILES - ${CMAKE_CURRENT_BINARY_DIR}/beman/execution/modules_export.hpp - ) - target_compile_definitions(${BEMAN_EXECUTION_TARGET_PREFIX} PUBLIC BEMAN_HAS_MODULES) -endif() - -if(BEMAN_USE_MODULES AND CMAKE_CXX_MODULE_STD) - target_compile_definitions(${BEMAN_EXECUTION_TARGET_PREFIX} PUBLIC BEMAN_HAS_IMPORT_STD) -else() - message(WARNING "Missing support for CMAKE_CXX_MODULE_STD!") -endif() -#=============================================================================== - -# ... - -# NOTE: this must be done before tests! CK -include(beman-install-library) -beman_install_library(${PROJECT_NAME} TARGETS ${BEMAN_EXECUTION_TARGET_PREFIX} beman.exemplar_headers # - # TODO(add): DEPENDENCIES [===[beman.inplace_vector 1.0.0]===] [===[beman.scope 0.0.1 EXACT]===] fmt -) -``` - ---- - -## Possible cmake config output - -**NOTE:** Exact output depend on the build host, used toolchain, and -whether module support is enabled and supported. - -```bash -bash-5.3$ make test-module -cmake -G Ninja -S /Users/clausklein/Workspace/cpp/beman-project/execution26 -B build/Darwin/default \ - -D CMAKE_EXPORT_COMPILE_COMMANDS=ON \ - -D CMAKE_SKIP_INSTALL_RULES=OFF \ - -D CMAKE_CXX_STANDARD=23 \ - -D CMAKE_CXX_EXTENSIONS=ON \ - -D CMAKE_CXX_STANDARD_REQUIRED=ON \ - -D CMAKE_CXX_SCAN_FOR_MODULES=ON \ - -D BEMAN_USE_MODULES=ON \ - -D CMAKE_BUILD_TYPE=Release \ - -D CMAKE_INSTALL_MESSAGE=LAZY \ - -D CMAKE_BUILD_TYPE=Release \ - -D CMAKE_CXX_COMPILER=clang++ --log-level=VERBOSE --- use ccache --- CXXFLAGS=-stdlib=libc++ -'brew' '--prefix' 'llvm' --- LLVM_DIR=/usr/local/Cellar/llvm/21.1.8 --- CMAKE_CXX_STDLIB_MODULES_JSON=/usr/local/Cellar/llvm/21.1.8/lib/c++/libc++.modules.json --- CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES=/usr/local/Cellar/llvm/21.1.8/include/c++/v1;/usr/local/Cellar/llvm/21.1.8/lib/clang/21/include;/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include --- CMAKE_CXX_STDLIB_MODULES_JSON=/usr/local/Cellar/llvm/21.1.8/lib/c++/libc++.modules.json --- BEMAN_USE_STD_MODULE=ON --- CMAKE_CXX_COMPILER_IMPORT_STD=23;26 --- CMAKE_CXX_MODULE_STD=ON --- BEMAN_HAS_IMPORT_STD=ON --- BEMAN_USE_MODULES=ON --- CMAKE_CXX_SCAN_FOR_MODULES=ON --- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY --- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success --- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY --- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success --- Performing Test COMPILER_HAS_DEPRECATED_ATTR --- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success --- beman_install_library(beman.execution): COMPONENT execution_headers for TARGET 'beman.execution_headers' --- beman-install-library(beman.execution): 'beman.execution_headers' has INTERFACE_HEADER_SETS=public_headers --- beman_install_library(beman.execution): COMPONENT execution for TARGET 'beman.execution' --- beman-install-library(beman.execution): 'beman.execution' has INTERFACE_HEADER_SETS=HEADERS --- beman-install-library(beman.execution): 'beman.execution' has CXX_MODULE_SETS=CXX_MODULES --- Configuring done (3.1s) -CMake Warning (dev) in CMakeLists.txt: - CMake's support for `import std;` in C++23 and newer is experimental. It - is meant only for experimentation and feedback to CMake developers. -This warning is for project developers. Use -Wno-dev to suppress it. - --- Generating done (0.4s) --- Build files have been written to: /Users/clausklein/Workspace/cpp/beman-project/execution26/build/Darwin/default -bash-5.3$ -``` - ---- - -## Possible cmake export config package - -**NOTE:** Exact contents depend on the build host, used toolchain, and -whether module support is enabled. - -```bash -cmake --install build/Darwin/default --prefix $PWD/stagedir - -bash-5.3$ cd stagedir/ -bash-5.3$ tree lib/ -lib/ -├── cmake -│   └── beman.execution -│   ├── beman.execution-config-version.cmake -│   ├── beman.execution-config.cmake -│   ├── beman.execution-targets-debug.cmake -│   ├── beman.execution-targets-relwithdebinfo.cmake -│   ├── beman.execution-targets.cmake -│   ├── bmi-GNU_Debug -│   │   └── beman.execution.gcm -│   ├── bmi-GNU_RelWithDebInfo -│   │   └── beman.execution.gcm -│   ├── cxx-modules -│   │   ├── cxx-modules-beman.execution-Debug.cmake -│   │   ├── cxx-modules-beman.execution-RelWithDebInfo.cmake -│   │   ├── cxx-modules-beman.execution.cmake -│   │   ├── target-execution-Debug.cmake -│   │   └── target-execution-RelWithDebInfo.cmake -│   └── modules -│   └── execution.cppm -├── libbeman.execution.a -└── libbeman.execution_d.a - -7 directories, 15 files -bash-5.3$ -``` - ---- - -## The recommended usage in implementation - -```cpp -// identity.cppm -module; - -#ifdef BEMAN_HAS_IMPORT_STD -import std; -#else -#include -#endif - -export module beman.exemplar; - -export namespace beman::exemplar { -struct __is_transparent; - -struct identity { - template - constexpr T&& operator()(T&& t) const noexcept { - return std::forward(t); - } - - using is_transparent = __is_transparent; -}; -} // namespace beman::exemplar -``` - ---- - -## The possible usage in user code - -```cpp -// example-usage.cpp - -#ifdef BEMAN_HAS_IMPORT_STD -import std; -#else -#include -#endif - -#ifdef BEMAN_HAS_MODULES -import beman.exemplar; -#else -#include -#endif - -int main() { - beman::exemplar::identity id; - - int x = 42; - int y = id(x); // y == 42 - - std::cout << y << '\n'; - return 0; -} -``` - ---- - -## Notes on CMake and Modules - -- `FILE_SET CXX_MODULE` support is still evolving and depends on the compiler - and CMake version. - -- Not all toolchains support installing or consuming prebuilt module interface - units yet. - -- These helpers aim to provide a pragmatic, forward-compatible structure rather - than a final standard solution. - ---- - -## Summary - -The helpers in this directory provide a structured way to: - -- build header-only and module-based libraries side by side, -- hide compiler- and platform-specific complexity, -- install and export targets in a consistent, consumer-friendly way. - -They are intended for projects that want to experiment with C++ modules today -while remaining usable on traditional toolchains. diff --git a/cmake/cxx-modules-rules.cmake b/cmake/cxx-modules-rules.cmake index 91939b36..b6c50c29 100644 --- a/cmake/cxx-modules-rules.cmake +++ b/cmake/cxx-modules-rules.cmake @@ -65,7 +65,11 @@ if(CMAKE_GENERATOR MATCHES "Ninja") string(APPEND CMAKE_CXX_MODULE_MAP_FLAG " -fmodules-reduced-bmi") endif() - add_compile_options($ENV{CXXFLAGS}) + add_compile_options( + $ENV{CXXFLAGS} + -Wno-missing-braces + -Wno-unneeded-internal-declaration + ) add_link_options($ENV{CXXFLAGS}) elseif( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" @@ -95,12 +99,14 @@ if(CMAKE_CXX_STANDARD GREATER_EQUAL 20) endif() message(STATUS "BEMAN_USE_MODULES=${BEMAN_USE_MODULES}") -option( - BEMAN_USE_STD_MODULE - "Check if 'import std;' is possible with the toolchain?" - OFF -) -message(STATUS "BEMAN_USE_STD_MODULE=${BEMAN_USE_STD_MODULE}") +if(CMAKE_CXX_STANDARD GREATER_EQUAL 23) + option( + BEMAN_USE_STD_MODULE + "Check if 'import std;' is possible with the toolchain?" + ON + ) + message(STATUS "BEMAN_USE_STD_MODULE=${BEMAN_USE_STD_MODULE}") +endif() if(BEMAN_USE_MODULES AND BEMAN_USE_STD_MODULE) # ------------------------------------------------------------------------- diff --git a/cmake/prelude.cmake b/cmake/prelude.cmake index de91a0b5..2d9a5c13 100644 --- a/cmake/prelude.cmake +++ b/cmake/prelude.cmake @@ -21,7 +21,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) # --------------------------------------------------------------------------- # The CMAKE_EXPERIMENTAL_CXX_IMPORT_STD is not longer needed except for OSX # --------------------------------------------------------------------------- -if(NOT BEMAN_USE_STD_MODULE OR CMAKE_VERSION VERSION_GREATER_EQUAL 4.4) +if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.5) if(NOT APPLE) return() endif() @@ -31,7 +31,7 @@ endif() # --------------------------------------------------------------------------- # check if import std; is supported by CMAKE_CXX_COMPILER # --------------------------------------------------------------------------- -if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.2 AND CMAKE_VERSION VERSION_LESS 4.4) +if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.2 AND CMAKE_VERSION VERSION_LESS 4.5) if(PROJECT_NAME) message( WARNING @@ -66,10 +66,11 @@ if( ) # NOTE: Always use libc++ # see https://releases.llvm.org/19.1.0/projects/libcxx/docs/index.html - set(ENV{CXXFLAGS} -stdlib=libc++) - message(STATUS "CXXFLAGS=-stdlib=libc++") if(APPLE) + set(ENV{CXXFLAGS} "-stdlib=libc++") + message(STATUS "CXXFLAGS=$ENV{CXXFLAGS}") + execute_process( OUTPUT_VARIABLE LLVM_PREFIX COMMAND brew --prefix llvm @@ -83,12 +84,15 @@ if( add_link_options(-L${LLVM_DIR}/lib/c++) include_directories(SYSTEM ${LLVM_DIR}/include) - # /usr/local/Cellar/llvm/21.1.8_1/lib/c++/libc++.modules.json - # "/usr/local/Cellar/llvm/21.1.8_1/share/libc++/v1/std.cppm", set(CMAKE_CXX_STDLIB_MODULES_JSON ${LLVM_DIR}/lib/c++/libc++.modules.json ) elseif(LINUX) + set(ENV{CXXFLAGS} + "-stdlib=libc++ -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0" + ) + message(STATUS "CXXFLAGS=$ENV{CXXFLAGS}") + execute_process( OUTPUT_VARIABLE LLVM_MODULES COMMAND clang++ -print-file-name=libc++.modules.json @@ -105,18 +109,19 @@ if( endif() if(EXISTS ${CMAKE_CXX_STDLIB_MODULES_JSON}) - message( - STATUS - "CMAKE_CXX_STDLIB_MODULES_JSON=${CMAKE_CXX_STDLIB_MODULES_JSON}" - ) + file(REAL_PATH "${CMAKE_CXX_STDLIB_MODULES_JSON}" LLVM_MODULES) + message(STATUS "CMAKE_CXX_STDLIB_MODULES_JSON=${LLVM_MODULES}") # gersemi: off set(CACHE{CMAKE_CXX_STDLIB_MODULES_JSON} TYPE FILEPATH - HELP "Result of: clang++ -print-file-name=c++/libc++.modules.json" - VALUE ${CMAKE_CXX_STDLIB_MODULES_JSON} + HELP "Result of: clang++ -print-file-name=libc++.modules.json" + VALUE ${LLVM_MODULES} ) # gersemi: on else() - message(STATUS "File does NOT EXISTS! ${CMAKE_CXX_STDLIB_MODULES_JSON}") + message( + WARNING + "File does NOT EXISTS! ${CMAKE_CXX_STDLIB_MODULES_JSON}" + ) endif() endif() diff --git a/include/beman/execution/detail/counting_scope_join.hpp b/include/beman/execution/detail/counting_scope_join.hpp index cd8f9f68..c5076f8d 100644 --- a/include/beman/execution/detail/counting_scope_join.hpp +++ b/include/beman/execution/detail/counting_scope_join.hpp @@ -54,6 +54,7 @@ struct counting_scope_join_t { struct state; auto operator()(::beman::execution::detail::counting_scope_base* ptr) const { + // TODO(CK): prevent -Wmissing-braces clang++ error! return ::beman::execution::detail::make_sender(*this, ptr); } diff --git a/infra/.beman_submodule b/infra/.beman_submodule index 628b5d0d..5cbeca37 100644 --- a/infra/.beman_submodule +++ b/infra/.beman_submodule @@ -1,3 +1,3 @@ [beman_submodule] remote=https://github.com/bemanproject/infra.git -commit_hash=7b66b858d7f48428fca936184aef2bd246ccc81a +commit_hash=7fc85e2e26cb491926ca2744c359c2aa7ea8fd27 diff --git a/infra/cmake/enable-experimental-import-std.cmake b/infra/cmake/enable-experimental-import-std.cmake index e41a5f7c..3c6d6887 100644 --- a/infra/cmake/enable-experimental-import-std.cmake +++ b/infra/cmake/enable-experimental-import-std.cmake @@ -1,5 +1,9 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.3.0") +if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.4.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "f35a9ac6-8463-4d38-8eec-5d6008153e7d" + ) +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "4.3.0") set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" ) diff --git a/infra/cmake/llvm-libc++-toolchain.cmake b/infra/cmake/llvm-libc++-toolchain.cmake index eabf3631..92a12dcf 100644 --- a/infra/cmake/llvm-libc++-toolchain.cmake +++ b/infra/cmake/llvm-libc++-toolchain.cmake @@ -16,5 +16,5 @@ include(${CMAKE_CURRENT_LIST_DIR}/llvm-toolchain.cmake) if(NOT CMAKE_CXX_FLAGS MATCHES "-stdlib=libc\\+\\+") - string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++") + string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++ -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0") endif() diff --git a/requirements.txt b/requirements.txt index 878177a0..d93c02ff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ pyaml bump2version>=1.0.1 check-jsonschema>=0.36.1 cmake>=4.3 -codespell>=2.4.1 +codespell>=2.4.3 # conan>=2.26.2 gersemi>=0.27.2 gcovr>=8.6 diff --git a/tests/beman/execution/CMakeLists.txt b/tests/beman/execution/CMakeLists.txt index 91bcd74e..6c5cd266 100644 --- a/tests/beman/execution/CMakeLists.txt +++ b/tests/beman/execution/CMakeLists.txt @@ -134,6 +134,18 @@ foreach(test ${execution_tests}) add_test(NAME ${TEST_EXE} COMMAND $) endforeach() +# Disable ThreadSanitizer for this specific test target (Clang only) +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_options( + beman.execution.stopsource-cons.test + PRIVATE -fno-sanitize=thread + ) + target_link_options( + beman.execution.stopsource-cons.test + PRIVATE -fno-sanitize=thread + ) +endif() + if(CMAKE_BUILD_TYPE STREQUAL "Debug") return() endif() diff --git a/tests/beman/execution/exec-affine.test.cpp b/tests/beman/execution/exec-affine.test.cpp index 419e4ede..47fe92ab 100644 --- a/tests/beman/execution/exec-affine.test.cpp +++ b/tests/beman/execution/exec-affine.test.cpp @@ -104,7 +104,8 @@ struct test_scheduler { } }; - auto schedule() const noexcept { return sender{this->data_}; } + auto schedule() const noexcept { return sender{this->data_}; } + // TODO(CK): prevent -Wunneeded-internal-declaration error! friend auto operator==(const test_scheduler&, const test_scheduler&) noexcept -> bool = default; }; @@ -167,7 +168,7 @@ TEST(affine) { assert(s == loop.get_scheduler()); auto st{test_std::transform_sender(test_std::affine(test_std::just(42)), test_std::get_env(r))}; test_std::connect(std::move(st), std::move(r)); - auto s0{test_std::connect(test_std::affine(test_std::just(42)), receiver(loop.get_scheduler()))}; + [[maybe_unused]] auto s0{test_std::connect(test_std::affine(test_std::just(42)), receiver(loop.get_scheduler()))}; std::thread t{[&]() noexcept { loop.run(); }}; auto r0 = test_std::sync_wait(test_std::affine(test_std::just(42))); diff --git a/tests/beman/execution/exec-continues-on.test.cpp b/tests/beman/execution/exec-continues-on.test.cpp index 53012fba..b8a64911 100644 --- a/tests/beman/execution/exec-continues-on.test.cpp +++ b/tests/beman/execution/exec-continues-on.test.cpp @@ -75,7 +75,8 @@ auto test_constraints(Scheduler&& scheduler, Sender&& sender) { auto domain{test_std::get_domain(scheduler)}; test::check_type(domain); - auto s{test_std::continues_on(::std::forward(sender), ::std::forward(scheduler))}; + [[maybe_unused]] auto s{ + test_std::continues_on(::std::forward(sender), ::std::forward(scheduler))}; } } diff --git a/tests/beman/execution/exec-dependent-sender.test.cpp b/tests/beman/execution/exec-dependent-sender.test.cpp index feb9634a..8518c5d0 100644 --- a/tests/beman/execution/exec-dependent-sender.test.cpp +++ b/tests/beman/execution/exec-dependent-sender.test.cpp @@ -23,11 +23,11 @@ TEST(exec_dependent_sender) { test_std::dependent_sender); static_assert(test_std::dependent_sender); + test_std::then([](auto /* sched */) noexcept {}))>); static_assert(test_std::dependent_sender); + test_std::then([](auto /* sched */) noexcept {}))>); static_assert( test_std::dependent_sender); static_assert(test_std::dependent_sender); static_assert(not std::is_assignable_v); static_assert(not std::is_assignable_v);