给定一个模块
// a-m.cc
export module A;
import B;
import C;
import "D.h";
...
有没有一种调用 gcc 的方法(类似于 -M 对标头所做的),它将列出对其他模块和导入标头(即 B、C 和“Dh”)的直接依赖关系?
给定一个模块
// a-m.cc
export module A;
import B;
import C;
import "D.h";
...
有没有一种调用 gcc 的方法(类似于 -M 对标头所做的),它将列出对其他模块和导入标头(即 B、C 和“Dh”)的直接依赖关系?
似乎我们可以使用标志调用 gcc -MMD
,它还跟踪模块依赖关系。鉴于我有一个示例项目,我生成它是这样的:
// partition.cpp
export module partition;
import :partition1;
export import :partition2;
export import :partition3;
export void Hello1() { _Hello1(); }
出于某种原因,我需要在编译主模块接口(如上所示的文件)之前编译模块分区,但也许这可以通过某种方式规避。我像这样编译上面的文件:
g++-11 -std=c++20 -fmodules-ts -c -MMD partition.cpp
这会生成一个partition.d
列出模块依赖项的文件:
partition.o gcm.cache/partition.gcm: partition.cpp
partition.o gcm.cache/partition.gcm: partition:partition3.c++m \
partition:partition2.c++m partition:partition1.c++m
partition.c++m: gcm.cache/partition.gcm
.PHONY: partition.c++m
gcm.cache/partition.gcm:| partition.o
CXX_IMPORTS += partition:partition3.c++m partition:partition2.c++m \
partition:partition1.c++m
看起来很有希望,但还需要更多的研究。
我写过/正在写这样的工具。它可以在 github 上找到:https ://github.com/alexpanter/cpp_module_parser 。
它尚未完成,但实际上正在工作。如果表现出兴趣,我将继续扩展它。
我还有一堆带有模块的小示例项目,旨在作为进一步研究的起点:https ://github.com/alexpanter/modules_testing
GCC 在本地目录中查找预编译模块(BMI):./gcm.cache/usr/include/c++/11/iostream.gcm
或(对于本地模块单元)./gcm.cache/,/my-module.gcm
。
如果用户代码导入一个模块,预编译的模块单元必须已经存在于该目录中,否则编译将失败。不幸的是(至少目前)无法为每个构建命令指定另一个目录或自定义目录。这将非常实用,我希望 GCC 开发人员会在某个时候添加它。该gcm.cache/
目录由默认模块映射器使用。可以创建自己的模块映射器,但从阅读中我所做的这听起来像是一个复杂的过程,因为模块映射器本质上是一个 Web 服务器:
与@Laserskjöld 的回答相比,我认为收集预处理器输出也是一个可行的解决方案,因为预处理器可以识别模块导入/导出命令。但是,我认为这不是一个好的解决方案,因为它比我编写的工具要慢得多。一个例子:
module;
#include <iostream>
export module mymodule;
import myothermodule;
export
{
[...]
}
预处理后,该文件将有约 100000 行长,所有行都需要由预处理器处理。但是使用我的工具(或可能更高效的工具),模块解析工具只会读取前 9 行,文件的其余部分将被忽略。此外,拥有模块的目的是减少对预处理器的依赖。
我不知道 gcc 有什么方法可以做到这一点,但我建议编写一个帮助脚本来扩展文件并查找所有名为 的内容import
,然后您可能需要使用"
和对导入进行排序<
并将它们作为标题输出。
然后,您需要找到导出所选模块的文件以与您的导入相匹配。那就是您需要浏览展开的文件并找到以 . 开头的语句export module
。
你扩展文件
g++ -E {include flags, standard version etc} > tmpfile
-E
也适用于 clang++,但对于 msvc 你需要/E
如果有使用 gcc 的直接方法,我也很想知道,但随之而来的问题是:gcc 如何知道在哪里查找模块?
相反,如果您有一个构建系统来跟踪每个模块的位置,您可以像使用编译命令一样指定它。(使用 clang 你指定这个-fmodule-file=
我认为它与 gcc 相同,但尚未测试)。至少这是我在构建系统中所做的。
但总结一下我对你问题的回答。我认为你需要:
import
,export import
和export module
的文件并处理它们。