From eee67980c2af84a22e5c5bc7f48af2907f1869aa Mon Sep 17 00:00:00 2001 From: ClausKlein Date: Mon, 8 Dec 2025 00:52:06 +0100 Subject: [PATCH 1/6] Feat: Prepare CXX_MODULES tests --- CMakeLists.txt | 29 ++++++++------- Makefile | 35 ++++++++++--------- cmake/CMakeUserPresets.json | 9 ++++- cmake/presets/CMakeGenericPresets.json | 2 +- cmake/presets/CMakeLinuxPresets.json | 2 +- cmake/presets/CMakeWindowsPresets.json | 2 +- examples/modules.cpp | 8 ++--- src/beman/execution/CMakeLists.txt | 9 +++-- src/beman/execution/execution.cppm | 13 ++++++- .../beman/execution/execution-module.test.cpp | 19 +++++----- .../execution/include/test/execution.hpp | 4 +++ .../execution/stop-token-module.test.cpp | 9 +++-- 12 files changed, 90 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e01b3774..0347d7a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ set(TARGET_PREFIX ${TARGET_NAMESPACE}.${TARGET_NAME}) set(TARGET_LIBRARY ${PROJECT_NAME}) set(TARGET_ALIAS ${TARGET_NAMESPACE}::${TARGET_NAME}) set(TARGET_PACKAGE_NAME ${PROJECT_NAME}-config) -set(TARGETS_EXPORT_NAME ${PROJECT_NAME}-config-targets) +set(TARGETS_EXPORT_NAME ${PROJECT_NAME}-targets) #========================== post project settings ============================== # Tell CMake that we explicitly want `import std`. @@ -45,13 +45,29 @@ if(${CMAKE_CXX_STANDARD} IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD) message(STATUS "CMAKE_CXX_MODULE_STD=${CMAKE_CXX_MODULE_STD}") endif() +add_library(${TARGET_NAME} STATIC) + +# CMake requires the language standard to be specified as compile feature +# when a target provides C++23 modules and the target will be installed +target_compile_features(${TARGET_NAME} PUBLIC cxx_std_23) + if(CMAKE_CXX_SCAN_FOR_MODULES AND ${CMAKE_GENERATOR} STREQUAL Ninja) set(BEMAN_USE_MODULES ON) message(STATUS "BEMAN_USE_MODULES=${BEMAN_USE_MODULES}") + target_compile_definitions(${TARGET_NAME} PUBLIC BEMAN_USE_MODULES) else() message(WARNING "Missing support for CMAKE_CXX_SCAN_FOR_MODULES!") endif() +if(BEMAN_USE_MODULES AND CMAKE_CXX_MODULE_STD) + set(BEMAN_HAS_IMPORT_STD ON) + message(STATUS "BEMAN_HAS_IMPORT_STD=${BEMAN_HAS_IMPORT_STD}") + target_compile_definitions(${TARGET_NAME} PUBLIC BEMAN_HAS_IMPORT_STD) +else() + set(CMAKE_CXX_MODULE_STD OFF) + message(WARNING "Missing support for CMAKE_CXX_MODULE_STD!") +endif() + # gersemi: off if(CMAKE_EXPORT_COMPILE_COMMANDS) set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) @@ -61,17 +77,6 @@ if(CMAKE_EXPORT_COMPILE_COMMANDS) ) endif() # gersemi: on - -# 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(${TARGET_NAME} STATIC) -target_compile_features(${TARGET_NAME} PUBLIC cxx_std_23) - -if(BEMAN_USE_MODULES AND CMAKE_CXX_MODULE_STD) - target_compile_definitions(${TARGET_NAME} PUBLIC BEMAN_HAS_IMPORT_STD) -else() - message(WARNING "Missing support for CMAKE_CXX_MODULE_STD!") -endif() #=============================================================================== option( diff --git a/Makefile b/Makefile index b956d026..8a2b86c1 100644 --- a/Makefile +++ b/Makefile @@ -31,12 +31,12 @@ endif LDFLAGS ?= SAN_FLAGS ?= CXX_FLAGS ?= -g -# TODO: SANITIZER := release -SANITIZER ?= default +SANITIZER := release +SANITIZER ?= RelWithDebInfo SOURCEDIR = $(CURDIR) BUILDROOT = build export hostSystemName:=$(shell uname -s) -# TODO BUILD := $(BUILDROOT)/$(SANITIZER) +BUILD := $(BUILDROOT)/$(SANITIZER) BUILD ?= $(BUILDROOT)/$(hostSystemName)/$(SANITIZER) EXAMPLE = beman.execution.examples.stop_token @@ -46,19 +46,19 @@ ifeq (${hostSystemName},Darwin) export LLVM_DIR:=$(shell realpath ${LLVM_PREFIX}) export PATH:=${LLVM_DIR}/bin:${PATH} - # export CMAKE_CXX_STDLIB_MODULES_JSON=${LLVM_DIR}/lib/c++/libc++.modules.json - # export CXX=clang++ - # export LDFLAGS=-L$(LLVM_DIR)/lib/c++ -lc++abi -lc++ # -lc++experimental - # export GCOV="llvm-cov gcov" + export CMAKE_CXX_STDLIB_MODULES_JSON=${LLVM_DIR}/lib/c++/libc++.modules.json + export CXX=clang++ + export LDFLAGS=-L$(LLVM_DIR)/lib/c++ -lc++abi # NO! -lc++ -lc++experimental + export GCOV="llvm-cov gcov" ### TODO: to test g++-15: export GCC_PREFIX:=$(shell brew --prefix gcc) export GCC_DIR:=$(shell realpath ${GCC_PREFIX}) - export CMAKE_CXX_STDLIB_MODULES_JSON=${GCC_DIR}/lib/gcc/current/libstdc++.modules.json - export CXX:=g++-15 - export CXXFLAGS:=-stdlib=libstdc++ - export GCOV="gcov" + # export CMAKE_CXX_STDLIB_MODULES_JSON=${GCC_DIR}/lib/gcc/current/libstdc++.modules.json + # export CXX:=g++-15 + # export CXXFLAGS:=-stdlib=libstdc++ + # export GCOV="gcov" else ifeq (${hostSystemName},Linux) export LLVM_DIR=/usr/lib/llvm-20 export PATH:=${LLVM_DIR}/bin:${PATH} @@ -95,9 +95,9 @@ ifeq ($(SANITIZER),lsan) endif # TODO: beman.execution.examples.modules -# FIXME: beman.execution.execution-module.test beman.execution.stop-token-module.test +FIXME: beman.execution.execution-module.test beman.execution.stop-token-module.test -default: test +# XXX: NO! $(SANITIZER): test all: $(SANITIZERS) @@ -111,16 +111,19 @@ doc: # $(MAKE) SANITIZER=$@ build: - cmake --fresh -G Ninja -S $(SOURCEDIR) -B $(BUILD) $(TOOLCHAIN) $(SYSROOT) \ + cmake -G Ninja -S $(SOURCEDIR) -B $(BUILD) $(TOOLCHAIN) $(SYSROOT) \ -D CMAKE_EXPORT_COMPILE_COMMANDS=ON \ -D CMAKE_SKIP_INSTALL_RULES=ON \ -D CMAKE_CXX_STANDARD=23 \ -D CMAKE_CXX_EXTENSIONS=ON \ -D CMAKE_CXX_STANDARD_REQUIRED=ON \ - -D CMAKE_CXX_COMPILER=$(CXX) # XXX -D CMAKE_CXX_FLAGS="$(CXX_FLAGS) $(SAN_FLAGS)" + -D CMAKE_CXX_SCAN_FOR_MODULES=ON \ + -D CMAKE_EXPERIMENTAL_CXX_IMPORT_STD=OFF \ + -D CMAKE_BUILD_TYPE=$(SANITIZER) \ + -D CMAKE_CXX_COMPILER=$(CXX) # XXX --fresh -D CMAKE_CXX_FLAGS="$(CXX_FLAGS) $(SAN_FLAGS)" cmake --build $(BUILD) -# NOTE: without install, see CMAKE_SKIP_INSTALL_RULES! CK +# NOTE: may w/o enabled install, see CMAKE_SKIP_INSTALL_RULES! CK test: build ctest --test-dir $(BUILD) --rerun-failed --output-on-failure diff --git a/cmake/CMakeUserPresets.json b/cmake/CMakeUserPresets.json index 331c063e..9e051014 100644 --- a/cmake/CMakeUserPresets.json +++ b/cmake/CMakeUserPresets.json @@ -22,9 +22,16 @@ "configurePreset": "release", "configuration": "Release", "targets": [ - "all_verify_interface_header_sets", "all" ] + }, + { + "name": "verify", + "configurePreset": "release", + "configuration": "Release", + "targets": [ + "all_verify_interface_header_sets" + ] } ], "testPresets": [ diff --git a/cmake/presets/CMakeGenericPresets.json b/cmake/presets/CMakeGenericPresets.json index 826484cc..d222b74b 100644 --- a/cmake/presets/CMakeGenericPresets.json +++ b/cmake/presets/CMakeGenericPresets.json @@ -1,5 +1,5 @@ { - "version": 6, + "version": 9, "configurePresets": [ { "name": "root-config", diff --git a/cmake/presets/CMakeLinuxPresets.json b/cmake/presets/CMakeLinuxPresets.json index 61f9b24a..7e5a5880 100644 --- a/cmake/presets/CMakeLinuxPresets.json +++ b/cmake/presets/CMakeLinuxPresets.json @@ -1,5 +1,5 @@ { - "version": 6, + "version": 9, "include": [ "CMakeGenericPresets.json" ], diff --git a/cmake/presets/CMakeWindowsPresets.json b/cmake/presets/CMakeWindowsPresets.json index d8834f2c..6ab8f1cf 100644 --- a/cmake/presets/CMakeWindowsPresets.json +++ b/cmake/presets/CMakeWindowsPresets.json @@ -1,5 +1,5 @@ { - "version": 6, + "version": 9, "include": [ "CMakeGenericPresets.json" ], diff --git a/examples/modules.cpp b/examples/modules.cpp index b3c245c9..ec2a54dd 100644 --- a/examples/modules.cpp +++ b/examples/modules.cpp @@ -11,17 +11,17 @@ import std; #endif -#if __cpp_modules < 201907L -#include -#else import beman_execution; -#endif namespace ex = beman::execution; int main() { +#ifdef USE_THIS_CODE auto [result] = ex::sync_wait(ex::when_all(ex::just(std::string("hello, ")), ex::just(std::string("world"))) | ex::then([](const auto& s1, const auto& s2) { return s1 + s2; })) .value_or(std::tuple(std::string("oops"))); std::cout << "result='" << result << "'\n"; +#else + std::println("ex::version = {}", ex::version); +#endif } diff --git a/src/beman/execution/CMakeLists.txt b/src/beman/execution/CMakeLists.txt index ecc5d4e4..c2acf034 100644 --- a/src/beman/execution/CMakeLists.txt +++ b/src/beman/execution/CMakeLists.txt @@ -200,6 +200,11 @@ if(BEMAN_USE_MODULES) BASE_DIRS ${PROJECT_SOURCE_DIR}/src/beman/execution FILES ${PROJECT_SOURCE_DIR}/src/beman/execution/execution.cppm ) +else() + set_target_properties( + ${TARGET_NAME} + PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON + ) endif() get_property( @@ -209,8 +214,6 @@ get_property( ) source_group("Header Files\\detail" FILES ${DETAIL_HEADER_FILES}) -set_target_properties(${TARGET_NAME} PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON) - if(NOT BEMAN_EXECUTION_ENABLE_INSTALL OR CMAKE_SKIP_INSTALL_RULES) return() endif() @@ -221,7 +224,7 @@ install( ARCHIVE DESTINATION lib/$ FILE_SET ${TARGET_NAME}_public_headers FILE_SET ${TARGET_NAME}_detail_headers - FILE_SET CXX_MODULES DESTINATION ${INSTALL_CONFIGDIR}/module + FILE_SET CXX_MODULES DESTINATION ${INSTALL_CONFIGDIR}/cxx-modules # There's currently no convention for this location CXX_MODULES_BMI DESTINATION ${INSTALL_CONFIGDIR}/bmi-${CMAKE_CXX_COMPILER_ID}_$ diff --git a/src/beman/execution/execution.cppm b/src/beman/execution/execution.cppm index a0e8e00a..df519414 100644 --- a/src/beman/execution/execution.cppm +++ b/src/beman/execution/execution.cppm @@ -3,15 +3,24 @@ // ---------------------------------------------------------------------------- module; + +#ifndef BEMAN_HAS_IMPORT_STD #include #include -#include +#endif + +// FIXME: #include #include export module beman_execution; +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#endif + namespace beman::execution { export int version(0); + // [stoptoken.concepts], stop token concepts export using ::beman::execution::stoppable_token; export using ::beman::execution::unstoppable_token; @@ -19,6 +28,7 @@ export using ::beman::execution::unstoppable_token; // [stoptoken], class stop_token export using ::beman::execution::stop_token; +#ifdef USE_THIS_CODE // [stopsource], class stop_source export using ::beman::execution::stop_source; @@ -218,5 +228,6 @@ export using ::beman::execution::sync_wait; // [exec.with.awaitable.senders] //-dk:TODO export using ::beman::execution::with_awaitable_senders; +#endif } // namespace beman::execution diff --git a/tests/beman/execution/execution-module.test.cpp b/tests/beman/execution/execution-module.test.cpp index 36d7361a..e6f94e92 100644 --- a/tests/beman/execution/execution-module.test.cpp +++ b/tests/beman/execution/execution-module.test.cpp @@ -2,12 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include -#if 1 -#include + +#ifdef BEMAN_HAS_IMPORT_STD +import std; #else -import beman_execution; +#include #endif +import beman_execution; + // ---------------------------------------------------------------------------- namespace { @@ -22,11 +25,11 @@ using error_types_of_t = test_stdex::error_types_of_t; TEST(execution_modules) { #if 0 - //-dk:TOD enable execution policies - test::use_type(); - test::use_type(); - test::use_type(); - test::use_type(); + //-dk:TODO enable execution policies + test::check_type(); + test::check_type(); + test::check_type(); + test::check_type(); test::use(test_std::seq); test::use(test_std::par); diff --git a/tests/beman/execution/include/test/execution.hpp b/tests/beman/execution/include/test/execution.hpp index f030b621..26d84f3f 100644 --- a/tests/beman/execution/include/test/execution.hpp +++ b/tests/beman/execution/include/test/execution.hpp @@ -4,7 +4,10 @@ #ifndef INCLUDED_TEST_EXECUTION #define INCLUDED_TEST_EXECUTION +// #ifndef BEMAN_USE_MODULES #include +// #endif + #include #include #ifndef _MSC_VER @@ -23,6 +26,7 @@ #define TEST(name) auto main() -> int namespace beman::execution {} +namespace beman::execution::detail {} namespace test_std = ::beman::execution; namespace test_detail = ::beman::execution::detail; diff --git a/tests/beman/execution/stop-token-module.test.cpp b/tests/beman/execution/stop-token-module.test.cpp index e58ee690..bbf68011 100644 --- a/tests/beman/execution/stop-token-module.test.cpp +++ b/tests/beman/execution/stop-token-module.test.cpp @@ -2,12 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include -#if 0 -#include + +#ifdef BEMAN_HAS_IMPORT_STD +import std; #else -import beman_execution; +#include #endif +import beman_execution; + // ---------------------------------------------------------------------------- TEST(stop_token_modules) { From 8589b363b1bb44ce78f6f522f3472c4fc13b41df Mon Sep 17 00:00:00 2001 From: ClausKlein Date: Mon, 8 Dec 2025 09:01:44 +0100 Subject: [PATCH 2/6] =?UTF-8?q?Add=20Modules=20=E2=80=93=20Quick=20Referen?= =?UTF-8?q?ce=20Cheat=20Sheet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/cxx_modules_cheatsheeet.md | 111 ++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 docs/cxx_modules_cheatsheeet.md diff --git a/docs/cxx_modules_cheatsheeet.md b/docs/cxx_modules_cheatsheeet.md new file mode 100644 index 00000000..2890d15f --- /dev/null +++ b/docs/cxx_modules_cheatsheeet.md @@ -0,0 +1,111 @@ + +# C++20/23 Modules – Quick Reference Cheat Sheet + +This cheat sheet summarizes **the correct order of `#include`, `import`, and `export module`** in C++20/23 modules. + +--- + +## 1️⃣ Module File Zones +``` +[Zone A] Global Module Fragment → before `export module` +[Zone B] Module Interface → after `export module` +[Zone C] Module Implementation → optional/private +``` + +--- + +## 2️⃣ Global Module Fragment (`module;`) +- Must appear **before** `export module` +- Allowed here: + - `#include` legacy headers + - macros + - conditional compilation + - rare `import` +- Example: +```cpp +module; +#include +#define INTERNAL_MACRO 1 +``` + +--- + +## 3️⃣ Module Declaration +```cpp +export module my.module; +``` +- Marks start of module interface +- Everything after is part of the module +- Prefer `import` instead of `#include` inside + +--- + +## 4️⃣ Import Rules +- ✅ After module: `import std;`, `import bar;` +- ✅ Rarely allowed in global fragment +- ❌ Forbidden before module line: +```cpp +import std; +export module foo; // ❌ +``` + +--- + +## 5️⃣ Include Rules +- ✅ Before `export module`: allowed (legacy headers) +- ✅ After `export module`: content becomes part of module +- ❌ System headers inside module body: may cause errors +Use `import std;` instead + +--- + +## 6️⃣ Recommended Layout +```cpp +module; // Global fragment +#include // OK +#define HELPER 1 // OK + +export module my.module; // Module interface begins +import std; // Prefer imports + +export int foo(); +#include "public_api.hpp" // Exported +``` + +--- + +## 7️⃣ Header-Only Library Example +```cpp +module; +#include + +#ifdef USE_STD_MODULE +import std; +#else +#include +#include +#endif + +export module boost.any; +#include // exported +``` + +--- + +## 8️⃣ Quick Rules Summary + +| Phase | Allowed | +|----------------------------|---------------------------------------| +| Before `export module` | `#include`, macros, conditional, rare `import` | +| After `export module` | `import`, includes become part of module interface | +| Never | `import` before module line, system headers inside module body, macros leaking into exported API | + +**Rule of Thumb:** +1. `module;` → legacy code +2. `export module X;` → module interface +3. `import` → after module +4. Include only when you want it exported + +--- + +**Tip:** Follow this layout for Beman, Boost, fmt, JSON, or other header-only libraries to wrap them safely as modules. From 42a521e2a48cd959c8375e45b42ab998aed12363 Mon Sep 17 00:00:00 2001 From: ClausKlein Date: Mon, 8 Dec 2025 09:25:41 +0100 Subject: [PATCH 3/6] Add more example code to cxx_modules_cheatsheet.md --- docs/cxx_modules_cheatsheeet.md | 172 +++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 2 deletions(-) diff --git a/docs/cxx_modules_cheatsheeet.md b/docs/cxx_modules_cheatsheeet.md index 2890d15f..a4fbc66d 100644 --- a/docs/cxx_modules_cheatsheeet.md +++ b/docs/cxx_modules_cheatsheeet.md @@ -75,21 +75,189 @@ export int foo(); --- ## 7️⃣ Header-Only Library Example + +### the boost/any/modules/boost_any.cppm + ```cpp +// Copyright (c) 2016-2025 Antony Polukhin +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + module; + +#include #include +#include -#ifdef USE_STD_MODULE +// FIXME(CK): #include +import boost.type_index; + +#ifdef BOOST_ANY_USE_STD_MODULE import std; #else #include +#include +#include #include +#include #endif +#define BOOST_ANY_INTERFACE_UNIT + export module boost.any; -#include // exported + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#endif + +#include +#include +#include + ``` +### the boost/any.hpp + +```cpp +// See http://www.boost.org/libs/any for Documentation. + +#ifndef BOOST_ANY_INCLUDED +#define BOOST_ANY_INCLUDED + +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT) + +#ifndef BOOST_ANY_INTERFACE_UNIT +#include +#ifdef BOOST_HAS_PRAGMA_ONCE +# pragma once +#endif + +#include // for std::addressof +#include + +#include +#include + +#endif // #ifndef BOOST_ANY_INTERFACE_UNIT + +#include +#include +#include + +namespace boost { + +BOOST_ANY_BEGIN_MODULE_EXPORT + + /// \brief A class whose instances can hold instances of any + /// type that satisfies \forcedlink{ValueType} requirements. + class any + { + public: + + /// \post this->empty() is true. + constexpr any() noexcept + : content(0) + { + } + + /// Makes a copy of `value`, so + + /// ... #### more code ### + + private: // representation + template + friend ValueType * unsafe_any_cast(any *) noexcept; + + friend class boost::anys::unique_any; + + placeholder * content; + /// @endcond + }; + + /// Exchange of the contents of `lhs` and `rhs`. + /// \throws Nothing. + inline void swap(any & lhs, any & rhs) noexcept + { + lhs.swap(rhs); + } + + /// ... ### more code ### + + /// \returns ValueType stored in `operand` + /// \throws boost::bad_any_cast if `operand` does not contain + /// specified ValueType. + template + ValueType any_cast(any & operand) + { + using nonref = typename std::remove_reference::type; + + nonref * result = boost::any_cast(std::addressof(operand)); + if(!result) + boost::throw_exception(bad_any_cast()); + + // Attempt to avoid construction of a temporary object in cases when + // `ValueType` is not a reference. Example: + // `static_cast(*result);` + // which is equal to `std::string(*result);` + typedef typename std::conditional< + std::is_reference::value, + ValueType, + typename std::add_lvalue_reference::type + >::type ref_type; + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local! +#endif + return static_cast(*result); +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + } + + /// \returns `ValueType` stored in `operand` + /// \throws boost::bad_any_cast if `operand` does not contain + /// specified `ValueType`. + template + inline ValueType any_cast(const any & operand) + { + using nonref = typename std::remove_reference::type; + return boost::any_cast(const_cast(operand)); + } + + /// \returns `ValueType` stored in `operand`, leaving the `operand` empty. + /// \throws boost::bad_any_cast if `operand` does not contain + /// specified `ValueType`. + template + inline ValueType any_cast(any&& operand) + { + static_assert( + std::is_rvalue_reference::value /*true if ValueType is rvalue or just a value*/ + || std::is_const< typename std::remove_reference::type >::value, + "boost::any_cast shall not be used for getting nonconst references to temporary objects" + ); + return boost::any_cast(operand); + } + +BOOST_ANY_END_MODULE_EXPORT + +} + +// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. +// Copyright Antony Polukhin, 2013-2025. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT) + +#endif + +``` --- ## 8️⃣ Quick Rules Summary From 48dcb8ad800f32e5014d4b4148e10ad326ec1b05 Mon Sep 17 00:00:00 2001 From: Claus Klein Date: Mon, 8 Dec 2025 14:51:55 +0100 Subject: [PATCH 4/6] Quickfix for export cmake config set --- Makefile | 4 ++-- examples/modules.cpp | 6 +++--- src/beman/execution/CMakeLists.txt | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 8a2b86c1..d1976d62 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ EXAMPLE = beman.execution.examples.stop_token ################################################ ifeq (${hostSystemName},Darwin) - export LLVM_PREFIX:=$(shell brew --prefix llvm) + export LLVM_PREFIX:=$(shell brew --prefix llvm) export LLVM_DIR:=$(shell realpath ${LLVM_PREFIX}) export PATH:=${LLVM_DIR}/bin:${PATH} @@ -113,7 +113,7 @@ doc: build: cmake -G Ninja -S $(SOURCEDIR) -B $(BUILD) $(TOOLCHAIN) $(SYSROOT) \ -D CMAKE_EXPORT_COMPILE_COMMANDS=ON \ - -D CMAKE_SKIP_INSTALL_RULES=ON \ + -D CMAKE_SKIP_INSTALL_RULES=OFF \ -D CMAKE_CXX_STANDARD=23 \ -D CMAKE_CXX_EXTENSIONS=ON \ -D CMAKE_CXX_STANDARD_REQUIRED=ON \ diff --git a/examples/modules.cpp b/examples/modules.cpp index ec2a54dd..dfbff855 100644 --- a/examples/modules.cpp +++ b/examples/modules.cpp @@ -4,11 +4,9 @@ #ifdef BEMAN_HAS_IMPORT_STD import std; #else - #include #include #include - #endif import beman_execution; @@ -21,7 +19,9 @@ int main() { ex::then([](const auto& s1, const auto& s2) { return s1 + s2; })) .value_or(std::tuple(std::string("oops"))); std::cout << "result='" << result << "'\n"; -#else +#elif defined(BEMAN_HAS_IMPORT_STD) std::println("ex::version = {}", ex::version); +#else + std::cout << "ex::version = " << ex::version << "\n"; #endif } diff --git a/src/beman/execution/CMakeLists.txt b/src/beman/execution/CMakeLists.txt index c2acf034..0e2f491c 100644 --- a/src/beman/execution/CMakeLists.txt +++ b/src/beman/execution/CMakeLists.txt @@ -220,7 +220,7 @@ endif() install( TARGETS ${TARGET_NAME} - EXPORT ${TARGETS_EXPORT_NAME}1 + EXPORT ${TARGETS_EXPORT_NAME} ARCHIVE DESTINATION lib/$ FILE_SET ${TARGET_NAME}_public_headers FILE_SET ${TARGET_NAME}_detail_headers @@ -231,7 +231,7 @@ install( ) install( - EXPORT ${TARGETS_EXPORT_NAME}1 + EXPORT ${TARGETS_EXPORT_NAME} FILE ${TARGETS_EXPORT_NAME}.cmake DESTINATION "${INSTALL_CONFIGDIR}" NAMESPACE ${TARGET_NAMESPACE}:: From 0e6bb8b748f765a3c286622ee13213b7b510dc89 Mon Sep 17 00:00:00 2001 From: ClausKlein Date: Tue, 9 Dec 2025 08:45:09 +0100 Subject: [PATCH 5/6] Fix install release presets --- Makefile | 23 ++- cmake/presets/CMakeDarwinPresets.json | 2 +- cmake/presets/CMakeLinuxPresets.json | 2 +- tests/beman/execution/CMakeLists.txt | 196 +++++++++++++------------- 4 files changed, 119 insertions(+), 104 deletions(-) diff --git a/Makefile b/Makefile index d1976d62..a6895d38 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,8 @@ endif LDFLAGS ?= SAN_FLAGS ?= CXX_FLAGS ?= -g -SANITIZER := release +# Note: disabled while working on CXX_MODULES! CK +# XXX: NO! SANITIZER := release SANITIZER ?= RelWithDebInfo SOURCEDIR = $(CURDIR) BUILDROOT = build @@ -94,12 +95,25 @@ ifeq ($(SANITIZER),lsan) LDFLAGS = $(SAN_FLAGS) endif +.PHONY: help FIXME TODO +help: + @echo "Use one of the folling targets:" + @echo "" + @echo "build -> use CXX_MODULES if possible" + @echo "test -> build and test " + @echo "debug -> preset with 'import std;'" + @echo "release -> preset with 'import std;'" + @echo "doc" + @echo "clean" + @echo "format" + @echo "distclean" + # TODO: beman.execution.examples.modules FIXME: beman.execution.execution-module.test beman.execution.stop-token-module.test +# Note: disabled while working on CXX_MODULES! CK # XXX: NO! $(SANITIZER): test - -all: $(SANITIZERS) +# XXX all: $(SANITIZERS) run: test ./$(BUILD)/examples/$(EXAMPLE) @@ -107,13 +121,14 @@ run: test doc: doxygen docs/Doxyfile +# Note: disabled while working on CXX_MODULES! CK # $(SANITIZERS): # $(MAKE) SANITIZER=$@ build: cmake -G Ninja -S $(SOURCEDIR) -B $(BUILD) $(TOOLCHAIN) $(SYSROOT) \ -D CMAKE_EXPORT_COMPILE_COMMANDS=ON \ - -D CMAKE_SKIP_INSTALL_RULES=OFF \ + -D CMAKE_SKIP_INSTALL_RULES=ON \ -D CMAKE_CXX_STANDARD=23 \ -D CMAKE_CXX_EXTENSIONS=ON \ -D CMAKE_CXX_STANDARD_REQUIRED=ON \ diff --git a/cmake/presets/CMakeDarwinPresets.json b/cmake/presets/CMakeDarwinPresets.json index 04528268..e635705f 100644 --- a/cmake/presets/CMakeDarwinPresets.json +++ b/cmake/presets/CMakeDarwinPresets.json @@ -22,7 +22,7 @@ "hidden": true, "cacheVariables": { "CMAKE_CXX_STDLIB_MODULES_JSON": "$env{CMAKE_CXX_STDLIB_MODULES_JSON}", - "CMAKE_BUILD_TYPE": "RelWithDebInfo" + "CMAKE_BUILD_TYPE": "Release" }, "condition": { "type": "equals", diff --git a/cmake/presets/CMakeLinuxPresets.json b/cmake/presets/CMakeLinuxPresets.json index 7e5a5880..4861d788 100644 --- a/cmake/presets/CMakeLinuxPresets.json +++ b/cmake/presets/CMakeLinuxPresets.json @@ -22,7 +22,7 @@ "hidden": true, "cacheVariables": { "CMAKE_CXX_STDLIB_MODULES_JSON": "$env{CMAKE_CXX_STDLIB_MODULES_JSON}", - "CMAKE_BUILD_TYPE": "RelWithDebInfo" + "CMAKE_BUILD_TYPE": "Release" }, "condition": { "type": "equals", diff --git a/tests/beman/execution/CMakeLists.txt b/tests/beman/execution/CMakeLists.txt index 0db8ff9d..d2d58dc6 100644 --- a/tests/beman/execution/CMakeLists.txt +++ b/tests/beman/execution/CMakeLists.txt @@ -16,106 +16,106 @@ if(BEMAN_USE_MODULES) execution-module.test # execution-module.test.cpp stop-token-module.test # stop-token-module.test.cpp ) +else() + list( + APPEND execution_tests + issue-174.test + issue-186.test + exec-scope-counting.test + exec-spawn.test + exec-stop-when.test + exec-prop.test + exec-scope-simple-counting.test + exec-spawn-future.test + exec-scope-concepts.test + issue-144.test + exec-on.test + notify.test + exec-awaitable.test + allocator-requirements-general.test + exec-connect.test + exec-continues-on.test + exec-domain-default.test + exec-fwd-env.test + exec-general.test + exec-get-allocator.test + exec-get-compl-sched.test + exec-get-delegation-scheduler.test + exec-get-domain.test + exec-get-env.test + exec-get-scheduler.test + exec-get-stop-token.test + exec-getcomplsigs.test + exec-into-variant.test + exec-just.test + exec-let.test + exec-opstate-start.test + exec-opstate.test + exec-read-env.test + exec-recv-concepts.test + exec-recv.test + exec-run-loop-general.test + exec-run-loop-types.test + exec-sched.test + exec-schedule-from.test + exec-schedule.test + exec-set-error.test + exec-set-stopped.test + exec-set-value.test + exec-snd-apply.test + exec-snd-concepts.test + exec-snd-expos.test + exec-snd-transform.test + exec-starts-on.test + exec-split.test + exec-sync-wait.test + exec-then.test + exec-utils-cmplsigs.test + exec-when-all.test + exec-with-awaitable-senders.test + execution-queryable-concept.test + exec-bulk.test + execution-syn.test + forward-like.test + function-objects.test + functional-syn.test + meta-combine.test + meta-contains.test + meta-filter.test + meta-prepend.test + meta-transform.test + meta-unique.test + stopcallback-cons.test + stopcallback-general.test + stopcallback-inplace-cons.test + stopcallback-inplace-general.test + stopcallback-inplace.test + stopcallback.test + stopsource-cons.test + stopsource-general.test + stopsource-inplace-cons.test + stopsource-inplace-general.test + stopsource-inplace-mem.test + stopsource-inplace.test + stopsource-mem.test + stopsource.test + stoptoken-concepts.test + stoptoken-general.test + stoptoken-inplace-general.test + stoptoken-inplace-members.test + stoptoken-inplace.test + stoptoken-mem.test + stoptoken-never-general.test + stoptoken-never.test + stoptoken.test + thread-stoptoken-intro.test + thread-stoptoken-syn.compile.test + thread-stoptoken.test + thread.test + utilities.test + ) endif() -list( - APPEND execution_tests - issue-174.test - issue-186.test - exec-scope-counting.test - exec-spawn.test - exec-stop-when.test - exec-prop.test - exec-scope-simple-counting.test - exec-spawn-future.test - exec-scope-concepts.test - issue-144.test - exec-on.test - notify.test - exec-awaitable.test - allocator-requirements-general.test - exec-connect.test - exec-continues-on.test - exec-domain-default.test - exec-fwd-env.test - exec-general.test - exec-get-allocator.test - exec-get-compl-sched.test - exec-get-delegation-scheduler.test - exec-get-domain.test - exec-get-env.test - exec-get-scheduler.test - exec-get-stop-token.test - exec-getcomplsigs.test - exec-into-variant.test - exec-just.test - exec-let.test - exec-opstate-start.test - exec-opstate.test - exec-read-env.test - exec-recv-concepts.test - exec-recv.test - exec-run-loop-general.test - exec-run-loop-types.test - exec-sched.test - exec-schedule-from.test - exec-schedule.test - exec-set-error.test - exec-set-stopped.test - exec-set-value.test - exec-snd-apply.test - exec-snd-concepts.test - exec-snd-expos.test - exec-snd-transform.test - exec-starts-on.test - exec-split.test - exec-sync-wait.test - exec-then.test - exec-utils-cmplsigs.test - exec-when-all.test - exec-with-awaitable-senders.test - execution-queryable-concept.test - exec-bulk.test - execution-syn.test - forward-like.test - function-objects.test - functional-syn.test - meta-combine.test - meta-contains.test - meta-filter.test - meta-prepend.test - meta-transform.test - meta-unique.test - stopcallback-cons.test - stopcallback-general.test - stopcallback-inplace-cons.test - stopcallback-inplace-general.test - stopcallback-inplace.test - stopcallback.test - stopsource-cons.test - stopsource-general.test - stopsource-inplace-cons.test - stopsource-inplace-general.test - stopsource-inplace-mem.test - stopsource-inplace.test - stopsource-mem.test - stopsource.test - stoptoken-concepts.test - stoptoken-general.test - stoptoken-inplace-general.test - stoptoken-inplace-members.test - stoptoken-inplace.test - stoptoken-mem.test - stoptoken-never-general.test - stoptoken-never.test - stoptoken.test - thread-stoptoken-intro.test - thread-stoptoken-syn.compile.test - thread-stoptoken.test - thread.test - utilities.test -) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) foreach(test ${execution_tests}) From c70e0964a4020210725a366814afd6f44b136188 Mon Sep 17 00:00:00 2001 From: Claus Klein Date: Tue, 9 Dec 2025 21:08:45 +0100 Subject: [PATCH 6/6] Tested with llvm-22 on Linux --- .pre-commit-config.yaml | 4 ++-- Makefile | 4 ++-- src/beman/execution/CMakeLists.txt | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5baf30b5..da3e7f81 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: # CMake linting and formatting - repo: https://github.com/BlankSpruce/gersemi - rev: 0.23.2 + rev: 0.24.0 hooks: - id: gersemi name: CMake linting @@ -55,7 +55,7 @@ repos: # Config file: pyproject.toml # second Python code formatting - repo: https://github.com/psf/black - rev: 25.11.0 + rev: 25.12.0 hooks: - id: black diff --git a/Makefile b/Makefile index a6895d38..21891770 100644 --- a/Makefile +++ b/Makefile @@ -61,9 +61,9 @@ ifeq (${hostSystemName},Darwin) # export CXXFLAGS:=-stdlib=libstdc++ # export GCOV="gcov" else ifeq (${hostSystemName},Linux) - export LLVM_DIR=/usr/lib/llvm-20 + export LLVM_DIR=/usr/lib/llvm-22 export PATH:=${LLVM_DIR}/bin:${PATH} - export CXX=clang++-20 + export CXX=clang++-22 else export CXX=$(COMPILER) endif diff --git a/src/beman/execution/CMakeLists.txt b/src/beman/execution/CMakeLists.txt index 0e2f491c..04499fff 100644 --- a/src/beman/execution/CMakeLists.txt +++ b/src/beman/execution/CMakeLists.txt @@ -197,8 +197,9 @@ if(BEMAN_USE_MODULES) ${TARGET_NAME} PUBLIC FILE_SET CXX_MODULES - BASE_DIRS ${PROJECT_SOURCE_DIR}/src/beman/execution - FILES ${PROJECT_SOURCE_DIR}/src/beman/execution/execution.cppm + # BASE_DIRS ${PROJECT_SOURCE_DIR}/src/beman/execution + # FILES ${PROJECT_SOURCE_DIR}/src/beman/execution/execution.cppm + FILES execution.cppm ) else() set_target_properties(