Skip to content
Merged
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
95 changes: 66 additions & 29 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,62 @@ jobs:
fail-fast: false

# Set up a matrix to run the following 3 configurations:
# 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
# 2. <Linux, Release, latest GCC compiler toolchain on the default runner image, default generator>
# 3. <Linux, Release, latest Clang compiler toolchain on the default runner image, default generator>
# 1. <Linux, Release, latest GCC compiler toolchain on the default runner image, default generator>
# 2. <Linux, Release, latest LLVM compiler toolchain on the default runner image, default generator>
# 3. <MacOS, Release, latest LLVM compiler toolchain on the default runner image, default generator>
# 4. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
#
# To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
matrix:
runner: [ubuntu-26.04, windows-2025-vs2026]
runner: [ubuntu-26.04, windows-2025-vs2026, macos-26-intel]
build_type: [Release]
c_compiler: [gcc-15, clang-22, cl]
toolchain: [gnu, llvm, msvc, xcode]
include:
- runner: windows-2025-vs2026
os: Windows
c_compiler: cl
cpp_compiler: cl
- runner: ubuntu-26.04
toolchain: gnu
c_compiler: gcc-15
cpp_compiler: g++-15
- runner: ubuntu-26.04
toolchain: llvm
c_compiler: clang-22
cpp_compiler: clang++-22
- runner: macos-26-intel
toolchain: llvm
c_compiler: /usr/local/opt/llvm@20/bin/clang
cpp_compiler: /usr/local/opt/llvm@20/bin/clang++
- runner: windows-2025-vs2026
toolchain: msvc
c_compiler: cl
cpp_compiler: cl
exclude:
- runner: ubuntu-26.04
toolchain: xcode
- runner: ubuntu-26.04
toolchain: msvc
- runner: macos-26-intel
toolchain: gnu
- runner: macos-26-intel
toolchain: xcode # xcode lacking clang-scan-deps
- runner: macos-26-intel
toolchain: msvc
- runner: windows-2025-vs2026
c_compiler: gcc-15
toolchain: gnu
- runner: windows-2025-vs2026
c_compiler: clang-22
- runner: ubuntu-26.04
c_compiler: cl
toolchain: llvm
- runner: windows-2025-vs2026
toolchain: xcode

steps:
- uses: actions/checkout@v5

- name: Install libc++ for Clang
- name: Install libc++ for Clang-22
if: matrix.c_compiler == 'clang-22'
run: |
sudo apt-get update
sudo apt-get install -y clang-22 clang-tools-22 libc++-22-dev libc++abi-22-dev

- uses: ilammy/msvc-dev-cmd@v1
if: matrix.c_compiler == 'cl'
if: matrix.toolchain == 'msvc'
with:
arch: x64

Expand All @@ -65,44 +82,65 @@ jobs:
run: |
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"

case "${{ matrix.c_compiler }}" in
gcc*)
# conan_compiler and conan_compiler_version

case "${{ matrix.toolchain }}" in
gnu)
conan_compiler=gcc
conan_compiler_version=$(${{ matrix.c_compiler }} -dumpversion | cut -d. -f1)
;;
clang*)
llvm)
conan_compiler=clang
conan_compiler_version=$(${{ matrix.c_compiler }} -dumpversion | cut -d. -f1)
;;
xcode)
conan_compiler=apple-clang
conan_compiler_version=$(${{ matrix.c_compiler }} -dumpversion | cut -d. -f1)
;;
cl)
msvc)
conan_compiler=msvc
conan_compiler_version=195
;;
*)
echo "Invalid toolchain: ${{ matrix.toolchain }}"
exit 1
;;
esac
echo "conan_compiler=$conan_compiler" >> "$GITHUB_OUTPUT"
echo "conan_compiler_version=$conan_compiler_version" >> "$GITHUB_OUTPUT"

case "${{ matrix.c_compiler }}" in
gcc*)
conan_compiler_version=$(${{ matrix.c_compiler }} -dumpversion | cut -d. -f1)
# conan_os

case "${RUNNER_OS}" in
Linux)
conan_os=Linux
;;
clang*)
conan_compiler_version=$(${{ matrix.c_compiler }} -dumpversion | cut -d. -f1)
macOS)
conan_os=Macos
;;
cl)
conan_compiler_version=195
Windows)
conan_os=Windows
;;
*)
echo "Invalid os: ${RUNNER_OS}"
exit 1
;;
esac
echo "conan_compiler_version=$conan_compiler_version" >> "$GITHUB_OUTPUT"
echo "conan_os=$conan_os" >> "$GITHUB_OUTPUT"

- name: Create Conan Dependencies Profile
shell: bash
run: |
cat << EOF > profile.txt
[settings]
arch=x86_64
os=$RUNNER_OS
os=${{ steps.strings.outputs.conan_os }}
compiler=${{ steps.strings.outputs.conan_compiler }}
compiler.version=${{ steps.strings.outputs.conan_compiler_version }}
compiler.cppstd=23
$([[ "${{ steps.strings.outputs.conan_compiler }}" == "gcc" ]] && echo "compiler.libcxx=libstdc++11")
$([[ "${{ steps.strings.outputs.conan_compiler }}" == "clang" ]] && echo "compiler.libcxx=libc++")
$([[ "${{ steps.strings.outputs.conan_compiler }}" == "apple-clang" ]] && echo "compiler.libcxx=libc++")
$([[ "${{ steps.strings.outputs.conan_compiler }}" == "msvc" ]] && echo "compiler.runtime=static")

[buildenv]
Expand Down Expand Up @@ -141,7 +179,6 @@ jobs:
.

- name: Build
# Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
run: >
cmake
--build ${{ steps.strings.outputs.build-output-dir }}
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,17 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# problematic in github CI
set(CMAKE_CXX_MODULE_STD OFF)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
# not supported
set(CMAKE_CXX_MODULE_STD OFF)
else()
set(CMAKE_CXX_MODULE_STD ON)
endif()

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)



# Options
option(ENABLE_EIGEN "Add Eigen support?" OFF)
option(ENABLE_CUDA "Add Cuda support?" OFF)
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Template project for C++20/23 module support in CMake. For more information see
### Tools

* cmake>=3.26
* conan>=2.29.0
* ninja>=1.11.1

### Compilers
Expand Down Expand Up @@ -86,7 +87,10 @@ One of:

## Build and Test

### Clang
> [!NOTE]
> This project uses a cononcial conan-driven buildchain for building dependencies. A CMake driven approach using [cmake-conan](https://github.com/conan-io/cmake-conan) is possible with conan>=2. For more information, see: [conan CMake integrations](https://docs.conan.io/2/integrations/cmake.html) and [conan/issues/17361](https://github.com/conan-io/conan/issues/17361)

### LLVM

```bash
export CONAN_PROFILE=profile-clang-<machine-name>.txt
Expand Down Expand Up @@ -118,9 +122,7 @@ cmake --build build/gcc --config Release -j8
ctest -preset=${CONAN_PROFILE} --no-compress-output --verbose
```

## Dockerfile

### Clang
### Docker LLVM

```bash
# build
Expand All @@ -129,7 +131,7 @@ docker build -t cmake-cpp-modules-template-clang -f docker/Dockerfile-clang .
docker run --security-opt seccomp=unconfined -it --rm cmake-cpp-modules-template-clang
```

### GNU
### Docker GNU

```bash
# build
Expand Down
6 changes: 2 additions & 4 deletions targets/cpp-deps-modules/libcxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ cmake_minimum_required(VERSION 3.26)
set(TARGET_NAME libcxx)
add_library(${TARGET_NAME})

if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_options(${TARGET_NAME} PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-stdlib=libc++>)
target_link_options(${TARGET_NAME} PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-stdlib=libc++>)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(${TARGET_NAME} PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-Wmodule-conflict>)
endif()

target_compile_definitions(${TARGET_NAME} PRIVATE CXX_MODULE_STD=$<BOOL:${CMAKE_CXX_MODULE_STD}>)
# target_compile_definitions(${TARGET_NAME} PRIVATE _LIBCPP_STD_VER=23)
target_compile_definitions(${TARGET_NAME} PRIVATE _LIBCPP_USING_IF_EXISTS=)
target_compile_definitions(${TARGET_NAME} PRIVATE _LIBCPP_STD_VER=23)
target_compile_definitions(${TARGET_NAME} PRIVATE _LIBCPP_HAS_LOCALIZATION=1)
target_compile_definitions(${TARGET_NAME} PRIVATE _LIBCPP_HAS_WIDE_CHARACTERS=1)
target_compile_definitions(${TARGET_NAME} PRIVATE _LIBCPP_HAS_THREADS=1)
Expand Down
2 changes: 2 additions & 0 deletions targets/cpp-deps-modules/libcxx/std.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ export import std;
#include <expected>
#include <filesystem>
#include <flat_map>
#if __has_include(<flat_set>)
#include <flat_set>
#endif // __has_include(<flat_set>)
#include <format>
#include <forward_list>
#include <fstream>
Expand Down
2 changes: 2 additions & 0 deletions targets/cpp-deps-modules/libcxx/std/algorithm.inc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export namespace std {
#endif
using std::ranges::min_max_result;
#if _LIBCPP_STD_VER >= 23
# if !defined(__clang__) || __clang_major__ > 20
using std::ranges::out_value_result;
# endif // !defined(__clang__) || __clang_major__ > 20
#endif
} // namespace ranges

Expand Down
4 changes: 4 additions & 0 deletions targets/cpp-deps-modules/libcxx/std/chrono.inc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ export namespace std {

using std::chrono::duration_values;

#if _LIBCPP_STD_VER >= 20
# if !defined(__clang__) || __clang_major__ > 20
using std::chrono::is_clock;
using std::chrono::is_clock_v;
# endif // !defined(__clang__) || __clang_major__ > 20
#endif

// [time.duration.nonmember], duration arithmetic
using std::chrono::operator+;
Expand Down
2 changes: 1 addition & 1 deletion targets/cpp-deps-modules/libcxx/std/flat_set.inc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//

export namespace std {
#if _LIBCPP_STD_VER >= 23
#if _LIBCPP_STD_VER >= 23 && __cpp_lib_constexpr_flat_set >= 202502L
// [flat.set], class template flat_­set
using std::flat_set;

Expand Down
2 changes: 1 addition & 1 deletion targets/cpp-deps-modules/libcxx/std/numeric.inc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export namespace std {

namespace ranges {

#if _LIBCPP_STD_VER >= 23
#if _LIBCPP_STD_VER >= 23 && __cpp_lib_ranges_iota >= 202202L
using std::ranges::iota;
using std::ranges::iota_result;
#endif // _LIBCPP_STD_VER >= 23
Expand Down
10 changes: 6 additions & 4 deletions targets/cpp-deps-modules/libcxx/std/ranges.inc
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ export namespace std {
using std::ranges::dangling;

#if _LIBCPP_STD_VER >= 23
# if !defined(__clang__) || __clang_major__ > 20
// [range.elementsof], class template elements_­of
using std::ranges::elements_of;
# endif
#endif

using std::ranges::borrowed_iterator_t;
Expand Down Expand Up @@ -247,14 +249,14 @@ export namespace std {
using std::ranges::views::join;
} // namespace views

#if _LIBCPP_STD_VER >= 23
#if _LIBCPP_STD_VER >= 23 && __cpp_lib_ranges_join_with >= 202202L
// [range.join.with]
using std::ranges::join_with_view;

namespace views {
using std::ranges::views::join_with;
} // namespace views
#endif // _LIBCPP_STD_VER >= 23
#endif // _LIBCPP_STD_VER >= 23 && __cpp_lib_ranges_join_with >= 202202L

using std::ranges::lazy_split_view;

Expand Down Expand Up @@ -305,7 +307,7 @@ export namespace std {
using std::ranges::views::values;
} // namespace views

#if _LIBCPP_STD_VER >= 23
#if _LIBCPP_STD_VER >= 23 && __cpp_lib_ranges_zip >= 202110L
// [range.zip], zip view
using std::ranges::zip_view;

Expand Down Expand Up @@ -333,7 +335,7 @@ export namespace std {
using std::ranges::views::pairwise_transform;
} // namespace views

#endif // _LIBCPP_STD_VER >= 23
#endif // _LIBCPP_STD_VER >= 23 && __cpp_lib_ranges_zip >= 202110L

#if 0
using std::ranges::chunk_view;
Expand Down
8 changes: 8 additions & 0 deletions targets/cpp-deps-modules/libcxx/std/type_traits.inc
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,14 @@ export namespace std {

#if _LIBCPP_STD_VER >= 23
# if __has_builtin(__reference_constructs_from_temporary)
# if !defined(__clang__) || __clang_major__ > 20
using std::reference_constructs_from_temporary;
# endif // !defined(__clang__) || __clang_major__ > 20
# endif
# if __has_builtin(__reference_converts_from_temporary)
# if !defined(__clang__) || __clang_major__ > 20
using std::reference_converts_from_temporary;
# endif // !defined(__clang__) || __clang_major__ > 20
# endif
#endif

Expand Down Expand Up @@ -292,10 +296,14 @@ export namespace std {
using std::is_volatile_v;
#if _LIBCPP_STD_VER >= 23
# if __has_builtin(__reference_constructs_from_temporary)
# if !defined(__clang__) || __clang_major__ > 20
using std::reference_constructs_from_temporary_v;
# endif // !defined(__clang__) || __clang_major__ > 20
# endif
# if __has_builtin(__reference_converts_from_temporary)
# if !defined(__clang__) || __clang_major__ > 20
using std::reference_converts_from_temporary_v;
# endif // !defined(__clang__) || __clang_major__ > 20
# endif
#endif

Expand Down
Loading