├── main.cpp ├── CMakeLists.txt ├── .github └── workflows │ ├── msvc.yml │ └── clang.yml ├── cmake └── EnableStandardLibraryModule.cmake └── README.md /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | import std; 4 | import std.compat; 5 | 6 | int main() { 7 | std::ifstream file { std::source_location::current().file_name() }; 8 | if (!file) { 9 | std::cerr << "Failed to open file: " << strerror(errno) << '\n'; 10 | std::abort(); 11 | } 12 | 13 | // Read file and store into buffer. 14 | file.seekg(0, std::ios::end); 15 | const std::size_t fileSize = file.tellg(); 16 | std::string buffer(fileSize, ' '); 17 | file.seekg(0); 18 | file.read(buffer.data(), fileSize); 19 | 20 | // Print buffer. 21 | std::cout << buffer; 22 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.26 FATAL_ERROR) 2 | project(CppStandardLibraryModule) 3 | 4 | # -------------------- 5 | # Enable C++20 module support in CMake. 6 | # You can omit this code when you're using CMake ≥ 3.28. 7 | # -------------------- 8 | 9 | if (CMAKE_VERSION VERSION_LESS "3.28.0") 10 | if(CMAKE_VERSION VERSION_LESS "3.27.0") 11 | set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") 12 | else() 13 | set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7") 14 | endif() 15 | set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) 16 | else() 17 | cmake_policy(VERSION 3.28) 18 | endif() 19 | 20 | # -------------------- 21 | # Include CMake scripts. 22 | # -------------------- 23 | 24 | include(cmake/EnableStandardLibraryModule.cmake) 25 | 26 | # -------------------- 27 | # Main executable. 28 | # -------------------- 29 | 30 | add_executable(CppStandardLibraryModule main.cpp) -------------------------------------------------------------------------------- /.github/workflows/msvc.yml: -------------------------------------------------------------------------------- 1 | name: MSVC 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | pull_request: 8 | branches: 9 | - main 10 | schedule: 11 | - cron: '0 0 * * 0' 12 | 13 | jobs: 14 | build: 15 | runs-on: windows-latest 16 | 17 | strategy: 18 | matrix: 19 | std_version: [20, 23] 20 | 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v4 24 | 25 | - name: Use Visual Studio devenv 26 | uses: seanmiddleditch/gha-setup-vsdevenv@master 27 | 28 | - name: Configure 29 | run: | 30 | mkdir build 31 | cmake -S . -B build ` 32 | -G "Visual Studio 17 2022" -T v143 ` 33 | -DCMAKE_CXX_STANDARD=${{ matrix.std_version }} ` 34 | -DVCTOOLS_INSTALL_DIR="$env:VCToolsInstallDir" 35 | 36 | - name: Build 37 | run: | 38 | cmake --build build -t CppStandardLibraryModule --config Release 39 | 40 | - name: Run executable 41 | run: | 42 | build/Release/CppStandardLibraryModule.exe 43 | -------------------------------------------------------------------------------- /cmake/EnableStandardLibraryModule.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR) 2 | 3 | # Check compiler support for C++23 Standard Library Module. 4 | if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "17.0.0") 5 | if (CMAKE_CXX_STANDARD LESS 20) 6 | message(FATAL_ERROR "C++20 or newer is required.") 7 | endif() 8 | 9 | set(CMAKE_CXX_STANDARD_REQUIRED YES) 10 | set(CMAKE_CXX_EXTENSIONS OFF) 11 | 12 | include(FetchContent) 13 | FetchContent_Declare( 14 | std 15 | URL "file://${LIBCXX_BUILD}/modules/c++/v1/" 16 | DOWNLOAD_EXTRACT_TIMESTAMP TRUE 17 | SYSTEM 18 | ) 19 | FetchContent_MakeAvailable(std) 20 | 21 | link_libraries(std c++) 22 | link_libraries(std.compat c++) 23 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "19.36") 24 | if (CMAKE_CXX_STANDARD VERSION_LESS 20) 25 | message(FATAL_ERROR "C++20 or newer is required.") 26 | elseif (CMAKE_CXX_STANDARD VERSION_LESS 23 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.38") 27 | message(FATAL_ERROR "C++23 Standard library module in C++20 is only supported with MSVC 19.38 or newer.") 28 | endif() 29 | 30 | file(TO_CMAKE_PATH "${VCTOOLS_INSTALL_DIR}" VCTOOLS_INSTALL_DIR) 31 | 32 | include(FetchContent) 33 | FetchContent_Declare( 34 | std 35 | URL "file://${VCTOOLS_INSTALL_DIR}/modules" 36 | DOWNLOAD_EXTRACT_TIMESTAMP TRUE 37 | SYSTEM 38 | ) 39 | FetchContent_MakeAvailable(std) 40 | 41 | add_library(std) 42 | target_sources(std PUBLIC 43 | FILE_SET CXX_MODULES 44 | BASE_DIRS ${std_SOURCE_DIR} 45 | FILES 46 | ${std_SOURCE_DIR}/std.ixx 47 | ${std_SOURCE_DIR}/std.compat.ixx 48 | ) 49 | 50 | link_libraries(std) 51 | else() 52 | message(FATAL_ERROR "C++23 Standard library module is not supported with current compiler.") 53 | endif() 54 | -------------------------------------------------------------------------------- /.github/workflows/clang.yml: -------------------------------------------------------------------------------- 1 | name: Clang 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | pull_request: 8 | branches: 9 | - main 10 | schedule: 11 | - cron: '0 0 * * 0' 12 | 13 | jobs: 14 | build: 15 | runs-on: ${{ matrix.os }} 16 | 17 | strategy: 18 | matrix: 19 | os: [ubuntu-latest, macos-latest] 20 | std_version: [20, 23] 21 | 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v4 25 | 26 | - name: Add homebrew to PATH (Linux only) 27 | if: runner.os == 'Linux' 28 | run: | 29 | echo "/home/linuxbrew/.linuxbrew/bin" >> $GITHUB_PATH 30 | 31 | - name: Get LLVM and Ninja via Homebrew 32 | run: | 33 | brew install llvm ninja 34 | echo "CC=$(brew --prefix llvm)/bin/clang" >> "$GITHUB_ENV" 35 | echo "CXX=$(brew --prefix llvm)/bin/clang++" >> "$GITHUB_ENV" 36 | 37 | - name: Cache libc++ build 38 | id: cache-libcxx 39 | uses: actions/cache@v4 40 | with: 41 | path: llvm-project/build 42 | key: ${{ runner.os }}-libcxx 43 | 44 | - name: Make local build of libc++ with Standard Library Module (when cache miss) 45 | if: steps.cache-libcxx.outputs.cache-hit != 'true' 46 | run: | 47 | git clone https://github.com/llvm/llvm-project.git 48 | cd llvm-project 49 | mkdir build 50 | cmake -G Ninja -S runtimes -B build \ 51 | -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ 52 | -DLLVM_INCLUDE_TESTS=OFF 53 | ninja -C build 54 | 55 | - name: Configure 56 | run: | 57 | mkdir build 58 | cmake -S . -G Ninja -B build \ 59 | -DCMAKE_CXX_STANDARD=${{ matrix.std_version }} \ 60 | -DLIBCXX_BUILD=${{ github.workspace }}/llvm-project/build 61 | 62 | - name: Build 63 | run: | 64 | cmake --build build -t CppStandardLibraryModule --config Release 65 | 66 | - name: Run executable 67 | run: | 68 | ./build/CppStandardLibraryModule 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CppStandardLibraryModule 2 | 3 | ![Clang CI](https://github.com/stripe2933/CppStandardLibraryModule/actions/workflows/clang.yml/badge.svg) 4 | ![MSVC CI](https://github.com/stripe2933/CppStandardLibraryModule/actions/workflows/msvc.yml/badge.svg) 5 | 6 | Enable [C++23 standard library module feature, a.k.a. `import std` (P2465R3)](https://wg21.link/P2465R3) in your CMake (≥ 3.26) project. 7 | It also [supported in C++20 as compiler extension](https://github.com/microsoft/STL/issues/3945). 8 | 9 | ## How to do? 10 | 11 | There are prerequisites for using this repository. 12 | 13 | - Your compiler must support the standard library module feature. 14 | - [Clang ≥ 17 with custom module build](https://libcxx.llvm.org/Modules.html): support for both [C++20](https://reviews.llvm.org/D158358) and C++23. Ninja ≥ 1.11 is required. 15 | - [MSVC](https://learn.microsoft.com/en-us/cpp/cpp/tutorial-import-stl-named-module?view=msvc-170): support for C++23 (≥ 19.36), C++20 (≥ 19.38). 16 | - You need CMake ≥ 3.26 for module support in CMake. 17 | 18 | All prerequisites satisfied, your simplest program will be: 19 | 20 | `CMakeLists.txt` 21 | ```cmake 22 | cmake_minimum_required(VERSION 3.28) 23 | project(CppStandardLibraryModule) 24 | 25 | # -------------------- 26 | # Enable C++20 module support in CMake. 27 | # Below code must be uncommented when use CMake < 3.28. 28 | # -------------------- 29 | 30 | #if (CMAKE_VERSION VERSION_LESS "3.28.0") 31 | # if(CMAKE_VERSION VERSION_LESS "3.27.0") 32 | # set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") 33 | # else() 34 | # set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "aa1f7df0-828a-4fcd-9afc-2dc80491aca7") 35 | # endif() 36 | # set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) 37 | #else() 38 | # cmake_policy(VERSION 3.28) 39 | #endif() 40 | 41 | # -------------------- 42 | # Include CMake scripts. 43 | # -------------------- 44 | 45 | file(DOWNLOAD https://raw.githubusercontent.com/stripe2933/CppStandardLibraryModule/main/cmake/EnableStandardLibraryModule.cmake 46 | ${CMAKE_BINARY_DIR}/EnableStandardLibraryModule.cmake 47 | ) 48 | include(${CMAKE_BINARY_DIR}/EnableStandardLibraryModule.cmake) 49 | 50 | # -------------------- 51 | # Main executable. 52 | # -------------------- 53 | 54 | add_executable(CppStandardLibraryModule main.cpp) 55 | ``` 56 | 57 | `main.cpp` 58 | ```c++ 59 | import std; 60 | // import std.compat also available. 61 | 62 | int main(){ 63 | std::cout << "Hello, world!\n"; 64 | } 65 | ``` 66 | 67 | Or simply, you can just clone this template repository. 68 | 69 | ### Clang 70 | 71 | Build Standard Library Module from LLVM repository. 72 | 73 | ```shell 74 | git clone https://github.com/llvm/llvm-project.git 75 | cd llvm-project 76 | mkdir build 77 | cmake -G Ninja -S runtimes -B build \ 78 | -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" 79 | ninja -C build 80 | ``` 81 | 82 | After that, specify the CMake variable `LIBCXX_BUILD` to your custom module build directory, explained at [Libc++ website](https://libcxx.llvm.org/Modules.html) in detail. 83 | 84 | ```shell 85 | cd 86 | mkdir build 87 | cmake -S . -B build -G Ninja \ 88 | -DCMAKE_CXX_STANDARD=20 \ 89 | -DLIBCXX_BUILD= 90 | ninja -C build 91 | # Your executable will be at /build 92 | ``` 93 | 94 | Here's [the Clang CI](.github/workflows/clang.yml) for your insight. 95 | 96 | ### MSVC 97 | 98 | Specify the CMake variable `VCTOOLS_INSTALL_DIR`, which can be directly fetched 99 | via `$env:VCToolsInstallDir` in *x86 Native Tools Command Prompt for VS*, explained at [Microsoft documentation](https://learn.microsoft.com/en-us/cpp/cpp/tutorial-import-stl-named-module?view=msvc-170) 100 | in detail. 101 | 102 | ```shell 103 | cd 104 | mkdir build 105 | cmake -S . -B build -G "Visual Studio 17 2022" -T v143 ` 106 | -DCMAKE_CXX_STANDARD=20 ` 107 | -DVCTOOLS_INSTALL_DIR="$env:VCToolsInstallDir" 108 | cmake --build build -j4 109 | # Your executable will be at build\Release 110 | ``` 111 | 112 | Here's [the MSVC CI](.github/workflows/msvc.yml) for your insight. --------------------------------------------------------------------------------