LINUX.ORG.RU

C++ modules и системы сборки

 , ,


1

4

Кто как собирает проекты с использованием C++ modules?

Компиляторы уже давно умеют их, например, в clang даже объявили deprecated опцию -fmodules-ts и поддержка модулей автоматически включается при активации стандарта C++20.

Однако, собирать руками проекты удовольствия мало. Хочется использовать какую-нибудь систему сборки. И вот тут возникает проблема. Самая популярная система сборки в мире C/C++ - CMake - поддерживает модули только для MSVC, что как бы не очень интересно (так как ограничивает одной платформой, к тому же clang/gcc по моим тестам обычно генерируют более оптимальный код, чем MSVC, даже под Windows). Какие есть альтернативы? Можно ли приобщиться к модулям не путём написания вручную Makefile или Bash-скриптов?

★★★★★

Последнее исправление: hobbit (всего исправлений: 3)
Ответ на: комментарий от hobbit

Так модули-то – это не заголовочные файлы, там же еще и реализация. А иметь один файл со 100500 строк реализации в C++ так себе идея, т.к. практически любой компилятор будет падать по internal compiler error с вероятностью в 99.9(9)%.

PS. Я сам не в восторге от того, что в C++ с модулями придумали. Да и более того, имхо, C++ с модулями расколет C++ на много лет так же, как это было с Python2/Python3.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

любой компилятор будет падать

А почему? Вроде ж не так давно вообще была какая-то движуха, чтобы сливать весь проект в один файл для увеличения скорости сборки.

GAMer ★★★★★
()
Ответ на: комментарий от GAMer

А почему?

А это у разработчиков компиляторов нужно спросить, почему у них время от времени на сложном коде internal compiler error случаются.

eao197 ★★★★★
()
Ответ на: комментарий от GAMer

А почему? Вроде ж не так давно вообще была какая-то движуха, чтобы сливать весь проект в один файл для увеличения скорости сборки.

Там определенные пределы есть для слияния.

x86 версии компилятора имеют лимит памяти в 3 gb.

Например, вот этот тест https://github.com/Microsoft/STL/blob/main/tests/std/tests/P0088R3_variant/test.cpp требует 3,033,104,384 байт для компиляции x86 кода с помощью cl.exe

fsb4000 ★★★★★
()
Ответ на: комментарий от eao197

Да и более того, имхо, C++ с модулями расколет C++ на много лет так же, как это было с Python2/Python3.

Я помню, Дедфуд начал лямбды в личкрафт тащить, как только они в gcc появились, я их впервые увидел, когда на моём дебиане личкрафт отказался собираться, что это, думаю, за хрень в квадратных скобках. Но то лямбды, а тут изменение куда более масштабное…

hobbit ★★★★★
()
Ответ на: комментарий от eao197

модули-то – это не заголовочные файлы, там же еще и реализация. А иметь один файл со 100500 строк реализации в C++ так себе идея

Вот тут вообще не понял. При сборке модуля создаётся объектный файл. Чем это будет отличаться от сборки посто файла в те же 100500 строк? Сомнительна логичность иметь всё внутри одного файла. Такие крупные библиотеки обычно имеют кучу внутренних функций, которые наружу не высовываются и внутри этого же модуля содержаться не обязаны.

grem ★★★★★
()
Последнее исправление: grem (всего исправлений: 1)
Ответ на: комментарий от grem

При сборке модуля создаётся объектный файл.

Насколько я могу судить по документации clang-а, там все несколько сложнее:

# Precompiling the module
$ clang++ -std=c++20 interface_part.cppm --precompile -o M-interface_part.pcm
$ clang++ -std=c++20 impl_part.cppm --precompile -fprebuilt-module-path=. -o M-impl_part.pcm
$ clang++ -std=c++20 M.cppm --precompile -fprebuilt-module-path=. -o M.pcm
$ clang++ -std=c++20 Impl.cpp -fmodule-file=M.pcm -c -o Impl.o

# Compiling the user
$ clang++ -std=c++20 User.cpp -fprebuilt-module-path=. -c -o User.o

# Compiling the module and linking it together
$ clang++ -std=c++20 M-interface_part.pcm -c -o M-interface_part.o
$ clang++ -std=c++20 M-impl_part.pcm -c -o M-impl_part.o
$ clang++ -std=c++20 M.pcm -c -o M.o
$ clang++ User.o M-interface_part.o  M-impl_part.o M.o Impl.o -o a.out

Чем это будет отличаться от сборки посто файла в те же 100500 строк?

Тем, что если модуль состоит из 500 файлов, то эти 500 файлов будут компилироваться в объектники отдельно, компилятору не нужно собирать из них один большой файл на 100500 строк.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Модуль не должен состоять из 500 файлов, а только из одного. Другие модули могут подключаться внутрь модулей для выполнения промежуточных задач и собираются отдельно, перед сборкой модуля или файла, который от них зависит. Никто из кучи модулей один объектный файл ни в одном языке не собирает.

Для примера, в фортране: из файла исходного кода модуля собирается объектный файл .o, который потом компонуется в файл mod. Эти файлы дальше используются при дальнейшей компиляции зависящих от них файлов. То есть они ищутся как хдеры, потому что в них содержится в том числе и информация об интерфейсах.

То есть если у нас есть основной файл и два файла модуля, то в результате сборки появятся 6 дополнительных файла: 3 объектных файла, 2 файла .mod, исполняемый файл. Разве в C++ не так? Вроде так же.

grem ★★★★★
()
Ответ на: комментарий от grem

Модуль не должен состоять из 500 файлов, а только из одного.

Почему?

Никто из кучи модулей один объектный файл ни в одном языке не собирает.

Мы говорим про C++, здесь многое не так, как в других языках.

Для примера, в фортране

Примеры из фортрана в разговоре про модули в C++ не нужны.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Да я уж понял, что у C++ свой путь. Зачем смотреть на фортран, паскаль и кучу других языков, где модули давно успешно используется, если можно сделать свою неудобную всем реализацию и страдать, размышляя о том, что непонятно как это теперь использовать.

grem ★★★★★
()
Последнее исправление: grem (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.