Ninja: Относительные пути субниндзя не разрешаются

Созданный на 21 июн. 2015  ·  8Комментарии  ·  Источник: ninja-build/ninja

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

При включении субниндзя я получаю

ниндзя: ошибка: 'mod.c', необходимая для 'mod.o', отсутствует и неизвестное правило для ее создания

хотя запуск ниндзя непосредственно в этом каталоге работает нормально. Подозревая, что виноваты относительные пути, я скопировал структуру проекта в новый каталог, добавил перед каждым вводом/выводом абсолютный путь и запустил ниндзя из родительского каталога (содержащего build.ninja , который subninja 'd модуль). Он построен просто отлично.

Означает ли это, что мы должны генерировать наши конфигурации ниндзя с абсолютными путями? Это имеет много проблем, а также тот факт, что не каждый генератор, который я видел, делает это. Кроме того, в документации нет различий, и в остальном Ninja работает нормально.

Я хочу ошибиться на стороне _это ошибка_, но я чувствую, что PR, который выполняет канонизацию пути во время выполнения, может привести к снижению производительности (хотя я машу руками здесь без каких-либо тестов, чтобы подтвердить это подозрение).

Самый полезный комментарий

Я не уверен, что понимаю. Субниндзя, в случае использования, который я описал, в частности, обычно не знают о структуре родительского ниндзя (по крайней мере, не должны знать). Я уверен, что кто-то там мог бы найти случай, когда они это делают.

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

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

Все 8 Комментарий

Все пути относятся к каталогу сборки, а не к файлу, содержащему строку subninja.

Хотя в этом нет смысла. Это означает, что генераторы должны будут _all_ реализовать какой-либо способ добавления префикса к файлам, что означает изменение запускаемых команд рабочего каталога (что может изменить исходное намерение конфигурации сборки в зависимости от того, как запускаются генератор/команды).

Каковы же тогда варианты использования для subninja и include ?

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

Функциональность include останется неизменной и будет действовать точно так же, как субниндзя, за исключением того, что имена правил фактов теперь будут находиться в объединенном пространстве имен (согласно #921). В настоящее время subninja и include достигают практически одного и того же, кроме определения области видимости переменных и имен правил...

Идея состоит в том, что генератор генерирует все файлы .ninja, поэтому они могут прописывать пути относительно каталога сборки. Это интересная идея объединить файлы ниндзя, сгенерированные разными генераторами (похоже, это то, что вы хотите сделать?), но на данный момент это не поддерживается.

Правильно, разница между subninja и include заключается в том, что первый добавляет область действия, а второй — нет. Вариант использования для этого заключается в том, что ниндзя верхнего уровня может определять общие правила сборки, такие как cc, которые ссылаются на переменные, такие как cflags , и каждый субниндзя может установить cflags на то, что подходит для этой цели, и там там могут быть разовые действия. Чтобы увидеть пример, вы можете запустить python misc/write_fake_manifests.py /tmp/foo`, чтобы записать набор файлов .ninja в /tmp/foo, которые используют этот шаблон.

Это имеет смысл, хотя я все еще не вижу особой выгоды (кроме области действия).

Интересная идея объединить файлы ниндзя, сгенерированные разными генераторами (похоже, это то, что вы хотите сделать?)

Точно. Возможность включить сам Ninja в качестве подмодуля для моего генератора, а затем другой проект CMake (который настроен на вывод файлов сборки Ninja), а затем создать файлы конфигурации Ninja для обоих и включить их как subninja в файл build.ninja проекта _my_, чтобы иметь возможность создавать их так, как если бы они были сами по себе, но при этом разрешить моему проекту использовать их выходные данные (и, следовательно, их графики зависимостей), чтобы построить весь проект сразу .

Если это имеет смысл. Непосредственный вариант использования, который я вижу, в частности, с моим генератором, заключается в том, что он заимствует несколько концепций у Tup (которые IIRC повлияли на некоторые дизайнерские решения в самом Ninja), поскольку я могу включать N подпроектов, каждый со своими собственными build.ninja файлов, а затем использовать их графики, чтобы позволить мне автоматически построить гораздо больший график зависимостей.

Я лично думаю, что это сделало бы subninja намного более полезным, хотя я мог видеть, что это потенциально критическое изменение. Однако я не вижу способа обойти это, если только 1) я не изменю файлы build.ninja зависимостей с помощью патча или 2) не пожертвую возможностью использовать графики зависимостей зависимостей.

Мысли?

Как насчет:

subninja path/to/build.ninja relative path/to

а отсутствующий relative по умолчанию равен ./ . Это сделало бы его неразрушающим, но все же дало бы функциональность, если генератор того пожелает.

Или, следуя по стопам других конструкций ниндзя, может быть,

subninja path/to/build.ninja
  relative = path/to

Предположим, у вас есть проект в .../foo, и у него есть панель подкаталогов, и у Ninja была предложенная вами логика относительного пути.

Если ваша система сборки хочет записывать все выходные данные сборки в /foo/obj, субниндзя в /foo/bar, который использует относительные пути к каталогу, должен знать, чтобы записать свой вывод в ../obj/bar, так как это путь к файл из этого подкаталога. Таким образом, все, что генерирует ваши файлы build.ninja, должно уже знать о глобальной иерархии путей, и в этом случае сделать все пути относительными — это фактически та же проблема, что и добавление строки bar/ к путям в каталоге bar/.

Возможно, есть достаточно людей, которые пишут выходные данные сборки в своих исходных каталогах, но вышеизложенное не имеет значения. В основном я слышу от людей, которые хотят еще более сильного разделения — например, людей, которые отправили патчи в Ninja, чтобы они могли собирать Ninja с выводом сборки в совершенно несвязанном каталоге.

Я не уверен, что понимаю. Субниндзя, в случае использования, который я описал, в частности, обычно не знают о структуре родительского ниндзя (по крайней мере, не должны знать). Я уверен, что кто-то там мог бы найти случай, когда они это делают.

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

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

Эван: Насколько я понял, нужно создать такое дерево:

  subbuild1
  subbuild2

и поскольку генераторы обычно поддерживают размещение каталога сборки в произвольных местах, сборка проекта 1 в подсборке 1 и проекта 2 в подсборке 2 должна работать. Затем в builddir есть файл ниндзя верхнего уровня, который Qix хочет использовать для создания подпроектов.

Несвязанный: эта функция relative также должна изменить cwd на свой аргумент, если какие-либо правила зависят от текущего каталога, равного их каталогу сборки (например, если правило удаляет встроенные артефакты или что-то в этом роде).

Была ли эта страница полезной?
0 / 5 - 0 рейтинги