From 021955732f5abc46f3dd954f6a2d364fae8f7cde Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 16 Jul 2026 16:31:15 -0400 Subject: [PATCH 1/3] Rename and use extern C++ --- module/{int128.cxx => int128.cppm} | 6 ++++++ 1 file changed, 6 insertions(+) rename module/{int128.cxx => int128.cppm} (92%) diff --git a/module/int128.cxx b/module/int128.cppm similarity index 92% rename from module/int128.cxx rename to module/int128.cppm index 3fd14317..6218cac9 100644 --- a/module/int128.cxx +++ b/module/int128.cppm @@ -65,6 +65,10 @@ export module boost.int128; import std; #endif +// Wrap the exported declarations in extern "C++" so they attach to the global +// module (classic mangling), keeping the module and header forms ABI compatible. +extern "C++" { + export namespace boost::int128 { struct int128_t; @@ -97,3 +101,5 @@ class numeric_limits; #elif defined(__clang__) # pragma clang diagnostic pop #endif + +} // extern "C++" From dbdf714d598e49d60c537b3d6e9fa305f083c0cb Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 16 Jul 2026 16:31:30 -0400 Subject: [PATCH 2/3] Update references to module --- doc/modules/ROOT/pages/getting_started.adoc | 2 +- module/CMakeLists.txt | 19 +++++++++++++++++-- module/Jamfile | 7 ++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/doc/modules/ROOT/pages/getting_started.adoc b/doc/modules/ROOT/pages/getting_started.adoc index 392c2ca6..01f47b82 100644 --- a/doc/modules/ROOT/pages/getting_started.adoc +++ b/doc/modules/ROOT/pages/getting_started.adoc @@ -77,7 +77,7 @@ When compiling with pass:[C++20] or newer, the library can be consumed as a name import boost.int128; ---- -Building the module requires defining `BOOST_INT128_BUILD_MODULE` and compiling `module/int128.cxx` with your toolchain's module support. See xref:config.adoc[Configuration Macros] for details. +Building the module requires defining `BOOST_INT128_BUILD_MODULE` and compiling `module/int128.cppm` with your toolchain's module support. See xref:config.adoc[Configuration Macros] for details. == CUDA Support diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt index 2fe5619c..bf0d6857 100644 --- a/module/CMakeLists.txt +++ b/module/CMakeLists.txt @@ -16,12 +16,18 @@ endif() add_library(boost_int128_module) target_sources(boost_int128_module PUBLIC - FILE_SET int128_module TYPE CXX_MODULES FILES int128.cxx + FILE_SET int128_module TYPE CXX_MODULES FILES int128.cppm ) target_link_libraries(boost_int128_module PUBLIC Boost::int128) target_compile_features(boost_int128_module PUBLIC cxx_std_23) -# int128.cxx defines BOOST_INT128_BUILD_MODULE itself, but the tests link this +# The purview includes the library's angled headers by design. +# clang-scan-deps warns on that and ignores -Wno-include-angled-in-module-purview, +# so -w keeps the dependency-scan output clean (this glue unit's code is fully +# warned on in the header builds). +target_compile_options(boost_int128_module PRIVATE $<$:-w>) + +# int128.cppm defines BOOST_INT128_BUILD_MODULE itself, but the tests link this # target and need the macro too so they import the module instead of including # the headers directly. target_compile_definitions(boost_int128_module PUBLIC BOOST_INT128_BUILD_MODULE) @@ -68,6 +74,15 @@ set(BOOST_INT128_MODULE_TESTS test_powm ) +# GCC's libstdc++ cannot yet mix the test sources' textual standard library +# includes with import std in one consumer translation unit, so only the quick +# test runs there. MSVC is treated the same way until its full consumer suite has +# been validated. The full list runs under clang/libc++. +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + message(STATUS "Boost.Int128 module: ${CMAKE_CXX_COMPILER_ID} consumer tests limited to module_quick_test") + set(BOOST_INT128_MODULE_TESTS) +endif() + add_executable(module_quick_test "${CMAKE_CURRENT_SOURCE_DIR}/quick_test.cpp") target_link_libraries(module_quick_test PRIVATE boost_int128_module) # The superproject pins an older policy version (CMP0155), so C++ sources are not diff --git a/module/Jamfile b/module/Jamfile index a20d8c9b..f3375450 100644 --- a/module/Jamfile +++ b/module/Jamfile @@ -11,6 +11,11 @@ import modules ; import testing ; import path ; import pch ; +import type ; + +# b2 registers the standard C++ suffixes (cpp cxx cc) but not cppm, so teach it +# that the .cppm module interface unit is a C++ source. +type.register-suffixes cppm : CPP ; project : requirements @@ -24,7 +29,7 @@ project clang:23 ; -obj int128 : int128.cxx : BOOST_INT128_EXPORT_TESTING msvc:-interface ; +obj int128 : int128.cppm : BOOST_INT128_EXPORT_TESTING msvc:-interface ; run quick_test.cpp int128 : : : int128 ; run ../test/test_bit.cpp int128 : : : int128 ; From 451f3bc4fa04416284c6adc76f949e65b6484ec5 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 16 Jul 2026 16:51:53 -0400 Subject: [PATCH 3/3] And GCC and MSVC runners --- .github/workflows/ci.yml | 162 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6bffc9db..13a58ba7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1325,7 +1325,7 @@ jobs: git submodule update --init tools/boostdep python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY - - name: Build with the standard library module and int128 module, then test + - name: Configure run: | cd ../boost-root mkdir __build__ && cd __build__ @@ -1334,9 +1334,167 @@ jobs: -DBUILD_TESTING=ON \ -DBOOST_INT128_BUILD_MODULE=ON \ -DCMAKE_CXX_COMPILER=clang++-$LLVM_VERSION \ - -DCMAKE_CXX_FLAGS="-stdlib=libc++" \ + -DCMAKE_CXX_FLAGS="-stdlib=libc++ -Wno-reserved-module-identifier" \ -DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=$IMPORT_STD_UUID \ -DCMAKE_CXX_STDLIB_MODULES_JSON=/usr/lib/llvm-$LLVM_VERSION/lib/libc++.modules.json \ .. + + # Kept as a separate step so the boost.int128 module build time is visible on its own. + - name: Build the Boost.Int128 module + run: | + cd ../boost-root/__build__ + cmake --build . --target boost_int128_module + + - name: Build and run the tests + run: | + cd ../boost-root/__build__ + cmake --build . --target tests + ctest --output-on-failure --no-tests=error + + cmake-module-test-gcc: + strategy: + fail-fast: false + + runs-on: ubuntu-latest + + # GCC 15 (the first release with import std support and + # libstdc++.modules.json) is not packaged for the runner image, so the job + # runs in a container that ships it. + container: ubuntu:26.04 + + env: + GCC_VERSION: "15" + # Pinned so the experimental `import std` feature UUID below stays valid. + CMAKE_VERSION: 4.4.0 + # CMake gates `import std` behind this UUID; it is specific to the CMake version. + IMPORT_STD_UUID: f35a9ac6-8463-4d38-8eec-5d6008153e7d + + steps: + - name: Install toolchain + run: | + apt-get update + apt-get install -y g++-$GCC_VERSION gcc-$GCC_VERSION ninja-build wget ca-certificates git python3 + wget -q https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-linux-x86_64.tar.gz + tar -xzf cmake-$CMAKE_VERSION-linux-x86_64.tar.gz -C /opt + echo "/opt/cmake-$CMAKE_VERSION-linux-x86_64/bin" >> "$GITHUB_PATH" + + - uses: actions/checkout@v6 + + - name: Setup Boost + run: | + echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY + LIBRARY=${GITHUB_REPOSITORY#*/} + echo LIBRARY: $LIBRARY + echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV + echo GITHUB_BASE_REF: $GITHUB_BASE_REF + echo GITHUB_REF: $GITHUB_REF + REF=${GITHUB_BASE_REF:-$GITHUB_REF} + REF=${REF#refs/heads/} + echo REF: $REF + BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true + echo BOOST_BRANCH: $BOOST_BRANCH + cd .. + git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + mkdir -p libs/$LIBRARY + cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY + git submodule update --init tools/boostdep + python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY + + - name: Configure + run: | + cd ../boost-root + mkdir __build__ && cd __build__ + cmake -G Ninja \ + -DBOOST_INCLUDE_LIBRARIES=$LIBRARY \ + -DBUILD_TESTING=ON \ + -DBOOST_INT128_BUILD_MODULE=ON \ + -DCMAKE_C_COMPILER=gcc-$GCC_VERSION \ + -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION \ + -DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=$IMPORT_STD_UUID \ + .. + + # Kept as a separate step so the boost.int128 module build time is visible on its own. + - name: Build the Boost.Int128 module + run: | + cd ../boost-root/__build__ + cmake --build . --target boost_int128_module + + - name: Build and run the tests + run: | + cd ../boost-root/__build__ + cmake --build . --target tests + ctest --output-on-failure --no-tests=error + + cmake-module-test-msvc: + strategy: + fail-fast: false + + runs-on: windows-2025 + + env: + # Pinned so the experimental import std feature UUID below stays valid. + CMAKE_VERSION: 4.4.0 + # CMake gates import std behind this UUID; it is specific to the CMake version. + IMPORT_STD_UUID: f35a9ac6-8463-4d38-8eec-5d6008153e7d + + steps: + - uses: actions/checkout@v6 + + # Puts cl.exe and the MSVC INCLUDE/LIB environment on PATH for the later steps. + - name: Set up the MSVC environment + uses: ilammy/msvc-dev-cmd@v1 + + - name: Install toolchain + shell: pwsh + run: | + # A pinned CMake (the import std UUID is tied to the version) and Ninja + # (required for C++ modules). + curl.exe -L -o cmake.zip "https://github.com/Kitware/CMake/releases/download/v$env:CMAKE_VERSION/cmake-$env:CMAKE_VERSION-windows-x86_64.zip" + Expand-Archive -Path cmake.zip -DestinationPath C:\tools + "C:\tools\cmake-$env:CMAKE_VERSION-windows-x86_64\bin" | Out-File -FilePath $env:GITHUB_PATH -Append -Encoding utf8 + choco install ninja -y + + - name: Setup Boost + shell: pwsh + run: | + $LIBRARY = ($env:GITHUB_REPOSITORY -split '/')[-1] + "LIBRARY=$LIBRARY" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + $ref = if ($env:GITHUB_BASE_REF) { $env:GITHUB_BASE_REF } else { $env:GITHUB_REF } + $ref = $ref -replace '^refs/heads/', '' + $branch = if ($ref -eq 'master') { 'master' } else { 'develop' } + cd .. + git clone -b $branch --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + New-Item -ItemType Directory -Force -Path "libs/$LIBRARY" | Out-Null + Copy-Item -Recurse -Force "$env:GITHUB_WORKSPACE/*" "libs/$LIBRARY" + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY + + - name: Configure + shell: pwsh + run: | + cd ../boost-root + New-Item -ItemType Directory -Force -Path __build__ | Out-Null + cd __build__ + cmake -G Ninja ` + -DBOOST_INCLUDE_LIBRARIES="$env:LIBRARY" ` + -DBUILD_TESTING=ON ` + -DBOOST_INT128_BUILD_MODULE=ON ` + -DCMAKE_CXX_COMPILER=cl ` + -DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD="$env:IMPORT_STD_UUID" ` + .. + + # Kept as a separate step so the boost.int128 module build time is visible on its own. + - name: Build the Boost.Int128 module + shell: pwsh + run: | + cd ../boost-root/__build__ + cmake --build . --target boost_int128_module + + - name: Build and run the tests + shell: pwsh + run: | + cd ../boost-root/__build__ cmake --build . --target tests ctest --output-on-failure --no-tests=error