Если порядок выполнения целей не указан явно, make
выполняет их в произвольном порядке - как в параллельном, так и в непараллельном режиме. Этот порядок подвергается внутренним алгоритмам make
и в вашем случае дает неприятные результаты.
Решение состоит в том, чтобы придать четкий порядок вашим тестам.
Из вашей части make-файла я предполагаю, что существует нераскрытая переменная «source», которая содержит список целей для тестирования (от этих целей зависят неявные). Также немедленное расширение этой переменной дает правильные результаты.
Предположим, что переменная такова:
list=file1 file2 file3 ... fileN
тогда для решения проблемы достаточно сгенерировать следующие зависимости:
file2: file1
file3: file2
...
fileN: fileN-1
run_tests: fileN
Как мы должны генерировать это? Давайте напишем цикл foreach-eval после того, как переменная list
получит свое значение:
len=$(words $(list))
$(foreach t, \
$(join \
$(addsuffix : ,$(wordlist 2,$(len),$(list)) run_tests), \
$(list) \
) \
, $(eval $(t)) \
)
Это создаст часть make-файла точно так же, как это делает препроцессор C (или, вернее, макросы LISP). Это будет работать так: для каждого элемента t
в списке, сформированном путем join
ing (конкатенация каждого элемента первого списка с соответствующим элементом второго) списка file2 file3 ... fileN run_tests
, к каждому элементу которого суффикс :
добавлен (таким образом формируя file2: file3: ... fileN: run_tests:
), с исходным списком file1 file2 ... fileN
; - для каждого такого элемента t
в списке с присоединенными элементами оцените его как часть источника make-файла, действуя так, как предписано вышеизложенными правилами.
Теперь вам нужно только вызвать цель run_tests, и она будет идти один за другим.