Как использовать модули C ++ в Clang?

Модули являются альтернативой #include. Clang имеет полную реализацию для C ++. Как бы я поступил, если бы сейчас хотел использовать модули, использующие Clang?


С помощью

import std.io;

в исходном файле C ++ пока не работает (не компилируется), поскольку спецификация для модулей (которая включает синтаксис) не является окончательной.


Clang документация утверждает, что при прохождении -fmodules флаг, #include будет переписан для соответствующего импорта. Однако проверка препроцессора предполагает иное (test.cpp содержит только #include <stdio.h> и пустая основная)

$ clang++-3.5 -fmodules -E test.cpp -o test
$ grep " printf " test
extern int printf (const char *__restrict __format, ...);

Кроме того, компиляция этого тестового файла с -fmodules vs без флагов вообще создает один и тот же объектный файл.

Что я делаю неправильно?

27

Решение

Как вы упомянули, у clang еще нет синтаксиса C ++ для импорта,
поэтому я сомневаюсь, что #include директивы будут в прямом смысле перезаписывается как импорт при предварительной обработке файла, так что это может быть не лучшим способом проверить, работают ли модули так, как задумано.

Однако, если вы установите -fmodules-cache-path=<path> в явном виде вы можете наблюдать, как clang заполняет его предварительно скомпилированными файлами модулей (* .pcm) во время сборки — если есть какие-либо задействованные модули.

Вам нужно будет использовать libc ++ (который, похоже, поставляется с module.modulemap начиная с версии 3.7.0), если вы хотите использовать стандартную библиотеку с поддержкой модулей прямо сейчас — хотя, по моему опыту, пока это не совсем работает.
(Компилятор Visual Studio 2015 C ++ также должен получить некоторую поддержку модулей с обновлением 1 в ноябре)

Независимо от stdlib, вы все равно можете использовать модули в своем собственном коде. Документы Clang содержат подробное описание Язык карты модуля, но
Я также создал небольшой пример проекта Вот (используя cmake), который должен генерировать cache каталог с некоторыми модулями при сборке.

12

Другие решения

По состоянию на этот коммит, Clang имеет экспериментальную поддержку Модули TS.

Давайте возьмем те же файлы примеров (с небольшим изменением), что и в VS сообщение в блоге о поддержке экспериментального модуля.

Сначала определите файл интерфейса модуля. По умолчанию Clang распознает файлы с cppm расширение (и некоторые другие) в виде файлов интерфейса модуля C ++.

// file: foo.cppm
export module M;

export int f(int x)
{
return 2 + x;
}
export double g(double y, int z)
{
return y * z;
}

Обратите внимание, что объявление интерфейса модуля должно быть export module M; и не только module M; как в блоге VS.

Затем используйте модуль следующим образом:

// file: bar.cpp
import M;

int main()
{
f(5);
g(0.0, 1);
return 0;
}

Теперь предварительно скомпилируйте модуль foo.cppm с

clang++ -fmodules-ts --precompile foo.cppm -o M.pcm

или, если расширение интерфейса модуля отличается от cppm (скажем ixx, как и в случае с VS), вы можете использовать:

clang++ -fmodules-ts --precompile -x c++-module foo.ixx -o M.pcm

Затем соберите программу с

clang++ -fmodules-ts -c M.pcm -o M.o
clang++ -fmodules-ts -fprebuilt-module-path=. M.o bar.cpp

или, если имя файла PCM не совпадает с именем модуля, вам придется использовать:

clang++ -fmodules-ts -fmodule-file=M.pcm bar.cpp

Я проверил эти команды в Windows, используя сборка r303050 (15 мая 2017 г.)

Примечание: при использовании -fprebuilt-module-path=. вариант, я получаю предупреждение:

clang ++. exe: warning: аргумент не используется во время компиляции: ‘-fprebuilt-module-path =.’ [-Wunused-командная строка аргументы]

который представляется неправильным, потому что без этой опции, модуль M не найден.

18

По вопросам рекламы [email protected]