История изменений
Исправление dimgel, (текущая версия) :
В общем, с учётом этого видео, почти получилось. Почти – потому что:
- У меня мультиплатформные цели, и правило
%.c++m : $(CXX_MODULE_PREFIX)%.gcm ;
из статьи хрен напишешь, потому что в зависимости от текущей цели этот %.c++m
должен зависеть либо от target/windows/%.gcm
, либо от target/linux/%.gcm
. От обоих зависеть нельзя, потому что некоторые модули платформно-специфичные. Написал Nathan Sidwell с предложением как лечить: писать в .d-файлы не .c++m
, а .gcm
после применения маппинга.
Может быть я забабахаю это преобразование сам: вывод gcc буду писать в .d0, а потом %.d : %.d0
с преобразованием .c++m
в .gcm
. Тогда и правило это дурацкое вообще не потребуется.
- Лень возиться с
.SECONDEXPANSION
(см. ниже зачем), может попозже добью.
В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):
-
Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка
export module a.b.c;
) должен лежать в файлеsrc/a/b/c.cpp
. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался. -
Рисуем баш-скриптик, который делает
cd src; grep -RlP '^export\s+module\s+\w'
и генерирует target/module-map вида:
$root target
a.b.c a/b/c.gcm
(В случае мультиплатформенности, скриптику передаётся параметр windows|linux
, он создаёт соответственно target/$1/module-map
с первой строчкой \$root target/$1
.)
Таким образом, .gcm-файлы ложатся рядышком с .d и .o. И тогда становится тривиальным другое правило из статьи:
%.gcm: | %.o ;
- Вызывать этот скриптик можно перед make (у меня есть ./build.sh, вызывающий make -j14 «$@»), а можно и правила подкрутить (несколько по беспределу, но у меня проект маленький):
/target/module-map: $(ALL_CPPs)
@create-module-map.sh
target/%.o: src/%.cpp target/%.d target/module-map
...
Наверное можно было бы и без баш-скриптика, а тупо юзать маппер по умолчанию, тогда модули ложились бы в gcm.cache/a.b.c.gcm
, и .SECONDEXPANSION
пришлось бы применять к другому правилу.
-
В команды CC добавляем опции
-std=c++20 -fmodules-ts -fmodule-mapper=target/module-map
-
Остаётся правило, на которое я жаловался в начале камента: зависимость
%.c++m
от%.gcm
; здесь нужно в prerequisite заменять точки на слеши, e.g.:
a.b.c.c++m : a/b/c.gcm ;
Полагаю, как раз для этого придётся юзать .SECONDEXPANSION
чтобы выполнить два $(subst )
: сначала .
—> /
, затем /c++m
на .gcm
. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.
Исправление dimgel, :
В общем, с учётом этого видео, почти получилось. Почти – потому что:
- У меня мультиплатформные цели, и правило
%.c++m : $(CXX_MODULE_PREFIX)%.gcm ;
из статьи хрен напишешь, потому что в зависимости от текущей цели этот %.c++m
должен зависеть либо от target/windows/%.gcm
, либо от target/linux/%.gcm
. От обоих зависеть нельзя, потому что некоторые модули платформно-специфичные. Написал Nathan Sidwell с предложением как лечить: писать в .d-файлы не .c++m
, а .gcm
после применения маппинга.
Может быть я забабахаю это преобразование сам: вывод gcc буду писать в .d0, а потом %.d : %.d0
с преобразованием .c++m
в .gcm
.
- Лень возиться с
.SECONDEXPANSION
(см. ниже зачем), может попозже добью.
В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):
-
Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка
export module a.b.c;
) должен лежать в файлеsrc/a/b/c.cpp
. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался. -
Рисуем баш-скриптик, который делает
cd src; grep -RlP '^export\s+module\s+\w'
и генерирует target/module-map вида:
$root target
a.b.c a/b/c.gcm
(В случае мультиплатформенности, скриптику передаётся параметр windows|linux
, он создаёт соответственно target/$1/module-map
с первой строчкой \$root target/$1
.)
Таким образом, .gcm-файлы ложатся рядышком с .d и .o. И тогда становится тривиальным другое правило из статьи:
%.gcm: | %.o ;
- Вызывать этот скриптик можно перед make (у меня есть ./build.sh, вызывающий make -j14 «$@»), а можно и правила подкрутить (несколько по беспределу, но у меня проект маленький):
/target/module-map: $(ALL_CPPs)
@create-module-map.sh
target/%.o: src/%.cpp target/%.d target/module-map
...
Наверное можно было бы и без баш-скриптика, а тупо юзать маппер по умолчанию, тогда модули ложились бы в gcm.cache/a.b.c.gcm
, и .SECONDEXPANSION
пришлось бы применять к другому правилу.
-
В команды CC добавляем опции
-std=c++20 -fmodules-ts -fmodule-mapper=target/module-map
-
Остаётся правило, на которое я жаловался в начале камента: зависимость
%.c++m
от%.gcm
; здесь нужно в prerequisite заменять точки на слеши, e.g.:
a.b.c.c++m : a/b/c.gcm ;
Полагаю, как раз для этого придётся юзать .SECONDEXPANSION
чтобы выполнить два $(subst )
: сначала .
—> /
, затем /c++m
на .gcm
. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.
Исправление dimgel, :
В общем, с учётом этого видео, почти получилось. Почти – потому что:
- У меня мультиплатформные цели, и правило
%.c++m : $(CXX_MODULE_PREFIX)%.gcm ;
из статьи хрен напишешь, потому что в зависимости от текущей цели этот %.c++m
должен зависеть либо от target/windows/%.gcm
, либо от target/linux/%.gcm
. От обоих зависеть нельзя, потому что некоторые модули платформно-специфичные. Написал Nathan Sidwell с предложением как лечить: писать в .d-файлы не .c++m
, а .gcm
после применения маппинга.
- Лень возиться с
.SECONDEXPANSION
(см. ниже зачем), может попозже добью.
В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):
-
Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка
export module a.b.c;
) должен лежать в файлеsrc/a/b/c.cpp
. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался. -
Рисуем баш-скриптик, который делает
cd src; grep -RlP '^export\s+module\s+\w'
и генерирует target/module-map вида:
$root target
a.b.c a/b/c.gcm
(В случае мультиплатформенности, скриптику передаётся параметр windows|linux
, он создаёт соответственно target/$1/module-map
с первой строчкой \$root target/$1
.)
Таким образом, .gcm-файлы ложатся рядышком с .d и .o. И тогда становится тривиальным другое правило из статьи:
%.gcm: | %.o ;
- Вызывать этот скриптик можно перед make (у меня есть ./build.sh, вызывающий make -j14 «$@»), а можно и правила подкрутить (несколько по беспределу, но у меня проект маленький):
/target/module-map: $(ALL_CPPs)
@create-module-map.sh
target/%.o: src/%.cpp target/%.d target/module-map
...
Наверное можно было бы и без баш-скриптика, а тупо юзать маппер по умолчанию, тогда модули ложились бы в gcm.cache/a.b.c.gcm
, и .SECONDEXPANSION
пришлось бы применять к другому правилу.
-
В команды CC добавляем опции
-std=c++20 -fmodules-ts -fmodule-mapper=target/module-map
-
Остаётся правило, на которое я жаловался в начале камента: зависимость
%.c++m
от%.gcm
; здесь нужно в prerequisite заменять точки на слеши, e.g.:
a.b.c.c++m : a/b/c.gcm ;
Полагаю, как раз для этого придётся юзать .SECONDEXPANSION
чтобы выполнить два $(subst )
: сначала .
—> /
, затем /c++m
на .gcm
. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.
Исправление dimgel, :
В общем, с учётом этого видео, почти получилось. Почти – потому что:
- У меня мультиплатформные цели, и правило
%.c++m : $(CXX_MODULE_PREFIX)%.gcm ;
из статьи хрен напишешь, потому что в зависимости от текущей цели этот %.c++m
должен зависеть либо от target/windows/%.gcm
, либо от target/linux/%.gcm
. От обоих зависеть нельзя, потому что некоторые модули платформно-специфичные. Написал Nathan Sidwell с предложением как лечить: писать в .d-файлы не .c++m
, а .gcm
после применения маппинга.
- Лень возиться с
.SECONDEXPANSION
(см. ниже зачем), может попозже добью.
В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):
-
Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка
export module a.b.c;
) должен лежать в файлеsrc/a/b/c.cpp
. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался. -
Рисуем баш-скриптик, который делает
cd src; grep -RlP '^export\s+module\s+\w'
и генерирует target/module-map вида:
$root target
a.b.c a/b/c.gcm
(В случае мультиплатформенности, скриптику передаётся параметр windows|linux
, он создаёт соответственно target/$1/module-map
с первой строчкой \$root target/$1
.)
Таким образом, .gcm-файлы ложатся рядышком с .d и .o. И тогда становится тривиальным другое правило из статьи:
%.gcm: | %.o ;
- Вызывать этот скриптик можно перед make (у меня есть ./build.sh, вызывающий make -j14 «$@»), а можно и правила подкрутить (несколько по беспределу, но у меня проект маленький):
/target/module-map: $(ALL_CPPs)
@create-module-map.sh
target/%.o: src/%.cpp target/%.d target/module-map
...
Наверное можно было бы и без баш-скриптика, а тупо юзать маппер по умолчанию, тогда модули ложились бы в gcm.cache/a.b.c.gcm
, и .SECONDEXPANSION
пришлось бы применять к другому правило.
-
В команды CC добавляем опции
-std=c++20 -fmodules-ts -fmodule-mapper=target/module-map
-
Остаётся правило, на которое я жаловался в начале камента: зависимость
%.c++m
от%.gcm
; здесь нужно в prerequisite заменять точки на слеши, e.g.:
a.b.c.c++m : a/b/c.gcm ;
Полагаю, как раз для этого придётся юзать .SECONDEXPANSION
чтобы выполнить два $(subst )
: сначала .
—> /
, затем /c++m
на .gcm
. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.
Исправление dimgel, :
В общем, с учётом этого видео, почти получилось. Почти – потому что:
- У меня мультиплатформные цели, и правило
%.c++m : $(CXX_MODULE_PREFIX)%.gcm ;
из статьи хрен напишешь, потому что в зависимости от текущей цели этот %.c++m
должен зависеть либо от target/windows/%.gcm
, либо от target/linux/%.gcm
. От обоих зависеть нельзя, потому что некоторые модули платформно-специфичные. Написал Nathan Sidwell с предложением как лечить: писать в .d-файлы не .c++m
, а .gcm
после применения маппинга.
- Лень возиться с
.SECONDEXPANSION
(см. ниже зачем), может попозже добью.
В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):
-
Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка
export module a.b.c;
) должен лежать в файлеsrc/a/b/c.cpp
. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался. -
Рисуем баш-скриптик, который делает
cd src; grep -RlP '^export\s+module\s+\w'
и генерирует target/module-map вида:
$root target
a.b.c a/b/c.gcm
(В случае мультиплатформенности, скриптику передаётся параметр windows|linux
, он создаёт соответственно target/$1/module-map
с первой строчкой \$root target/$1
.)
Таким образом, .gcm-файлы ложатся рядышком с .d и .o. И тогда становится тривиальным другое правило из статьи:
%.gcm: | %.o ;
- Вызывать этот скриптик можно перед make (у меня есть ./build.sh, вызывающий make -j14 «$@»), а можно и правила подкрутить (несколько по беспределу, но у меня проект маленький):
/target/module-map: $(ALL_CPPs)
@create-module-map.sh
target/%.o: src/%.cpp target/%.d target/module-map
...
Наверное можно было бы и без баш-скриптика, а тупо юзать маппер по умолчанию, тогда модули ложились бы в gcm.cache/a.b.c.gcm, и .SECONDEXPANSION
пришлось бы применять к другому правило.
-
В команды CC добавляем опции
-std=c++20 -fmodules-ts -fmodule-mapper=target/module-map
-
Остаётся правило, на которое я жаловался в начале камента: зависимость
%.c++m
от%.gcm
; здесь нужно в prerequisite заменять точки на слеши, e.g.:
a.b.c.c++m : a/b/c.gcm ;
Полагаю, как раз для этого придётся юзать .SECONDEXPANSION
чтобы выполнить два $(subst )
: сначала .
—> /
, затем /c++m
на .gcm
. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.
Исходная версия dimgel, :
В общем, с учётом этого видео, почти получилось. Почти – потому что:
- У меня мультиплатформные цели, и правило
%.c++m : $(CXX_MODULE_PREFIX)%.gcm ;
из статьи хрен напишешь, потому что в зависимости от текущей цели этот %.c++m
должен зависеть либо от target/windows/%.gcm
, либо от target/linux/%.gcm
. От обоих зависеть нельзя, потому что некоторые модули платформно-специфичные. Написал Nathan Sidwell с предложением как лечить: писать в .d-файлы не .c++m
, а .gcm
после применения маппинга.
- Лень возиться с
.SECONDEXPANSION
(см. ниже зачем), может попозже добью.
В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):
-
Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка
export module a.b.c;
) должен лежать в файлеsrc/a/b/c.cpp
. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался. -
Рисуем баш-скриптик, который делает
cd src; grep -RlP '^export\s+module\s+\w'
и генерирует target/module-map вида:
$root target
a.b.c a/b/c.gcm
(В случае мультиплатформенности, скриптику передаётся параметр windows|linux
, он создаёт соответственно target/$1/module-map
с первой строчкой \$root target/$1
.)
Таким образом, .gcm-файлы ложатся рядышком с .d и .o. И тогда становится тривиальным другое правило из статьи:
%.gcm: | %.o ;
- Вызывать этот скриптик можно перед make (у меня есть ./build.sh, вызывающий make -j14 «$@»), а можно и правила подкрутить (несколько по беспределу, но у меня проект маленький):
/target/module-map: $(ALL_CPPs)
@create-module-map.sh
target/%.o: src/%.cpp target/%.d target/module-map
...
Наверное можно было бы и без баш-скриптика, а тупо юзать маппер по умолчанию, тогда модули ложились бы в gcm.cache/a.b.c.gcm, и .SECONDEXPANSION
пришлось бы применять к другому правило.
-
В команды CC добавляем опции
-std=c++20 -fmodules-ts -fmodule-mapper=target/module-map
-
Остаётся правило, на которое я жаловался в начале камента: зависимость
%.c++m
от%.gcm
; здесь нужно в prerequisite заменять точки на слеши, e.g.:
a.b.c.c++m : a/b/c.gcm ;
Полагаю, как раз для этого придётся юзать .SECONDEXPANSION
чтобы выполнить два $(subst ): сначала .
—> /
, затем /c++m
на .gcm
. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.