Ошибка: не удалось прочитать скомпилированный модуль: нет такого файла или каталога

Я только что купил книгу 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, где кто-то указывает на эту версию (Как скомпилировать код C++ с использованием modules-ts и gcc (экспериментально)?)

Я также попробовал примеры из вики (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 include <iostream> :)

Mansoor 20.12.2020 22:21

Я новичок, пытающийся изучить С++, я понял, что с момента импорта <iostream>; метод считается «лучшим» решением по сравнению с методом #include <iostream>. Я мог бы также начать использовать более новый/лучший способ сделать это. Но я думаю, что пока мне придется использовать метод #include. Спасибо за ответ!

user14598891 21.12.2020 09:35

Я полностью согласен, но я видел только рабочие реализации модулей с компилятором MSVC. Возможно, вам придется подождать некоторое время, прежде чем он будет реализован в GCC или Clang.

Mansoor 21.12.2020 09:38
Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
8
3
3 367
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Думаю, я отвечу на свой вопрос.

Когда я следую инструкциям на вики GCC (https://gcc.gnu.org/wiki/cxx-modules), это более новая версия по сравнению с той, что находится на svn.

У svn есть версия 10 gcc, а у github — версия 11.

Когда я компилирую версию для github (g++ (GCC) 11.0.0 20201217 (экспериментальная) [версия c++-модулей 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 ; не работает).

Вы можете преобразовать заголовки std_lib в модули с помощью g++ -c -fmodules-ts -x c++-system-header -std=c++20 iostream string vector

hr0m 14.11.2021 11:44

Как построить модуль и код, который использует модуль отдельно?

debashish.ghosh 03.01.2022 13:43

@debashish.ghosh - Предположительно, вы имеете в виду «Как мне получить отдельный интерфейс и реализацию при написании собственного модуля?». Ответ интересный. В файле интерфейса вы говорите export module foo;, а затем имеете операторы экспорта для каждого имени, которое вы хотите, чтобы модуль предоставил другим. В реализации вместо этого вы говорите module foo;. В файле реализации не должно быть операторов экспорта.

Omnifarious 03.01.2022 17:16

Большое спасибо за этот ответ! Он работает на CMake 3.18.4. Как указано в приведенном выше решении, убедитесь, что источники, которые являются (определяемыми пользователем) модулями, являются ПЕРВЫМИ при перечислении их в вашей переменной ${SOURCES}. И не забудьте добавить set(CMAKE_CXX_FLAGS "-fmodules-ts") в свой CMakeList.txt ;) Еще раз спасибо!

Lorenzo_g 12.02.2022 23:47

Я собрал // Ex1_01.cpp исходный файл из вопроса двумя командами:

$ g++ -std=c++20 -fmodules-ts -xc++-system-header iostream
$ g++ -std=c++20 -fmodules-ts -o Ex1_01 Ex1_01.cpp

После запуска Ex1_01 у меня есть:

The answer to life, the universe, and everything is 42

Для следующего кода в Linux Ubuntu 20.04

import <iostream>;
import <limits>;

int main()
{
    int min{ std::numeric_limits<int>::max()};
    int max{ std::numeric_limits<int>::min() };
    bool any { false };
    int x;

    while(std::cin >> x)
    {
        any = true;
        if (x < min)
            min = x;
        if (x> max)
            max = x;
    }

    if (any)
        std::cout<<"min = "<<min<<"\nmax = "<<max<<'\n';
}

Я должен был установить g++-11 тогда

g++-11 -std=c++20 -fmodules-ts -xc++-system-header iostream
g++-11 -std=c++20 -fmodules-ts -xc++-system-header limits
g++-11 -std=c++20 -fmodules-ts list0201.cpp -o list0201
$ ./list0201
10
20
-100 
ctrl+D
min = -100
max = 20

Другие вопросы по теме