Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/ci.cpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ jobs:
-DCMAKE_BUILD_TYPE=${{ matrix.build }} \
-DCMAKE_CXX_FLAGS="${{ matrix.cxxflags }}" \
-DSTDEXEC_ENABLE_TBB:BOOL=${{ !contains(matrix.cxxflags, '-fsanitize') && !contains(matrix.name, 'modules') }} \
-DSTDEXEC_ENABLE_TASKFLOW:BOOL=${{ matrix.name == 'CPU (clang 22, Debug)' }} \
-DSTDEXEC_ENABLE_ASIO:BOOL=TRUE \
-DSTDEXEC_ASIO_IMPLEMENTATION:STRING=boost \
-DCMAKE_CXX_STANDARD:STRING=${{ matrix.cxxstd }} \
Expand All @@ -128,6 +129,23 @@ jobs:
# to result in fewer Clang ICEs.
cmake --build build -v -j ${{ contains(matrix.name, 'modules') && 1 || 512 }};

# Verify that public headers are self-contained. This alone doesn't
# depend on the rest of the build matrix, but the SKIP_LINTING
# exclusions in CMakeLists.txt for optional-dependency and
# platform-specific headers do: run it only here and it would
# silently never compile exec/taskflow/taskflow_thread_pool.hpp,
# exec/windows/filetime_clock.hpp, or exec/windows/windows_thread_pool.hpp
# anywhere in CI, defeating the point of checking them at all. So:
# Taskflow is force-enabled above just for this one job (verified
# locally that STDEXEC_ENABLE_TASKFLOW builds clean via CPM, same as
# the existing Boost/ASIO fetch), which covers the TBB and Taskflow
# exclusions between them; the Windows-only headers are covered
# separately by the equivalent step added to test-windows.ps1, which
# runs on an actual Windows job where WIN32 is true.
if [ "${{ matrix.name }}" = "CPU (clang 22, Debug)" ]; then
cmake --build build -v --target all_verify_interface_header_sets;
fi

# Print sccache stats
sccache -s;

Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/test-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,15 @@ Invoke-NativeCommand cmake -B $BuildDirectory -G Ninja `
"-DSTDEXEC_ASIO_IMPLEMENTATION:STRING=boost" `
"-DSTDEXEC_BUILD_TESTS:BOOL=TRUE" .
Invoke-NativeCommand cmake --build $BuildDirectory

# Verify that public headers are self-contained, same as the Linux CI job.
# This is the only job in CI where WIN32 is true, so it's the only place
# exec/windows/filetime_clock.hpp and exec/windows/windows_thread_pool.hpp
# (SKIP_LINTING'd everywhere else per CMakeLists.txt) actually get compiled
# and checked. Gated to Debug so it doesn't run twice per compiler/toolset
# pairing, matching the "run once" approach on the Linux side.
if ($Config -eq "Debug") {
Invoke-NativeCommand cmake --build $BuildDirectory --target all_verify_interface_header_sets
}

Invoke-NativeCommand ctest --test-dir $BuildDirectory --output-on-failure --verbose --timeout 60
34 changes: 34 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,40 @@ set_target_properties(stdexec PROPERTIES VERSION "${STDEXEC_VERSION}"
if(STDEXEC_BUILD_TESTS)
# Test that headers are self-contained
set_target_properties(stdexec PROPERTIES VERIFY_INTERFACE_HEADER_SETS TRUE)

# A handful of headers are not self-contained by design; exclude them from
# verification rather than treating that as a bug.

# These headers bracket a translation unit's warning/pragma state.
# __epilogue.hpp pops state that __prologue.hpp is documented to push, so it
# cannot compile on its own.
set_source_files_properties(include/stdexec/__detail/__epilogue.hpp
PROPERTIES SKIP_LINTING ON)

# This header has a documented precondition that includers define
# STDEXEC_PARALLEL_SCHEDULER_INLINE before including it.
set_source_files_properties(
include/stdexec/__detail/__parallel_scheduler_default_impl_entry.hpp
PROPERTIES SKIP_LINTING ON)

# These headers require an optional external dependency that isn't present
# in every configuration; only verify them when the corresponding feature
# is actually enabled.
if(NOT STDEXEC_ENABLE_TBB)
set_source_files_properties(include/exec/tbb/tbb_thread_pool.hpp
PROPERTIES SKIP_LINTING ON)
endif()
if(NOT STDEXEC_ENABLE_TASKFLOW)
set_source_files_properties(include/exec/taskflow/taskflow_thread_pool.hpp
PROPERTIES SKIP_LINTING ON)
endif()

# These headers are Windows-only.
if(NOT WIN32)
set_source_files_properties(
include/exec/windows/filetime_clock.hpp
include/exec/windows/windows_thread_pool.hpp PROPERTIES SKIP_LINTING ON)
endif()
endif()

# Declare the public include directories
Expand Down
23 changes: 23 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,29 @@ if(STDEXEC_BUILD_PARALLEL_SCHEDULER AND NOT STDEXEC_ENABLE_CUDA)
30)
endif()

# __detail/__parallel_scheduler_default_impl_entry.hpp is excluded from
# VERIFY_INTERFACE_HEADER_SETS because it has a documented precondition
# (includers must define STDEXEC_PARALLEL_SCHEDULER_INLINE first) that the
# automatic verification can't express. Compile it here instead, with that
# precondition satisfied.
#
# This is a plain (non-EXCLUDE_FROM_ALL) OBJECT library rather than a
# dependency hooked onto all_verify_interface_header_sets: CMake creates that
# aggregate target itself only once the whole build has been configured
# (confirmed directly - `if(TARGET all_verify_interface_header_sets)` is
# still false at this point in test/CMakeLists.txt, even though the property
# enabling it was set earlier in the root CMakeLists.txt), so there's no
# handle to attach a dependency to from here. Building it unconditionally is
# simpler and just as effective: it's one small translation unit, so the
# added cost per build is negligible.
add_library(verify_parallel_scheduler_default_impl_entry OBJECT
stdexec/detail/verify_parallel_scheduler_default_impl_entry.cpp)
target_link_libraries(verify_parallel_scheduler_default_impl_entry
PRIVATE STDEXEC::stdexec)
set_target_properties(
verify_parallel_scheduler_default_impl_entry
PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF)

add_subdirectory(exec)

if(STDEXEC_ENABLE_CUDA)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2026 NVIDIA Corporation
*
* Licensed under the Apache License Version 2.0 with LLVM Exceptions
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://llvm.org/LICENSE.txt
*
* 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.
*/

// stdexec/__detail/__parallel_scheduler_default_impl_entry.hpp is excluded
// from VERIFY_INTERFACE_HEADER_SETS (see the root CMakeLists.txt) because it
// has a documented precondition: includers must define
// STDEXEC_PARALLEL_SCHEDULER_INLINE before including it. That precondition
// is otherwise only exercised when STDEXEC_BUILD_PARALLEL_SCHEDULER is
// enabled, which CI does not currently do.
//
// This translation unit exists solely to verify that, given the documented
// precondition, the header is otherwise self-contained. It is not linked
// into any test executable or library; see the verify_parallel_scheduler_
// default_impl_entry OBJECT library target in this directory's CMakeLists
// wiring, which is hooked into all_verify_interface_header_sets as an extra
// dependency.

#define STDEXEC_PARALLEL_SCHEDULER_INLINE inline
#include "stdexec/__detail/__parallel_scheduler_default_impl_entry.hpp"
Loading