4

给定一个模块

// a-m.cc
export module A;

import B;
import C;

import "D.h";

...

有没有一种调用 gcc 的方法(类似于 -M 对标头所做的),它将列出对其他模块和导入标头(即 B、C 和“Dh”)的直接依赖关系?

4

2 回答 2

2

[编辑]

似乎我们可以使用标志调用 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 行,文件的其余部分将被忽略。此外,拥有模块的目的是减少对预处理器的依赖。

于 2021-10-17T13:02:42.317 回答
0

我不知道 gcc 有什么方法可以做到这一点,但我建议编写一个帮助脚本来扩展文件并查找所有名为 的内容import,然后您可能需要使用"和对导入进行排序<并将它们作为标题输出。

然后,您需要找到导出所选模块的文件以与您的导入相匹配。那就是您需要浏览展开的文件并找到以 . 开头的语句export module

你扩展文件

g++ -E {include flags, standard version etc} > tmpfile

-E也适用于 clang++,但对于 msvc 你需要/E

如果有使用 gcc 的直接方法,我也很想知道,但随之而来的问题是:gcc 如何知道在哪里查找模块?

相反,如果您有一个构建系统来跟踪每个模块的位置,您可以像使用编译命令一样指定它。(使用 clang 你指定这个-fmodule-file=我认为它与 gcc 相同,但尚未测试)。至少这是我在构建系统中所做的。

但总结一下我对你问题的回答。我认为你需要:

  • 展开您的源文件
  • 查找所有带有import,export importexport module的文件并处理它们。
于 2021-03-30T13:37:59.923 回答