Модули являются альтернативой #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 без флагов вообще создает один и тот же объектный файл.
Что я делаю неправильно?
Как вы упомянули, у clang еще нет синтаксиса C ++ для импорта,
поэтому я сомневаюсь, что #include
директивы будут в прямом смысле перезаписывается как импорт при предварительной обработке файла, так что это может быть не лучшим способом проверить, работают ли модули так, как задумано.
Однако, если вы установите -fmodules-cache-path=<path>
в явном виде вы можете наблюдать, как clang заполняет его предварительно скомпилированными файлами модулей (* .pcm) во время сборки — если есть какие-либо задействованные модули.
Вам нужно будет использовать libc ++ (который, похоже, поставляется с module.modulemap начиная с версии 3.7.0), если вы хотите использовать стандартную библиотеку с поддержкой модулей прямо сейчас — хотя, по моему опыту, пока это не совсем работает.
(Компилятор Visual Studio 2015 C ++ также должен получить некоторую поддержку модулей с обновлением 1 в ноябре)
Независимо от stdlib, вы все равно можете использовать модули в своем собственном коде. Документы Clang содержат подробное описание Язык карты модуля, но
Я также создал небольшой пример проекта Вот (используя cmake), который должен генерировать cache
каталог с некоторыми модулями при сборке.
По состоянию на этот коммит, 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
не найден.