make idea
Я периодически нарываюсь на проблемы параллельной сборки всяких проектов
средствами make. Из недавних: баг
#326347, баг
#373947. Эти баги
особенны тем, что они проявляются только на 8-головых (и выше) машинах.
На моём корытце они не очень хотят проявляться.
Концептуально, Makefile - файл со списком целей и правил, по которым
строятся промежуточные цели, чтобы достигнуть конечной.
A -(r1)-> B \
C -(r2)-> D (r4)-> G
E -(r3)-> F /
A,B,C- начальные целиD,E,F- промежуточные целиG- конечная цельr<N>- правила построения целей.
Обычно апстрим проекта тестирует сборку через команду make без
всяких -jN параметров, а GNU make всегда выполняет правила для
(хоть и независимых) целей в одном и том же порядке.
В итоге получаем порядок исполнения правил:
r1r2r3r4
Но что, если r2 всё-таки требует результата r1 и Makefile -
неправильный? Как бы извратиться и найти эту ошибку автоматически?
И вот что я надумал:
Простое решение. Произвольно переставлять порядок исполнения
независимых целей при каждом запуске make в самом make. Так бы
от запуска к запуску тестировались разные порядки сборки и возможные
ошибки (правда, не все) выплывали чаще даже без использвания make -j<N>. Чтобы воспроизвести тот же порядок при ошибке make мог бы
выводить на экран или в файл то, что заставило бы make пытаться
собрать цели в том же порядке. К примеру, Makefile.faulty с явно
заданной последовательностью правил.
Сложное решение. Встроить в make поддержку отслеживания всех
порождаемых процессов (например, через ptrace или LD_PRELOAD) и
записывать в какие цели они лезут на чтение/запись. После завершения
сборки проверять: соответствует ли граф зависимотей целей тем целям,
которые открывались дочерними программами. В теории, такой вариант (в
отличии от предыдущего) способен находить сразу все недостаточные
завосимости в Makefile.
ptrace используется
sydbox из exherbo,
LD_PRELOAD используется
sandbox
из gentoo. На свете есть еще
fsnotify.
Кто реализует раньше, чем я, тот - молодец! :)
UPDATE: в GNU make это реализовано в опции
--shuffle.