Проект GPR, в котором каждый исходный файл является основным файлом?

У меня есть следующая структура проекта, где каждый .adb файл является автономным исполняемым файлом, который не зависит и не будет зависеть ни от чего другого:

project/
├── project.gpr
├── bin/
│   ├── bar
│   ├── baz
│   └── foo
├── obj/
│   └── .o's, .ali's, etcetera
└── src/
    ├── bar.adb
    ├── baz.adb
    └── foo.adb

А это project.gpr:

project Project is
   for Source_Dirs use ("src");
   for Object_Dir use "obj";
   for Exec_Dir use "bin";
   for Main use ("src/foo.adb", "src/bar.adb", "src/baz.adb");
end Project;

В настоящее время gprbuild и gprclean делают именно то, что я хочу, однако количество файлов под src/ может вырасти до сотен.

Есть ли способ сообщить GPRbuild, что каждый файл .adb под src/ должен считаться целью Main без явного перечисления каждого из них?


person Marcel Hernandez    schedule 27.01.2018    source источник
comment
В документации говорится, что вы не должны помещать компонент каталога в имена основных файлов (я знаю, это не ответ, но ..)   -  person Simon Wright    schedule 28.01.2018
comment
Все таки оценил, только начинаю осваивать Аду.   -  person Marcel Hernandez    schedule 28.01.2018
comment
Поскольку вы начинаете с Ады, вы должны помнить, что Ада — это язык программирования, а GNAT — специальный компилятор для этого языка. Детали того, как GNAT выполняет эту компиляцию, включая его механизм проекта, язык файлов проекта, необходимость использования определенных имен файлов, необходимость иметь только одну единицу компиляции для каждого файла и т.п., технически не являются Адой. Вы должны стараться разделять в уме, какие части того, что вы изучаете, относятся к Аде, а какие относятся к GNAT.   -  person Jeffrey R. Carter    schedule 28.01.2018


Ответы (2)


Поскольку вы используете георадар, вы можете рассмотреть возможность использования агрегированных проектов.

Вы определяете 1 GPR для каждого исполняемого файла. Затем вы определяете 1 совокупный георадар, чтобы построить их все.

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

Цитата:

Чаще всего приложение организовано в модули и подмодули, которые очень удобно представлять в виде дерева проекта или графа (корневой проект A с проектами для каждого модуля (скажем, B и C), который, в свою очередь, с проектами для подмодулей.

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

Однако, если вы создаете свой проект с помощью gnatmake или gprbuild, используя синтаксис, аналогичный

    gprbuild -PA.gpr

это приведет к перестроению только основных программ проекта A, а не импортированных проектов B и C. Поэтому вам нужно создать несколько команд gnatmake, по одной на проект, для сборки всех исполняемых файлов. Это немного неудобно, но, что более важно, неэффективно, потому что gnatmake должен выполнять дублирующую работу, чтобы гарантировать актуальность исходных кодов, и не может легко компилировать вещи параллельно при использовании ключа -j.

Также библиотеки всегда пересобираются при сборке проекта.

Таким образом, вы можете определить совокупный проект Agg, который группирует A, B и C. Затем, когда вы строите с помощью

     gprbuild -PAgg.gpr

это построит все сети из A, B и C.

    aggregate project Agg is
       for Project_Files use ("a.gpr", "b.gpr", "c.gpr");
    end Agg;

Конечно, в конечном итоге у вас будут небольшие накладные расходы на создание 1 георадара для каждой магистрали, но кажется довольно логичным четко определить каждый созданный артефакт, особенно если они будут

никогда не зависеть друг от друга

как вы указали в своем вопросе.

Однако кажется, что GPR принимает синтаксис для агрегатов GPR, где учитываются все GPR в данном каталоге. см. здесь и, в частности, здесь

Файлы проекта:

Этот атрибут является обязательным. Он определяет список составляющих файлов .gpr, сгруппированных в совокупности. Список может быть пуст. Файлы проекта могут быть любыми проектами, кроме конфигурационных или абстрактных проектов; они могут быть другими совокупными проектами. При группировке стандартных проектов вы можете иметь как корень замыкания импорта проекта (и вам не нужно указывать все его импортированные проекты), так и любой проект внутри замыкания.

Основная идея состоит в том, чтобы указать все те проекты, в которых есть основные программы, которые вы хотите собрать и скомпоновать, или библиотеки, которые вы хотите создать. Вы можете указать проекты, которые не используют атрибут Main или атрибуты Library_*, и в результате будут созданы все их исходные файлы (а не только те, которые необходимы другим проектам).

[...]

Пути также могут включать шаблоны подстановки * и **. Последнее указывает, что в любом подкаталоге (рекурсивно) будет выполняться поиск соответствующих файлов. Шаблон ** может встречаться только в последней позиции в части каталога (т. е. поддерживается a/**/*.gpr, но не **/a/*.gpr). Запуск шаблона с ** эквивалентен запуску с ./**.

В настоящее время шаблон * разрешен только в части имени файла, а не в части каталога. Это в основном из соображений эффективности, чтобы ограничить количество необходимых системных вызовов.

Вот несколько примеров:

    for Project_Files use ("a.gpr", "subdir/b.gpr");
    --  two specific projects relative to the directory of agg.gpr

    for Project_Files use ("/.gpr");
    --  all projects recursively
person LoneWanderer    schedule 21.03.2019
comment
Я могу неправильно понять это, но разве это не переносит бремя указания каждого основного файла в GPR на указание каждого GPR в совокупном GPR? Или пример просто делает это, и есть альтернативный синтаксис, где вам не нужно вручную указывать каждый GPR в совокупности? - person Jere; 21.03.2019
comment
Ответ отредактирован соответствующим образом: кажется возможным избежать боли при указании каждого файла .gpr. - person LoneWanderer; 21.03.2019

IIRC, отсутствие объявления каких-либо Main эквивалентно запросу GPRBuild скомпилировать все доступные исходные файлы.

person Jacob Sparre Andersen    schedule 28.01.2018
comment
Технически это правильно, однако без предложения Main GPRbuild только компилирует исходные файлы без выполнения шагов привязки и компоновки. Таким образом, окончательные исполняемые файлы не создаются. - person Marcel Hernandez; 28.01.2018
comment
Вы можете попробовать gprbuild -P project src/*.adb - gprbuild рассматривает файлы, указанные в командной строке, как основные программы, если они содержат потенциальные основные программы (подпрограммы без параметров). И (здесь), кажется, не заботится о компоненте каталога. Это оставит вас нуждающимся в Makefile. - person Simon Wright; 28.01.2018