简体   繁体   English

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

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

As we know, C++23 support Standard Library Modules.众所周知,C++23 支持标准库模块。 Until May 2023, MSVC support it but we need add Standard Library Modules manually as Microsoft blog mentioned .直到 2023 年 5 月,MSVC 都支持它,但我们需要手动添加标准库模块,如Microsoft 博客所述

But how to use import std in CMake project?但是如何在CMake项目中使用import std呢? 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))而这些文件不能工作。( std.ifc文件取自微软博客教程: cl /std:c++latest /EHsc /nologo /W4 /MTd /c "%VCToolsInstallDir%\modules\std.ixx" (在 msvc x64 本机控制台中使用))

CMakeList.txt 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主.cpp

import std;
using namespace std;

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

And MSVC shows: MSVC 显示:

[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?我可以使用复制%VCToolsInstallDir\modules\std.ixx到项目文件夹并将std.ifc更改为std.ixx ,但是是否有更优雅的方法来实现它以避免每次构建 std 模块? I think it's because .ifc is not a source file,how to deal with it in CMake?我想是因为.ifc不是源文件,CMake怎么处理?

With Visual Studio version 17.6.0 this became very straightforward.在 Visual Studio 版本 17.6.0 中,这变得非常简单。 Simply set CMAKE_CXX_STANDARD to use C++23:只需将CMAKE_CXX_STANDARD设置为使用 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 .这会将 VS 配置属性C/C++->Language->C++ Language Standard设置为/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. Visual Studio 17.6 现在还提供了属性C/C++->Language->Build ISO C++23 Standard Library Modules ,默认情况下设置为Yes并将自动在/std:c++latest上构建标准库模块作为一部分你的项目构建。 So no special handling is required anymore.因此不再需要特殊处理。

CMake is currently considering to provide an option for controlling this property . CMake 目前正在考虑提供一个控制此属性的选项

For older versions of Visual Studio, you will have to compile the std named module yourself before importing it.对于旧版本的 Visual Studio,您必须在导入之前自行编译std命名模块。

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.由于 CMake 目前不支持导入预编译模块,因此最简单的运行方式是在项目中简单地包含标准库的主要模块接口。

Be sure to first read this answer to understand the current prerequisites and limitations of the C++20 modules in CMake.请务必先阅读此答案以了解 CMake 中 C++20 模块的当前先决条件和限制。

CMakeLists.txt 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演示.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. CMake 正确地阻止您在构建中包含源代码树之外的模块源。 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.相应地构建你的构建,这样你就不会意外地以std.ixx被编译两次而告终。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 C++23 中将标准库宏与 std 模块一起使用 - How to use standard library macros with std module in C++23 C++23 中的 constexpr function 有什么用? - What is the use of a constexpr function in C++23? 为什么在 C++23 中弃用 std::aligned_storage 以及使用什么代替? - Why is std::aligned_storage to be deprecated in C++23 and what to use instead? C++23 中 std::string::contains 的时间复杂度是多少? - What's the time complexity of std::string::contains in C++23? 如何在不编写标识样板的情况下访问 C++23 std::optional 中包含的值? - How to access contained value in C++23 std::optional without writing identity boilerplate? C++23 多线程应用程序中的 std::start_lifetime_as 和 UB - std::start_lifetime_as and UB in C++23 multithreaded application 如何在C ++模块中使用标准库? (例如:`import std.io`) - how to use standard library with C++ modules? (eg: `import std.io`) 如何使用 GCC 12.1 生成 C++23 堆栈跟踪? - How can I generate a C++23 stacktrace with GCC 12.1? 是否在 c++23 中向 std::string 添加了一个接受 std::array 的新构造函数<char, n> ?</char,> - Was a new constructor added to std::string in c++23 that accepts std::array<char, N>? 理解 C++23 中的 std::inout_ptr 和 std::out_ptr - Understanding std::inout_ptr and std::out_ptr in C++23
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM