LINUX.ORG.RU

История изменений

Исправление dimgel, (текущая версия) :

В общем, с учётом этого видео, почти получилось. Почти – потому что:

  1. У меня мультиплатформные цели, и правило
%.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. Тогда и правило это дурацкое вообще не потребуется.

  1. Лень возиться с .SECONDEXPANSION (см. ниже зачем), может попозже добью.

В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):

  1. Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка export module a.b.c;) должен лежать в файле src/a/b/c.cpp. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался.

  2. Рисуем баш-скриптик, который делает 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 ;
  1. Вызывать этот скриптик можно перед 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 пришлось бы применять к другому правилу.

  1. В команды CC добавляем опции -std=c++20 -fmodules-ts -fmodule-mapper=target/module-map

  2. Остаётся правило, на которое я жаловался в начале камента: зависимость %.c++m от %.gcm; здесь нужно в prerequisite заменять точки на слеши, e.g.:

a.b.c.c++m : a/b/c.gcm ;

Полагаю, как раз для этого придётся юзать .SECONDEXPANSION чтобы выполнить два $(subst ): сначала . —> /, затем /c++m на .gcm. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.

Исправление dimgel, :

В общем, с учётом этого видео, почти получилось. Почти – потому что:

  1. У меня мультиплатформные цели, и правило
%.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.

  1. Лень возиться с .SECONDEXPANSION (см. ниже зачем), может попозже добью.

В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):

  1. Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка export module a.b.c;) должен лежать в файле src/a/b/c.cpp. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался.

  2. Рисуем баш-скриптик, который делает 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 ;
  1. Вызывать этот скриптик можно перед 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 пришлось бы применять к другому правилу.

  1. В команды CC добавляем опции -std=c++20 -fmodules-ts -fmodule-mapper=target/module-map

  2. Остаётся правило, на которое я жаловался в начале камента: зависимость %.c++m от %.gcm; здесь нужно в prerequisite заменять точки на слеши, e.g.:

a.b.c.c++m : a/b/c.gcm ;

Полагаю, как раз для этого придётся юзать .SECONDEXPANSION чтобы выполнить два $(subst ): сначала . —> /, затем /c++m на .gcm. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.

Исправление dimgel, :

В общем, с учётом этого видео, почти получилось. Почти – потому что:

  1. У меня мультиплатформные цели, и правило
%.c++m : $(CXX_MODULE_PREFIX)%.gcm ;

из статьи хрен напишешь, потому что в зависимости от текущей цели этот %.c++m должен зависеть либо от target/windows/%.gcm, либо от target/linux/%.gcm. От обоих зависеть нельзя, потому что некоторые модули платформно-специфичные. Написал Nathan Sidwell с предложением как лечить: писать в .d-файлы не .c++m, а .gcm после применения маппинга.

  1. Лень возиться с .SECONDEXPANSION (см. ниже зачем), может попозже добью.

В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):

  1. Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка export module a.b.c;) должен лежать в файле src/a/b/c.cpp. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался.

  2. Рисуем баш-скриптик, который делает 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 ;
  1. Вызывать этот скриптик можно перед 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 пришлось бы применять к другому правилу.

  1. В команды CC добавляем опции -std=c++20 -fmodules-ts -fmodule-mapper=target/module-map

  2. Остаётся правило, на которое я жаловался в начале камента: зависимость %.c++m от %.gcm; здесь нужно в prerequisite заменять точки на слеши, e.g.:

a.b.c.c++m : a/b/c.gcm ;

Полагаю, как раз для этого придётся юзать .SECONDEXPANSION чтобы выполнить два $(subst ): сначала . —> /, затем /c++m на .gcm. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.

Исправление dimgel, :

В общем, с учётом этого видео, почти получилось. Почти – потому что:

  1. У меня мультиплатформные цели, и правило
%.c++m : $(CXX_MODULE_PREFIX)%.gcm ;

из статьи хрен напишешь, потому что в зависимости от текущей цели этот %.c++m должен зависеть либо от target/windows/%.gcm, либо от target/linux/%.gcm. От обоих зависеть нельзя, потому что некоторые модули платформно-специфичные. Написал Nathan Sidwell с предложением как лечить: писать в .d-файлы не .c++m, а .gcm после применения маппинга.

  1. Лень возиться с .SECONDEXPANSION (см. ниже зачем), может попозже добью.

В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):

  1. Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка export module a.b.c;) должен лежать в файле src/a/b/c.cpp. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался.

  2. Рисуем баш-скриптик, который делает 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 ;
  1. Вызывать этот скриптик можно перед 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 пришлось бы применять к другому правило.

  1. В команды CC добавляем опции -std=c++20 -fmodules-ts -fmodule-mapper=target/module-map

  2. Остаётся правило, на которое я жаловался в начале камента: зависимость %.c++m от %.gcm; здесь нужно в prerequisite заменять точки на слеши, e.g.:

a.b.c.c++m : a/b/c.gcm ;

Полагаю, как раз для этого придётся юзать .SECONDEXPANSION чтобы выполнить два $(subst ): сначала . —> /, затем /c++m на .gcm. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.

Исправление dimgel, :

В общем, с учётом этого видео, почти получилось. Почти – потому что:

  1. У меня мультиплатформные цели, и правило
%.c++m : $(CXX_MODULE_PREFIX)%.gcm ;

из статьи хрен напишешь, потому что в зависимости от текущей цели этот %.c++m должен зависеть либо от target/windows/%.gcm, либо от target/linux/%.gcm. От обоих зависеть нельзя, потому что некоторые модули платформно-специфичные. Написал Nathan Sidwell с предложением как лечить: писать в .d-файлы не .c++m, а .gcm после применения маппинга.

  1. Лень возиться с .SECONDEXPANSION (см. ниже зачем), может попозже добью.

В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):

  1. Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка export module a.b.c;) должен лежать в файле src/a/b/c.cpp. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался.

  2. Рисуем баш-скриптик, который делает 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 ;
  1. Вызывать этот скриптик можно перед 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 пришлось бы применять к другому правило.

  1. В команды CC добавляем опции -std=c++20 -fmodules-ts -fmodule-mapper=target/module-map

  2. Остаётся правило, на которое я жаловался в начале камента: зависимость %.c++m от %.gcm; здесь нужно в prerequisite заменять точки на слеши, e.g.:

a.b.c.c++m : a/b/c.gcm ;

Полагаю, как раз для этого придётся юзать .SECONDEXPANSION чтобы выполнить два $(subst ): сначала . —> /, затем /c++m на .gcm. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.

Исходная версия dimgel, :

В общем, с учётом этого видео, почти получилось. Почти – потому что:

  1. У меня мультиплатформные цели, и правило
%.c++m : $(CXX_MODULE_PREFIX)%.gcm ;

из статьи хрен напишешь, потому что в зависимости от текущей цели этот %.c++m должен зависеть либо от target/windows/%.gcm, либо от target/linux/%.gcm. От обоих зависеть нельзя, потому что некоторые модули платформно-специфичные. Написал Nathan Sidwell с предложением как лечить: писать в .d-файлы не .c++m, а .gcm после применения маппинга.

  1. Лень возиться с .SECONDEXPANSION (см. ниже зачем), может попозже добью.

В остальном, алгоритм наклёвывается такой (если без мультиплатформенности):

  1. Приводим пути файлов в соответствии с именами модулей: модуль a.b.c (т.е. исходник, в котором есть строка export module a.b.c;) должен лежать в файле src/a/b/c.cpp. С интерфейсами, разбитыми по нескольким сорцам, пока что не заморачивался.

  2. Рисуем баш-скриптик, который делает 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 ;
  1. Вызывать этот скриптик можно перед 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 пришлось бы применять к другому правило.

  1. В команды CC добавляем опции -std=c++20 -fmodules-ts -fmodule-mapper=target/module-map

  2. Остаётся правило, на которое я жаловался в начале камента: зависимость %.c++m от %.gcm; здесь нужно в prerequisite заменять точки на слеши, e.g.:

a.b.c.c++m : a/b/c.gcm ;

Полагаю, как раз для этого придётся юзать .SECONDEXPANSION чтобы выполнить два $(subst ): сначала . —> /, затем /c++m на .gcm. Ежели кто подскажет-нарисует (я с ним досконально не разобрался), буду благодарен.