4

As we know, C++23 support Standard Library Modules. Until May 2023, MSVC support it but we need add Standard Library Modules manually as Microsoft blog mentioned.

But how to use import std in CMake project? The MS blog doesn't mentioned it. And these files can't work.(The std.ifc file is obtained from microsoft blog tutorial:cl /std:c++latest /EHsc /nologo /W4 /MTd /c "%VCToolsInstallDir%\modules\std.ixx"(use in msvc x64 native console))

CMakeList.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.26)

set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP ON)

set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${CMAKE_PROJECT_NAME})


set(CMAKE_CXX_STANDARD 23)

project(1-1)

add_executable(${CMAKE_PROJECT_NAME})
target_sources(${CMAKE_PROJECT_NAME}
    PUBLIC
    FILE_SET all_my_modules TYPE CXX_MODULES FILES
    main.cpp
    std.ifc
)

main.cpp

import std;
using namespace std;

int main(){
    cout<<"Hello\n";
}

And MSVC shows:

[build] main.cpp(1,11): error C2230: Could not find module "std" 
[build] main.cpp(5,5): error C2065: "cout" : Undeclared identifier 

I can use copy %VCToolsInstallDir\modules\std.ixx to project folder and change std.ifc to std.ixx, but is there a more elegant way to achieve it to avoid building std module every time? I think it's because .ifc is not a source file,how to deal with it in CMake?

Leen Hawk
  • 101
  • 7

1 Answers1

3

With Visual Studio version 17.6.0 this became very straightforward. Simply set CMAKE_CXX_STANDARD to use C++23:

[...]
set(CMAKE_CXX_STANDARD 23)

add_executable(demo)
target_sources(demo
  PRIVATE
    demo.cpp
)

This will set the VS configuration property C/C++->Language->C++ Language Standard to /std:c++latest. Visual Studio 17.6 now also provides a property C/C++->Language->Build ISO C++23 Standard Library Modules which by default is set to Yes and will automatically build the standard library modules on /std:c++latest as part of your project build. So no special handling is required anymore.

CMake is currently considering to provide an option for controlling this property.

For older versions of Visual Studio, you will have to compile the std named module yourself before importing it.

Since CMake does not support importing pre-compiled modules at the moment, the easiest way to get things running is therefore to simply include the primary module interface for the standard library in your project.

Be sure to first read this answer to understand the current prerequisites and limitations of the C++20 modules in CMake.

CMakeLists.txt

[...]
add_executable(demo)

file(COPY
  # you don't want to hardcode the path here in a real-world project,
  # but you get the idea
  "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.36.32532/modules/std.ixx"
  DESTINATION
  ${PROJECT_BINARY_DIR}/stdxx
)

target_sources(demo
  PRIVATE
  FILE_SET CXX_MODULES FILES
  ${PROJECT_BINARY_DIR}/stdxx/std.ixx
  PRIVATE
  demo.cpp
)

demo.cpp

import std;

int main()
{
    std::cout << "Hello World\n";
}

CMake rightfully prevents you from including module sources outside of your source tree in the build. So we will copy the module interface file to our binary tree for building.

As usual, having the same primary module interface appear more than once in a program is not allowed. Structure your build accordingly so that you don't accidentally end up with std.ixx being compiled twice.

ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
  • Could I understand there is no method to use pre-compiled module in cmake now? – Leen Hawk May 18 '23 at 06:13
  • 1
    @LeenHawk That is correct. There's still a couple of unresolved issues in that area that tooling vendors will need to figure out. See e.g. [P2577](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2577r2.pdf) for details. Build2 already supports this through a proprietary metadata file format (which then also only works for build2, naturally), but all the other build systems will likely depend on SG15 to release a standardized format before supporting this. – ComicSansMS May 19 '23 at 07:57
  • 1
    @LeenHawk And finally, as suspected, the whole endeavour just became a lot easier with the last Visual Studio update. I updated the answer accordingly. – ComicSansMS May 21 '23 at 11:09