如何使用CMake构建一个使用C++23标准库模块(导入std)的项目?

huangapple go评论71阅读模式
英文:

How to use CMake to build a project with C++23 standard library module(import std)?

问题

As we know, C++23支持标准库模块。直到2023年5月,MSVC支持它,但我们需要手动添加标准库模块,如Microsoft博客所述

但在CMake项目中如何使用import std呢?MS博客没有提到。并且这些文件无法工作(std.ifc文件来自Microsoft博客教程:cl /std:c++latest /EHsc /nologo /W4 /MTd /c "%VCToolsInstallDir%\modules\std.ixx"(在msvc x64本机控制台中使用))。

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";
}

MSVC显示:

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

我可以复制%VCToolsInstallDir\modules\std.ixx到项目文件夹并将std.ifc更改为std.ixx,但是否有更加优雅的方法来避免每次构建std模块?我认为这是因为.ifc不是源文件,如何在CMake中处理它?

英文:

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 &quot;%VCToolsInstallDir%\modules\std.ixx&quot;(use in msvc x64 native console))

CMakeList.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.26)

set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API &quot;2182bf5c-ef0d-489a-91da-49dbc3090d2a&quot;)
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&lt;&lt;&quot;Hello\n&quot;;
}

And MSVC shows:

[build] main.cpp(1,11): error C2230: Could not find module &quot;std&quot; 
[build] main.cpp(5,5): error C2065: &quot;cout&quot; : 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?

答案1

得分: 3

使用Visual Studio 17.6.0,这变得非常简单。只需将 CMAKE_CXX_STANDARD 设置为使用C++23:

[...]
set(CMAKE_CXX_STANDARD 23)

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

这将将VS配置属性 C/C++-&gt;Language-&gt;C++ Language Standard 设置为 /std:c++latest。Visual Studio 17.6 现在还提供了一个属性 C/C++-&gt;Language-&gt;Build ISO C++23 Standard Library Modules,默认设置为 Yes 并将自动在项目构建中作为 /std:c++latest 构建标准库模块。因此不再需要特殊处理。

CMake 目前正在考虑提供一个控制此属性的选项。

对于较旧版本的Visual Studio,您需要在导入之前自行编译名为 std 的模块。

由于CMake目前不支持导入预编译模块,因此使一切正常运行的最简单方法是简单地在项目中包含标准库的主模块接口。

请确保首先阅读此答案,以了解CMake中C++20模块的当前先决条件和限制。

CMakeLists.txt

[...]
add_executable(demo)

file(COPY
  # 不要在实际项目中硬编码路径,
  # 但你明白意思
  &quot;C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.36.32532/modules/std.ixx&quot;
  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 &lt;&lt; &quot;Hello World\n&quot;;
}

CMake rightly 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.

英文:

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++-&gt;Language-&gt;C++ Language Standard to /std:c++latest. Visual Studio 17.6 now also provides a property C/C++-&gt;Language-&gt;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&#39;t want to hardcode the path here in a real-world project,
  # but you get the idea
  &quot;C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.36.32532/modules/std.ixx&quot;
  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 &lt;&lt; &quot;Hello World\n&quot;;
}

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.

huangapple
  • 本文由 发表于 2023年5月17日 11:55:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76268455.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定