Печать в C ищет исходники рантайма рядом с ДВОИЧНЫМ, и в дереве репозитория это работает по совпадению раскладки
flang emit --target c кладёт рантайм, прогонщик и оболочку в вывод дословно, а значит читает их с диска. Ищет он их в --runtime, в $FLANG_RUNTIME_DIR и рядом с собой — то есть относительно каталога, где лежит сам исполняемый файл, а не относительно текущего каталога и не относительно входного .flang.
Двоичный из bootstrap/flang находит их случайно: на один уровень выше его каталога как раз корень дерева, где и лежит flang/src/emit/c. Стоит взять тот же самый двоичный, скопированный или собранный в стороне, — и печать отказывает:
flang emit: не найдены исходники рантайма C — они уезжают в вывод ДОСЛОВНО, и
без них печать соврала бы.
Код возврата 2. Отказ честный и называет причину — тихо неправильного вывода здесь не бывает, — но обнаруживается он только тогда, когда двоичного двигают.
Чем подтверждено. Ветка svod/vosem, поверх fe8e8a37, 20 августа 2026. Семь файлов точки раскрутки скопированы в каталог вне дерева и собраны там (env -i PATH=/usr/bin:/bin, -Werror -pedantic, ноль предупреждений, 55 с). Получившийся двоичный — 12 694 664 байта, побайтово тот же файл, что bootstrap/flang. Тот же двоичный, позванный из корня дерева на том же входе:
- лежащий в
bootstrap/— печатает, код 0; - лежащий вне дерева — «не найдены исходники рантайма C», код 2.
Разошлось только место двоичного. Ни вход, ни текущий каталог, ни ключи не менялись.
С названным --runtime тот же двоичный вне дерева печатает и сходится: сверка sh scripts/raskrutka.sh --check под env -i PATH=/usr/bin:/bin отвечает «точка раскрутки bootstrap/ совпадает с печатью: 7 файлов, 23903454 байт», код 0, 11 м 52 с, пик памяти 20 072 180 КБ. То есть ключ ничего в напечатанном байте не меняет — он только перестаёт полагаться на раскладку.
Чему учит. Рецепт пересборки обязан называть --runtime явно, а не полагаться на поиск. Пока рецепт жил в JavaScript (scripts/bootstrap-c.mjs, который звал печать библиотекой, а не командой), этой развилки не существовало вовсе, и в записке bootstrap-circle-is-broken-but-the-binary-cannot-check-itself она названа второй из трёх помех: «печать читает рантайм C с диска, и для пересборки нужен не каталог bootstrap/, а дерево целиком». Замер выше уточняет её: нужно не просто дерево, а ещё и двоичный внутри дерева, на один уровень ниже корня.
Это класс, а не случай: работает по совпадению раскладки. Признак, по которому третий такой случай ищется заранее, — путь, выведенный из места исполняемого файла (dirname(argv[0])/..) и нигде не названный словами. Пока единственный потребитель лежит там, где надо, такой путь неотличим от настоящего умолчания.
Чем ограничено. Мерено на Linux 7.0.0, cc 15.2.0, версия 0.5.1, цель c. У остальных семи целей рантайм читается тем же кодом, но отдельно не проверялось. Установленный из релиза двоичный сюда не попадает: обе упаковки кладут рантайм в share/flang/c рядом с ним, и это названный путь, а не совпадение.
Связано: bootstrap-circle-is-broken-but-the-binary-cannot-check-itself, a-layer-inside-the-bootstrap-point-is-frozen-until-it-is-reprinted