Skip to content

Commit af4c45f

Browse files
authored
Add Windows MinGW tests (#20)
1 parent 04c54e9 commit af4c45f

File tree

6 files changed

+83
-20
lines changed

6 files changed

+83
-20
lines changed

.github/workflows/tests.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ jobs:
4141
- os: windows-latest
4242
# uses MSVC
4343

44+
- os: windows-latest
45+
mingw-version: "13.2.0"
46+
description: "MinGW 13"
47+
cmake-flags: '-G "MinGW Makefiles"'
48+
4449
steps:
4550
- uses: actions/checkout@v4
4651

@@ -58,6 +63,12 @@ jobs:
5863
with:
5964
version: ${{ matrix.gcc-version }}
6065

66+
- name: Setup MinGW
67+
if: contains(matrix.os, 'windows') && matrix.mingw-version != ''
68+
run: |
69+
choco install --no-progress mingw --version ${{ matrix.mingw-version }}
70+
Add-Content $env:GITHUB_PATH "C:\ProgramData\mingw64\mingw64\bin"
71+
6172
- name: Setup LLVM and Clang
6273
uses: KyleMayes/install-llvm-action@v1
6374
if: ${{ matrix.llvm-version != '' }}
@@ -73,7 +84,7 @@ jobs:
7384

7485
- name: Build and Test
7586
run: |
76-
cmake -S . -B build/ -DCMAKE_BUILD_TYPE=Debug -DPOOLSTL_TEST=ON -DPOOLSTL_TEST_COVERAGE=ON
87+
cmake -S . -B build/ -DCMAKE_BUILD_TYPE=Debug -DPOOLSTL_TEST=ON -DPOOLSTL_TEST_COVERAGE=ON ${{ matrix.cmake-flags }}
7788
cmake --build build/ --config Debug
7889
cd build/tests
7990
ctest -C Debug --output-on-failure --verbose
@@ -85,7 +96,7 @@ jobs:
8596
# Earliest GCC with all benchmarked methods is 9
8697
if: matrix.gcc-version != '7' && matrix.gcc-version != '8'
8798
run: |
88-
cmake -S . -B bench_build/ -DCMAKE_BUILD_TYPE=Release -DPOOLSTL_BENCH=ON
99+
cmake -S . -B bench_build/ -DCMAKE_BUILD_TYPE=Release -DPOOLSTL_BENCH=ON ${{ matrix.cmake-flags }}
89100
cmake --build bench_build/ --config Release
90101
cd bench_build/benchmark/
91102
./poolstl_bench || ./Release/poolstl_bench.exe
@@ -101,7 +112,7 @@ jobs:
101112
cp tools/poolstl.hpp include/poolstl/
102113
mkdir -p include/poolstl/internal
103114
cp tools/poolstl.hpp include/poolstl/internal/utils.hpp
104-
cmake -S . -B build/ -DCMAKE_BUILD_TYPE=Debug -DPOOLSTL_TEST=ON -DPOOLSTL_TEST_COVERAGE=OFF
115+
cmake -S . -B build/ -DCMAKE_BUILD_TYPE=Debug -DPOOLSTL_TEST=ON -DPOOLSTL_TEST_COVERAGE=OFF ${{ matrix.cmake-flags }}
105116
cmake --build build/ --config Debug
106117
cd build/tests
107118
ctest -C Debug --output-on-failure --verbose

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,5 +222,12 @@ If not found then poolSTL will alias its `poolstl::par` as `std::execution::par`
222222

223223
Now just use `std::execution::par` as normal, and poolSTL will fill in as necessary. See [supplement_test.cpp](tests/supplement_test.cpp).
224224

225-
Example use case: You *can* link against TBB, so you'll use native support on GCC 9+, Clang, MSVC, etc.
225+
**Example use case:** You *can* link against TBB, so you'll use native support on GCC 9+, Clang, MSVC, etc.
226226
PoolSTL will fill in automatically on GCC <9 and Apple Clang.
227+
228+
**Example use case 2:** You'd *prefer* to use the TBB version, but don't want to fail on systems that don't have it.
229+
Simply use the supplement as above, but have your build system (CMake, meson, etc.) check for TBB.
230+
If not found define `POOLSTL_STD_SUPPLEMENT_NO_INCLUDE`.
231+
232+
If defined, the supplement will not `#include <execution>` (and neither should your code!),
233+
thus dropping the TBB link requirement. The poolSTL supplement fills in. See the supplement section of [tests/CMakeLists.txt](tests/CMakeLists.txt) for an example.

benchmark/CMakeLists.txt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STR
66
set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -DNDEBUG")
77
endif ()
88

9+
if (MINGW AND WIN32)
10+
# MinGW on GitHub Actions requires these.
11+
# If omitted the executable crashes with 'Exit code 0xc0000139' which appears to mean a missing DLL.
12+
add_link_options("-static-libstdc++" "-static-libgcc")
13+
endif()
14+
915
include(FetchContent)
1016

1117
# Add Google Benchmark
@@ -33,7 +39,7 @@ add_executable(poolstl_bench
3339
target_link_libraries(poolstl_bench benchmark::benchmark poolSTL::poolSTL)
3440
target_compile_features(poolstl_bench PUBLIC cxx_std_17)
3541

36-
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
42+
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT MINGW))
3743
# GCC and Clang require TBB for native std::execution::par
3844
find_package(TBB)
3945
if (TBB_FOUND)
@@ -42,10 +48,9 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STR
4248
target_compile_definitions(poolstl_bench PUBLIC POOLSTL_BENCH_STD_PAR)
4349
else()
4450
message("No TBB")
45-
# No TBB means cannot use std::execution::par
46-
unset(HAVE_STD_EXECUTION_PAR)
4751
endif()
4852
else()
49-
# MSVC requires nothing
53+
# MSVC requires nothing.
54+
# MinGW also requires nothing to compile std::execution::par, but performance appears to be the same as sequential.
5055
target_compile_definitions(poolstl_bench PUBLIC POOLSTL_BENCH_STD_PAR)
5156
endif()

include/poolstl/poolstl.hpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,21 @@
2727
*
2828
* To use this define POOLSTL_STD_SUPPLEMENT=1 before including poolstl.hpp.
2929
*
30-
* This aliasing will not happen if native support exists. If this autodetection fails for you,
31-
* define POOLSTL_ALLOW_SUPPLEMENT=0 to disable this feature.
30+
* Attempts to autodetect native support by checking for <execution>, including it if it exists, and then checking for
31+
* the __cpp_lib_parallel_algorithm feature macro.
32+
*
33+
* If native support is not found then the standard execution policies are declared as forwards to poolSTL.
34+
*
35+
* GCC and Clang: TBB is required if <execution> is #included. If you'd like to use the poolSTL supplement in cases
36+
* that TBB is not available, have your build system define POOLSTL_STD_SUPPLEMENT_NO_INCLUDE if TBB is not found.
37+
* PoolSTL will then not include <execution> and the supplement will kick in.
38+
* Your code must not #include <execution>.
39+
*
40+
* MinGW: the compiler declares support, but actual performance is sequential (see poolSTL benchmark). To use
41+
* the supplement anyway define POOLSTL_STD_SUPPLEMENT_FORCE to override the autodetection.
42+
* Your code must not #include <execution>.
43+
*
44+
* Define POOLSTL_ALLOW_SUPPLEMENT=0 to override POOLSTL_STD_SUPPLEMENT and disable this feature.
3245
*/
3346
#ifndef POOLSTL_ALLOW_SUPPLEMENT
3447
#define POOLSTL_ALLOW_SUPPLEMENT 1
@@ -38,11 +51,13 @@
3851

3952
#if __cplusplus >= 201603L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201603L)
4053
#if __has_include(<execution>)
54+
#ifndef POOLSTL_STD_SUPPLEMENT_NO_INCLUDE
4155
#include <execution>
4256
#endif
4357
#endif
58+
#endif
4459

45-
#if !defined(__cpp_lib_parallel_algorithm)
60+
#if !defined(__cpp_lib_parallel_algorithm) || defined(POOLSTL_STD_SUPPLEMENT_FORCE)
4661
namespace std {
4762
namespace execution {
4863
using ::poolstl::execution::sequenced_policy;

tests/CMakeLists.txt

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,25 @@
22
cmake_minimum_required(VERSION 3.11...3.26)
33
enable_testing()
44

5-
# Be pedantic for clean code
6-
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
7-
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -Wextra -pedantic")
5+
if (WIN32)
6+
# Need bigobj because some tests use lots of templates
7+
if (MSVC)
8+
add_compile_options("/bigobj")
9+
elseif(MINGW)
10+
# Also add -Os to reduce maximum filesize
11+
add_compile_options("-Wa,-mbig-obj" "-Os")
12+
endif()
13+
else()
14+
# Be pedantic for clean code
15+
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
16+
add_compile_options("-g" "-Wall" "-Wextra" "-pedantic")
17+
endif()
18+
endif()
19+
20+
if (MINGW AND WIN32)
21+
# The MinGW on GitHub Actions requires these.
22+
# If omitted some executables crash with 'Exit code 0xc0000139' which appears to mean a missing DLL.
23+
add_link_options("-static-libstdc++" "-static-libgcc")
824
endif()
925

1026
# Code Coverage
@@ -55,19 +71,26 @@ add_executable(cpp11_test cpp11_test.cpp)
5571
target_link_libraries(cpp11_test PUBLIC poolSTL::poolSTL)
5672
target_compile_features(cpp11_test PUBLIC cxx_std_11)
5773

58-
# Test std::execution supplementation
59-
# This uses only std::execution::par. On compilers with support this should result in a poolSTL no-op,
60-
# and on ones without support it should use fallback to poolstl::par.
74+
# Test std::execution supplementation.
75+
# The test code uses only std::execution::par, seq, and par_unseq.
76+
# On compilers with support poolSTL does nothing, else poolSTL creates a fallback using poolstl::par.
6177
add_executable(supplement_test supplement_test.cpp)
6278
target_link_libraries(supplement_test PUBLIC poolSTL::poolSTL)
6379
target_compile_features(supplement_test PUBLIC cxx_std_17)
6480
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
65-
# GCC and Clang require TBB for std::execution::par
81+
# GCC and Clang require TBB for std::execution::par.
82+
# MinGW will compile std::execution::par without TBB, but performance is sequential.
6683
find_package(TBB)
6784
if (TBB_FOUND)
6885
target_link_libraries(supplement_test PUBLIC TBB::tbb)
6986
else()
7087
message("No TBB")
71-
target_compile_definitions(supplement_test PUBLIC POOLSTL_MISSING_NEEDED_TBB)
88+
# Prevent including <execution>, as doing that requires linking against TBB on newer GCC/Clang.
89+
target_compile_definitions(supplement_test PUBLIC POOLSTL_STD_SUPPLEMENT_NO_INCLUDE)
90+
if (MINGW)
91+
# extra hack!
92+
# MinGW declares support, so must override poolSTL's auto-detection to enable the supplement.
93+
target_compile_definitions(supplement_test PUBLIC POOLSTL_STD_SUPPLEMENT_FORCE)
94+
endif()
7295
endif()
7396
endif()

tests/supplement_test.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
// The <execution> header defines compiler-provided execution policies, but is not always present.
1111
#if __cplusplus >= 201603L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201603L)
1212
#if __has_include(<execution>)
13-
#ifndef POOLSTL_MISSING_NEEDED_TBB
13+
#ifndef POOLSTL_STD_SUPPLEMENT_NO_INCLUDE
14+
// On GCC and Clang simply including <execution> requires linking with TBB.
15+
// MinGW does not require TBB, but performance may be sequential. To keep parallel performance fallback to poolSTL.
1416
#include <execution>
1517
#endif
1618
#endif

0 commit comments

Comments
 (0)