Я пытаюсь использовать «ложное» шаблонное правило в моем Makefile
для компиляции всех моих исходных файлов Erlang с помощью одного вызова компилятора.Это работает, но по какой-то причине make решает всегда переделывать цель, даже если она новее, чем ее предпосылки.Что здесь происходит?
Это соответствующий раздел моего Makefile
:
.SUFFIXES: .erl .beam .yrl .d .app .app.src
.PHONY: all build tests clean docs distclean realclean
build: $(ERL_OBJECTS)
$(ERL_NON_PRE_OBJECTS:.beam=.bea%): $(ERL_NON_PRE_SOURCES)
$(ERLC) -pa $(EBIN_DIR) $(ERLC_FLAGS) -o $(EBIN_DIR) $(filter $(SRC_DIR)/%.erl,$?)
Это соответствующий раздел вывода make -d -p build
:
Considering target file 'build'.
File 'build' does not exist.
Considering target file 'ebin/field_usage.beam'.
Looking for an implicit rule for 'ebin/field_usage.beam'.
Trying pattern rule with stem 'm'.
Trying rule prerequisite 'src/field_usage.erl'.
Trying rule prerequisite 'src/bo_lib.erl'.
Trying rule prerequisite 'src/bo.erl'.
Trying rule prerequisite 'src/flags.erl'.
Trying rule prerequisite 'src/bos_utilities.erl'.
Trying rule prerequisite 'src/generate_bo_template.erl'.
Trying rule prerequisite 'src/bo_mappings.erl'.
Trying rule prerequisite 'src/document_bos.erl'.
Trying rule prerequisite 'src/types.erl'.
Trying rule prerequisite 'src/document_config_bos.erl'.
Trying rule prerequisite 'src/bo_transform.erl'.
Found an implicit rule for 'ebin/field_usage.beam'.
[...]
Finished prerequisites of target file 'ebin/field_usage.beam'.
Prerequisite 'src/field_usage.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/bo_lib.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/bo.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/flags.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/bos_utilities.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/generate_bo_template.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/bo_mappings.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/document_bos.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/types.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/document_config_bos.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/bo_transform.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'src/field_usage.erl' is older than target 'ebin/field_usage.beam'.
Prerequisite 'ebin' is order-only for target 'ebin/field_usage.beam'.
Must remake target 'ebin/field_usage.beam'.
[...]
ERL_OBJECTS := ebin/field_usage.beam ebin/bo_lib.beam ebin/bo.beam ebin/flags.beam ebin/bos_utilities.beam ebin/generate_bo_template.beam ebin/bo_mappings.beam ebin/document_bos.beam ebin/types.beam ebin/document_config_bos.beam ebin/bo_transform.beam
ERL_NON_PRE_OBJECTS := ebin/field_usage.beam ebin/bo_lib.beam ebin/bo.beam ebin/flags.beam ebin/bos_utilities.beam ebin/generate_bo_template.beam ebin/bo_mappings.beam ebin/document_bos.beam ebin/types.beam ebin/document_config_bos.beam ebin/bo_transform.beam
ERL_NON_PRE_SOURCES := src/field_usage.erl src/bo_lib.erl src/bo.erl src/flags.erl src/bos_utilities.erl src/generate_bo_template.erl src/bo_mappings.erl src/document_bos.erl src/types.erl src/document_config_bos.erl src/bo_transform.erl
ebin/field_usage.beam: src/field_usage.erl src/bo_lib.erl src/bo.erl src/flags.erl src/bos_utilities.erl src/generate_bo_template.erl src/bo_mappings.erl src/document_bos.erl src/types.erl src/document_config_bos.erl src/bo_transform.erl src/field_usage.erl | ebin
# Implicit rule search has been done.
# Implicit/static pattern stem: 'm'
# Also makes: ebin/bo_transform.beam ebin/document_config_bos.beam ebin/types.beam ebin/document_bos.beam ebin/bo_mappings.beam ebin/generate_bo_template.beam ebin/bos_utilities.beam ebin/flags.beam ebin/bo.beam ebin/bo_lib.beam
# Last modified 2019-04-10 13:04:00.763145368
# File has been updated.
# Successfully updated.
# automatic
# @ := ebin/field_usage.beam
# automatic
# % :=
# automatic
# * := m
# automatic
# + := src/field_usage.erl src/bo_lib.erl src/bo.erl src/flags.erl src/bos_utilities.erl src/generate_bo_template.erl src/bo_mappings.erl src/document_bos.erl src/types.erl src/document_config_bos.erl src/bo_transform.erl src/field_usage.erl
# automatic
# | := ebin
# automatic
# < := src/field_usage.erl
# automatic
# ^ := src/field_usage.erl src/bo_lib.erl src/bo.erl src/flags.erl src/bos_utilities.erl src/generate_bo_template.erl src/bo_mappings.erl src/document_bos.erl src/types.erl src/document_config_bos.erl src/bo_transform.erl
# automatic
# ? :=
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=2/31=6%
# recipe to execute (from '/mybuildpath/make/stdapp.mk', line 408):
$(PROGRESS)
$(ERLC) -pa $(EBIN_DIR) $(ERLC_FLAGS) -o $(EBIN_DIR) $(filter $(SRC_DIR)/%.erl,$?)
Это просто не имеет никакого смысла для меня.Зачем перестраивать ebin/field_usage.beam
, если он новее всех его зависимостей?Даже $?
устанавливается равным make
.
Я полагаю, это как-то вызвано ситуацией, когда каждый скомпилированный модуль .beam
новее своего соответствующего .erl
источника, но есть .erl
источники, которые новее, чем некоторые другие .beams
.По крайней мере, добавление touch $(ERL_NON_PRE_OBJECTS)
к рецептуре решило проблему.
Однако я не могу воспроизвести пустую ситуацию $?
на упрощенном примере:
FILES := a b c
INS := $(FILES:%=in/%.txt)
OUTS := $(FILES:%=out/%.txt)
.PHONY: build
build: $(OUTS)
$(OUTS): | out
out:
mkdir -p $@
$(OUTS:.txt=.tx%): $(INS)
echo building $@ from $?
cp -t out $?
Например make; touch in/b.txt; make
будет печатать building out/a.txt from in/b.txt
.Это указывает на проблему с моим рецептом, но мне не удалось получить пустой $?
, независимо от того, как выглядят метки времени.