Как отслеживать цели Makefile для устранения неполадок?

У нас есть длинный и сложный Makefile в нашей системе сборки. Есть ли хороший способ отследить, какие именно цели выполняются для данного вызова make?


person zer0stimulus    schedule 07.06.2012    source источник


Ответы (3)


Используйте make -d или make --debug[=flags] параметры:

‘-d’

Печать отладочной информации в дополнение к обычной обработке. Информация об отладке сообщает, какие файлы рассматриваются для переделки, какое время файла сравнивается и с какими результатами, какие файлы на самом деле необходимо переделать, какие неявные правила учитываются и какие применяются — все интересно о том, как make решает, что делать. Параметр -d эквивалентен ‘--debug=a’ (см. ниже).

‘--debug[=options]’

Печать отладочной информации в дополнение к обычной обработке. Могут быть выбраны различные уровни и типы выхода. Без аргументов вывести «базовый» уровень отладки. Возможные аргументы приведены ниже; учитывается только первый символ, а значения должны быть разделены запятыми или пробелами.

a (все) Включены все типы вывода отладки. Это эквивалентно использованию «-d».

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

v (подробно) Уровень выше ‘basic’; включает сообщения о том, какие make файлы были проанализированы, пререквизиты, которые не нужно было пересобирать, и т. д. Эта опция также включает ‘basic’ сообщения.

i (неявный) Выводит сообщения, описывающие поиск неявных правил для каждой цели. Эта опция также включает ‘basic’ сообщений.

j (jobs) Выводит сообщения с подробными сведениями о вызове определенных подкоманд.

m (makefile) По умолчанию вышеуказанные сообщения не отображаются при попытке пересоздать make-файлы. Эта опция также включает сообщения при перестроении make-файлов. Обратите внимание, что опция ‘all’ включает эту опцию. Эта опция также включает ‘basic’ сообщений.

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

person Eldar Abusalimov    schedule 07.06.2012

ElectricMake может создать версию журнала сборки с разметкой XML с много информации, которая поможет в этой ситуации:

  • Полные командные строки для всех команд, вызываемых во время сборки (даже тех, которые были помечены как «тихие» команды с модификатором @).
  • Происхождение (makefile и номер строки) вызванных команд.
  • Время выполнения команд.
  • Отношения зависимости между целями в сборке.
  • Структурная взаимосвязь между целями и рекурсивными производителями в сборке.
  • Файлы, читаемые/записываемые командами, вызванными в сборке.

Вот пример этого вывода:

<job id="J0824ab08" thread="5e72bb0" node="linbuild1-2" type="rule" name="../../i686_Linux/testmain/testmain.d" file="../config/rules.mak" line="109">
<command line="110">
<argv>echo Rebuilding '../../i686_Linux/testmain/testmain.d'</argv>
<output src="prog">Rebuilding ../../i686_Linux/testmain/testmain.d
</output>
</command>
<command line="111-114">
<argv>set -e; g++ -MM -w  -DUSE_PROFILING -DUSE_LOGGING -DHAVE_UNIX -DHAVE_LINUX -I.. testmain.cpp \
        | sed 's!\(testmain\)\.o[ :]*!../../i686_Linux/testmain/\1.o '../../i686_Linux/testmain/testmain.d' : !g' \
        &gt; '../../i686_Linux/testmain/testmain.d'; \
        [ -s '../../i686_Linux/testmain/testmain.d' ] || touch '../../i686_Linux/testmain/testmain.d'</argv>
</command>
<opList>
<op type="read" file="/home/ericm/src/testmain/testmain.cpp"/>
<op type="read" file="/home/ericm/src/minidumper/ExceptionReport.h"/>
<op type="read" file="/home/ericm/src/util/ECAssert.h"/>
<op type="create" file="/home/ericm/i686_Linux/ecloud/testmain/testmain.d" found="0"/>
</opList>
<timing invoked="1.919926" completed="3.600491" node="linbuild1-2"/>
<waitingJobs idList="J0824ae38"/>
</job>

Как быстро перемещаться Незнакомый Makefile показывает пример использования аннотированного журнала сборки, чтобы ориентироваться в Makefile.

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

ElectricMake совместим с GNU Make, поэтому он может обрабатывать make-файлы, которые работают с GNU make.

Отказ от ответственности. Я архитектор и ведущий разработчик ElectricAccelerator.

person Eric Melski    schedule 07.06.2012
comment
Эй, Эрик! Я электрический пользователь. Круто видеть, что ты публикуешь. Количество журналов отладки и опций, встроенных в emake, просто ошеломляет. Отличный продукт, рекомендую. - person ThePosey; 08.06.2012
comment
Привет, Эрик. Я не смог найти в Интернете электрические или искровые сборки. Разве больше нет бесплатной возможности попробовать эти инструменты? - person SFbay007; 09.01.2019
comment
@SFbay007 Electric Make является компонентом ElectricAccelerator. Ссылка в моем ответе ведет на страницу продукта ElectricAccelerator, откуда вы можете загрузить пробную версию. Вот еще раз ссылка: electric-cloud.com/products/electricaccelerator - person Eric Melski; 10.01.2019

Вы можете получить некоторую информацию о том, какие цели создаются и почему, переопределив переменную SHELL в GNU make:

__ORIGINAL_SHELL:=$(SHELL)
SHELL=$(warning Building $@$(if $<, (from $<))$(if $?, ($? newer)))$(TIME) $(__ORIGINAL_SHELL)

Например, в trace-targets.mk:

__ORIGINAL_SHELL:=$(SHELL)
SHELL=$(warning Building $@$(if $<, (from $<))$(if $?, ($? newer)))$(TIME) $(__ORIGINAL_SHELL)

all: aa.stamp ba.stamp

%.stamp:
    echo stamp > $(@)

stamp-clean:
    rm -vf *.stamp

clean: stamp-clean

.PHONY: %.phony
%.phony:
    echo $(@)

aa.stamp: ab.stamp
ab.stamp: ac.stamp

ba.stamp: bb.stamp
bb.stamp: bc.phony

Запуск trace-targets.mk после очистки:

$ make -f trace-targets.mk
trace-targets.mk:9: Building ac.stamp
echo stamp > ac.stamp
trace-targets.mk:9: Building ab.stamp (from ac.stamp) (ac.stamp newer)
echo stamp > ab.stamp
trace-targets.mk:9: Building aa.stamp (from ab.stamp) (ab.stamp newer)
echo stamp > aa.stamp
trace-targets.mk:18: Building bc.phony
echo bc.phony
bc.phony
trace-targets.mk:9: Building bb.stamp (from bc.phony) (bc.phony newer)
echo stamp > bb.stamp
trace-targets.mk:9: Building ba.stamp (from bb.stamp) (bb.stamp newer)
echo stamp > ba.stamp

Затем снова запустим trace-targets.mk без очистки:

$ make -f trace-targets.mk
trace-targets.mk:18: Building bc.phony
echo bc.phony
bc.phony
trace-targets.mk:9: Building bb.stamp (from bc.phony) (bc.phony newer)
echo stamp > bb.stamp
trace-targets.mk:9: Building ba.stamp (from bb.stamp) (bb.stamp newer)
echo stamp > ba.stamp

Практически, что я делаю в своих make-файлах, так это добавляю этот фрагмент:

ifneq ($(filter all targets,$(VERBOSE)),)
__ORIGINAL_SHELL:=$(SHELL)
SHELL=$(warning Building $@$(if $<, (from $<))$(if $?, ($? newer)))$(TIME) $(__ORIGINAL_SHELL)
endif

Затем я запускаю свои make-файлы следующим образом, чтобы увидеть трассировку:

make VERBOSE=all
# or
make VERBOSE=targets

Причина all/targets в том, что у меня есть и другие подробные сведения, подобные этому:

ifneq ($(filter all vars,$(VERBOSE)),)
dump_var=$(info var $(1)=$($(1)))
dump_vars=$(foreach var,$(1),$(call dump_var,$(var)))
else
dump_var=
dump_vars=
endif

# used like

$(call dump_vars,SHELL VERBOSE)

И иногда я хочу выборочно включать/отключать аспекты отладки.

Если у вас много make-файлов, возможно, имеет смысл поместить их в общий файл и включить из других.


Предоставлено Джоном Грэмом-Каммингом, который описал этот метод в Отслеживание выполнения правила в GNU Make.

person Iwan Aucamp    schedule 14.01.2020
comment
Это действительно интересное решение. Единственная проблема заключается в том, что переменные SHELL и OLD_SHELL должны быть переопределены в каждом отдельном файле Makefile проекта с помощью следующей команды (предварительные условия не в списке): find . -name "Makefile" -exec sed -i '1s/^/OLD_SHELL := $(SHELL)\nSHELL = $(warning Building $@)$(OLD_SHELL) -x\n/' {} \; - person TheAhmad; 01.11.2020
comment
@TheAhmad Я добавил некоторые подробности о том, что я делаю на практике, то есть помещал это в условие, контролируемое переменной VERBOSE, а иногда помещал его в отдельный файл, который я включаю. - person Iwan Aucamp; 06.11.2020