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,也没有问题。

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

相关推荐
2401_831824962 小时前
基于C++的区块链实现
开发语言·c++·算法
汉克老师2 小时前
GESP5级C++考试语法知识(六、链表(一)单链表)
c++·链表·单链表·快慢指针·进阶·gesp5级·gesp五级
m0_518019483 小时前
C++与机器学习框架
开发语言·c++·算法
qq_417695053 小时前
C++中的代理模式高级应用
开发语言·c++·算法
学嵌入式的小杨同学3 小时前
STM32 进阶封神之路(十九):ADC 深度解析 —— 从模拟信号到数字转换(底层原理 + 寄存器配置)
c++·stm32·单片机·嵌入式硬件·mcu·架构·硬件架构
xiaoye-duck3 小时前
《算法题讲解指南:动态规划算法--路径问题》--5.不同路径,6.不同路径II
c++·算法·动态规划
ambition202423 小时前
最大子数组和算法全解析:从暴力枚举到动态规划优化
数据结构·c++·算法
qq_461489334 小时前
C++与Qt图形开发
开发语言·c++·算法
小菜鸡桃蛋狗5 小时前
C++——类和对象(上)
开发语言·c++
2401_879503415 小时前
C++中的观察者模式变体
开发语言·c++·算法