【问题标题】:error: failed to read compiled module: No such file or directory错误:无法读取已编译的模块:没有这样的文件或目录
【发布时间】:2021-03-30 17:10:21
【问题描述】:

我刚刚购买了《Beginning C++20》(电子书版)一书,我正在尝试使用新的 C++20 方法编译第一个示例。

源文件的内容是

// Ex1_01.cpp
// A Complete C++ program
import <iostream>;

int main()
{
    int answer{42};     // Defines answer with 42
    std::cout << "The answer to life, the universe, and everything is "
        << answer
        << std::endl;
    return 0;
}

如果我理解正确的话,GCC 版本 10 或 11 尚不支持此功能(有些网站声称 GCC 11 支持它,但是当我使用 -fmodules-ts 标志时,因为有些人建议有一条错误消息表明它没有实现/实验并退出。

经过一番搜索,我找到了一些引用 https://gcc.gnu.org/wiki/cxx-modules 的帖子,其中有安装支持模块的 GCC 10 版本的说明(使用 -fmodules-ts 标志)但是当我在示例代码中使用它时我收到以下错误:

In module imported at Ex1_01.cpp:3:1:
/usr/local/include/c++/10.0.0/iostream: error: failed to read compiled module: No such file or directory
/usr/local/include/c++/10.0.0/iostream: note: compiled module file is ‘gcm.cache/./usr/local/include/c++/10.0.0/iostream.gcm’
/usr/local/include/c++/10.0.0/iostream: fatal error: jumping off the crazy train to crashville
compilation terminated.

gcc 的版本是: g++ (GCC) 10.0.0 20200110(实验性)[svn-280157:20201220-1704] 我在 Stack Overflow 上发现了一个帖子,有人指向这个版本 (How to compile C++ code using modules-ts and gcc (experimental)?)

我还尝试了 wiki 中的示例(hello.cc 和 main.cc),但这些示例也给出了错误消息:

In module imported at main.cpp:1:1:
hello: error: failed to read compiled module: No such file or directory
hello: note: compiled module file is ‘gcm.cache/hello.gcm’
hello: fatal error: jumping off the crazy train to crashville
compilation terminated.

有没有办法让这项工作,或者我应该从“旧”#include 方法开始,直到有支持模块的 GCC 11 稳定版本?据我了解,如果我构建 GCC 11 的最新快照,大多数其他 C++20 特定代码应该可以工作吗? (或者只是坚持我的发行版提供的默认 (g++ (Debian 10.2.1-1) 10.2.1 20201207) 版本?)

【问题讨论】:

  • 如果你想学习模块,你会被塞满的。如果您是尝试学习一些 C++ 的新手,那么继续学习的实用方法是切换回旧的包含语法 include &lt;iostream&gt; :)
  • 我是一个尝试学习 C++ 的新手,我从 import ;方法被认为是与 #include 方法相比的“更好”解决方案。我不妨开始使用更新/更好的方法来做到这一点。但我想我现在只需要使用#include 方法。感谢您的回复!
  • 我完全同意,但我只看到了使用 MSVC 编译器的模块的工作实现。您可能需要等待一段时间才能在 GCC 或 Clang 中实现它。

标签: c++ gcc module g++ c++20


【解决方案1】:

我想我会回答我自己的问题。

当我按照 GCC wiki (https://gcc.gnu.org/wiki/cxx-modules) 上的说明进行操作时,与 svn 上的版本相比,它是一个更新的版本。

svn 的 gcc 版本是 10,而 github 的版本是 11。

当我为 github (g++ (GCC) 11.0.0 20201217 (experimental) [c++-modules revision 20201220-2203]) 编译版本时,GCC Wiki 提供的示例编译并工作。这些文件是 你好.cpp:

module;
#include <iostream>
#include <string_view>
export module hello;
export void greeter (std::string_view const &name)
{
  std::cout << "Hello " << name << "!\n";
}

和 main.cpp

import hello;
int main (void)
{
  greeter ("world");
  return 0;
}

编译命令为:g++ -fmodules-ts hello.cpp main.cpp

据我了解,源文件的顺序很重要,因此 hello.cpp 需要在 main.cpp 之前编译

因此,目前似乎只有用户制作的模块可以工作,而标准库的模块则不行(因为仍然需要#include)。

[编辑] 似乎模块支持现在与 gcc-11 的主分支合并,因此不再需要通过 git 或 svn 使用开发人员构建(不幸的是,标准库头文件还没有转换为模块,所以目前 import ;不起作用)。

【讨论】:

  • 您可以使用g++ -c -fmodules-ts -x c++-system-header -std=c++20 iostream string vector将std_lib头文件转换为模块
  • 如何分别构建模块和使用模块的代码?
  • @debashish.ghosh - 大概您的意思是“在编写自己的模块时,我如何拥有单独的接口和实现?”。答案很有趣。在接口文件中,您说export module foo;,然后为您希望模块提供给其他人的每个名称都有导出语句。在实现中,您改为使用module foo;。实现文件中不能有任何导出语句。
  • 非常感谢您的回答!它适用于 CMake 3.18.4。如上面的解决方案所述,在您的 ${SOURCES} 变量中列出它们时,确保作为(用户定义的)模块的源是第一个。并且不要忘记将set(CMAKE_CXX_FLAGS "-fmodules-ts") 添加到您的 CMakeList.txt 中;)再次感谢您!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
相关资源
最近更新 更多