C++23中的import使用CMake实践

一、使用CMake进行模块编程

在前面开发中对使用import模块开发进行了简单的入门应用说明。但在实际的开发中,可能有更多的开发者使用CMake来开发C++程序,那么如何在cmake中使用模块进行开发呢?本文将对此通过一个基础的例程来进行分析说明。

此处的环境仍然是使用上文一样的环境,Ubuntu25.10,其它均为默认环境(gcc15.2 cmake3.31.6)

二、入门的程序

还是使用一个简单的例程:

c 复制代码
import std;
int main()
{
    std::cout << "Hello World!" << std::endl;
    return 0;
}

下面可以使用两种方法:

  1. 使用g++和cmake
    其CMakelists.txt文件为:
    下面再把直接使用前文命令预编译好后的CMakeLists.txt文件描述一下:

    cmake_minimum_required(VERSION 3.16)

    project(importCMake LANGUAGES CXX)

    set(CMAKE_CXX_STANDARD 23)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    set(CMAKE_CXX_EXTENSIONS OFF)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmodules-ts")
    add_executable(importCMake main.cpp)

    include(GNUInstallDirs)
    install(TARGETS importCMake
    LIBRARY DESTINATION {CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION {CMAKE_INSTALL_BINDIR}
    )

但是需要提前在当前目录编译:

复制代码
g++ -std=c++23 -fmodules-ts -fsearch-include-path -c bits/std.cc

从而生成相关的std库依赖包。其它的编译处理方式与原来的编译没有区别。

直接使用类似下面Clang的直接编译的方式,将依赖库和应用一起编译完成,没有测试成功,总是报工具链不支持。

  1. 使用clang和cmake

其CMakeLists.txt的文件内容为:

复制代码
cmake_minimum_required(VERSION 3.31.6 FATAL_ERROR)
# 实验库CMake匹配GUID支持到 https://github.com/Kitware/CMake/blob/master/Help/dev/experimental.rst查看,必须严格匹配
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
# 设置Clang编译器
set(CMAKE_CXX_COMPILER "clang++")
set(CMAKE_C_COMPILER "clang")
# 使用Clang的libc++
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
set(CMAKE_CXX_EXTENSIONS OFF) # 避免编译命令设置 -std=gnu23
# C++23
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_MODULE_STD 1) # 自动编译 std 模块
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # 生成 compile_commands.json 文件
project(importCMake2 LANGUAGES CXX)
add_executable(importCMake2)
target_sources(importCMake2
  main.cpp
)

在上面的CMake文件中,编译器使用提Clang。尝试了一上午使用g++没有搞定。查询各种资料和相关配置说明,都无法直接使用cmakelists.txt文件一步生成相关的文件。如果象前文一样预编译好gcm文件,倒是也可以使用CMake,但这样失去了便捷性。

三、编译和处理

这里重点分析一下Clang+CMake的编译。在上面的相关文件编写完成后,可以用下面的方法进行编译:

复制代码
#进入工程目录
mkdir build
cd build
cmake -G Ninja ..
ninja

此时会报下面的错误:

复制代码
CMake Error at /usr/share/cmake-3.31/Modules/CMakeTestCXXCompiler.cmake:73 (message):
  The C++ compiler

    "/usr/bin/clang++"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: '/home/fpc/importCMake2/build/CMakeFiles/CMakeScratch/TryCompile-I54ppq'

    Run Build Command(s): /usr/bin/ninja -v cmTC_cd1cc
    [1/2] /usr/bin/clang++   -stdlib=libc++  -std=c++23 -MD -MT CMakeFiles/cmTC_cd1cc.dir/testCXXCompiler.cxx.o -MF CMakeFiles/cmTC_cd1cc.dir/testCXXCompiler.cxx.o.d -o CMakeFiles/cmTC_cd1cc.dir/testCXXCompiler.cxx.o -c /home/fpc/importCMake2/build/CMakeFiles/CMakeScratch/TryCompile-I54ppq/testCXXCompiler.cxx
    [2/2] : && /usr/bin/clang++ -stdlib=libc++ -stdlib=libc++ CMakeFiles/cmTC_cd1cc.dir/testCXXCompiler.cxx.o -o cmTC_cd1cc   && :
    FAILED: cmTC_cd1cc
    : && /usr/bin/clang++ -stdlib=libc++ -stdlib=libc++ CMakeFiles/cmTC_cd1cc.dir/testCXXCompiler.cxx.o -o cmTC_cd1cc   && :
    /usr/bin/ld: 找不到 -lc++: 没有那个文件或目录
    clang++: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:24 (project)

从错误提示可看到需要安装相关的Clang自己的libc++的库,使用下面的命令:

复制代码
sudo apt install libc++-dev

重新编译即可成功。在build/CMakeFiles/__cmake_cxx23.dir目录下,可以看到std.pcm,这和前文中的std.o的功能一致。

四、总结

目前看来,g++和cmake一起相关的匹配细节还是有一些问题。至少是不太方便使用。大家可以使用Clang来写成同样的工作。当然,如果习惯使用g++,也可以使用前文的方式先用命令搞定std库的编译,再使用cmake,也没有问题。

不过大家不用担心,随着最终的版本落地,这种不方便适配的情况会很快改善。

相关推荐
沧澜sincerely1 小时前
蓝桥杯11 路径之谜
c++·蓝桥杯·stl·dfs·剪枝
羑悻的小杀马特1 小时前
深入C++与Redis的异构之美:用redis-plus-plus优雅操控键值宇宙之通用命令版!
c++·redis
MSTcheng.2 小时前
【C++】菱形继承为何会引发二义性?虚继承如何破解?
开发语言·c++
Lion Long2 小时前
C++20 异步编程:用future、promise 还是协程?
开发语言·c++·stl·c++20
渡我白衣2 小时前
计算机组成原理(3):计算机软件
java·c语言·开发语言·jvm·c++·人工智能·python
qq_310658512 小时前
mediasoup源码走读(三)Node.js 控制面
c++·音视频
小龙报2 小时前
【C语言初阶】动态内存分配实战指南:C 语言 4 大函数使用 + 经典笔试题 + 柔性数组优势与内存区域
android·c语言·开发语言·数据结构·c++·算法·visual studio
小龙报2 小时前
【算法通关指南:算法基础篇(三)】一维差分专题:1.【模板】差分 2.海底高铁
android·c语言·数据结构·c++·算法·leetcode·visual studio
小李小李快乐不已2 小时前
图论理论基础(5)
数据结构·c++·算法·机器学习·动态规划·图论