如何使用CMake用C++23标准库模块(import std)构建项目?

wyyhbhjk  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(348)

众所周知,C ++23支持标准库模块。直到2023年5月,MSVC支持它,但我们需要手动添加标准库模块作为Microsoft blog mentioned
那么如何在CMake项目中使用import std呢?MS博客没有提到它。而这些文件无法工作。(std.ifc文件来自微软博客教程: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,但是否有更优雅的方法来实现它,以避免每次构建标准模块?我想是因为.ifc不是源文件,在CMake中如何处理?

rn0zuynd

rn0zuynd1#

在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++->Language->C++ Language Standard设置为/std:c++latest。Visual Studio 17.6现在还提供了一个属性C/C++->Language->Build ISO C++23 Standard Library Modules,默认情况下设置为Yes,并将自动在/std:c++latest上构建标准库模块作为项目构建的一部分。因此不再需要特殊处理。
CMake目前是considering to provide an option for controlling this property
对于旧版本的Visual Studio,您必须在导入std模块 yourself 之前编译它。
由于CMake目前不支持导入预编译模块,因此最简单的方法是在项目中包含标准库的主模块接口。
请务必先阅读this answer以了解CMake中C++20模块的当前先决条件和限制。
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正确地阻止您在构建中包含源代码树之外的模块源代码。因此,我们将模块接口文件复制到我们的二叉树中进行构建。
通常,不允许在程序中多次出现相同的主模块接口。相应地构造构建,这样就不会意外地导致std.ixx被编译两次。

相关问题