Подтвердить что ты не робот

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

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


Использование

import std.io;

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


Документация Clang утверждает, что при передаче флага -fmodules #includes будут переписаны на соответствующий импорт. Однако проверка препроцессора предполагает иное (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 no flags вообще создает один и тот же файл объекта.

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

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

// 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 -fprebuilt-module-path=. bar.cpp

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

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

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

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

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

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