C++23中的自定义模块开发

一、模块开发

在前面的开发中,基本都是使用标准库中的模块直接调用。在本文中,将自己开发一个模块供程序调用,这样,就可以真正的进入了模块自行开发的实际应用场景。这和前面的动态库开发的思想有些类似,大家可以对比着来看。

二、编写一个模块并调用

看一下自定义模块的代码:

c 复制代码
//exportdemo.h
export module demo;
import std;
namespace demo{
export int Add(int,int);
export class exportDemo
{
public:
    exportDemo();
public:
    void display();
};
}
//exportdemo.cpp
module demo;
import std;
namespace demo{
int Add(int a,int b){return a+b;}
exportDemo::exportDemo() {}
void exportDemo::display(){
    std::cout<<"this is demo module!"<<std::endl;
}
}

标准的头文件加cpp文件,再看一下调用代码:

c 复制代码
import std;
import demo;

int main()
{
    demo::exportDemo d;
    d.display();
    std::cout << "main app!"<<"Add return:"<<demo::Add(1,2) << std::endl;
    return 0;
}

首先使用命令行进行编译:

复制代码
1. 先编译std.o
g++ -std=c++23 -fmodules-ts -fsearch-include-path -c bits/std.cc
在当前目录下可以发现生成的std.o和gcm文件夹
2. 编译模块文件
g++ -std=c++23 -fmodules-ts -c exportdemo.h
会报一个错误:
exportdemo.h:4:8: error: module-declaration not permitted in header-unit
    4 | export module demo;

看错误的说明是不能将模块声明放到头文件,好,那就随便起一个名字,比如exportdemo.cm,再次编译:

复制代码
g++ -std=c++23 -fmodules-ts -c exportdemo.cm

会报另外一个警告和一个错误:

复制代码
g++: warning: exportdemo.cm: linker input file unused because linking not done
error: exportdemo.cm: linker input file not found: 没有那个文件或目录

看这样子应该是没找到相关的输入文件。再次修改文件名称为exportdemo.cppm并重新编译:

复制代码
g++ -std=c++23 -fmodules-ts -c exportdemo.cppm

编译成功。给大家留一个问题,这个模块文件名称是否可以随便取?叫exportdemo.ixx或exportdemo.ccm、exportdemo.cxxm可不可以?还有没有其它的规则限制?

再模块编译成功的基础上继续编译:

复制代码
3. 编译所有单元
g++ -std=c++23 -fmodules-ts -o demo exportdemo.cpp main.cpp

编译成功,在当前路径下有一个demo可执行文件,执行它:

复制代码
./demo
this is demo module!
main app!Add return:3

说明编译流程整体走通,没有问题。

三、使用cmake编译

先看一下cmakelists.txt的文件内容:

复制代码
cmake_minimum_required(VERSION 3.31.6 )

set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
set(CMAKE_CXX_COMPILER "clang++")
set(CMAKE_C_COMPILER "clang")

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)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_MODULE_STD 1)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

project(cmakeMouduleFirst LANGUAGES CXX)
add_executable(cmakeMouduleFirst)
target_sources(cmakeMouduleFirst
  PRIVATE
    main.cpp
    exportdemo.cpp
 PRIVATE FILE_SET demoMmodules TYPE CXX_MODULES FILES
  exportdemo.cppm
)

文件内容整体和上一次的没有太大差别,主要是增加了对新增模块的引用,在target_sources增加相关的模块文件编译文件。然后使用cmake编译:

复制代码
mkdir build &&cd build
cmake -G Ninja ..
-- The CXX compiler identification is Clang 20.1.8
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (1.9s)
CMake Error in CMakeLists.txt:
  The "CXX_MODULE_STD" property on the target "cmakeMouduleFirst" requires
  that the "__CMAKE::CXX23" target exist, but it was not provided by the
  toolchain.  Reason:

    Experimental `import std` support not enabled when detecting toolchain; it must be set before `CXX` is enabled (usually a `project()` call)


-- Generating done (0.0s)
CMake Generate step failed.  Build files cannot be regenerated correctly.

这是原来用g++编译才报得错误啊,想了一下,忽然想到刚刚编译了一个最新cmake 4.0,并临时在环境变量里进行了指定。会不是是这个原因呢?然后查看了一下cmake版本,果然是4.0,重新打开一个终端,再次查看了一下cmake版本,是3.31.6。重新使用上面的命令编译:

复制代码
cmake -G Ninja ..
-- The CXX compiler identification is Clang 20.1.8
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/clang++ - skipped
-- Detecting CXX compile features
CMake Warning (dev) at /usr/share/cmake-3.31/Modules/Compiler/CMakeCommonCompilerMacros.cmake:248 (cmake_language):
  CMake's support for `import std;` in C++23 and newer is experimental.  It
  is meant only for experimentation and feedback to CMake developers.
Call Stack (most recent call first):
  /usr/share/cmake-3.31/Modules/CMakeDetermineCompilerSupport.cmake:113 (cmake_create_cxx_import_std)
  /usr/share/cmake-3.31/Modules/CMakeTestCXXCompiler.cmake:83 (CMAKE_DETERMINE_COMPILER_SUPPORT)
  CMakeLists.txt:19 (project)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Detecting CXX compile features - done
-- Configuring done (0.4s)
-- Generating done (0.0s)

编译成功。这就是那个cmake中"CMAKE_EXPERIMENTAL_CXX_IMPORT_STD"对应的ID的问题。执行编译后的可执行文件,可呈现与直接编译相同的结果。

四、总结

对新技术的学习,不用突飞猛进,细雨无声,慢慢掌握即可。其实对于模块编程,目前尚未听说哪家公司已经在大规模的铺开,所以还是有时间慢慢来学习并应用于实践的。

相关推荐
qq_310658512 小时前
mediasoup源码走读(十二)——router
服务器·c++·音视频
落羽的落羽2 小时前
【C++】哈希扩展——位图和布隆过滤器的介绍与实现
linux·服务器·开发语言·c++·人工智能·算法·机器学习
汪宁宇2 小时前
如何在QT5+MinGW环境中编译使用QGIS开发地图应用
c++·qt·qgis·mingw·地图库
fish_xk3 小时前
类和对象(二)
开发语言·c++·算法
MC皮蛋侠客3 小时前
C++编译死机排查工具与实战指南
c++
tang&3 小时前
双指针算法:化繁为简的优雅解法
数据结构·c++·算法
爱装代码的小瓶子3 小时前
【c++知识铺子】封装map和set(详细版)
android·java·c++
明洞日记3 小时前
【VTK手册026】高性能网格简化——vtkQuadricClustering 深度解析
c++·图像处理·vtk·图形渲染
xiaoye-duck3 小时前
C++入门基础指南:引用全解析(从入门到精通)
c++