#export #overriding #target #gnu-make
#экспорт #переопределение #цель #gnu-make
Вопрос:
Рассмотрим следующий makefile:
# various settings, lots of them
# (supposed to be in defaults.mk)
option1="glob_val1"
option2="glob_val2"
#option3="glob_val3" # uncomment and it will override target-specific in sub-make
option4="glob_val4"
# goal is to make many items with various options
# which share common setup, but change in details.
all: item1 item2
# Item 1 is common changed option3
item1: export option3="i1_val3"
item1:
@echo "start item1:option3=$(option3)"
$(MAKE) generic_item
@echo "done item1"
# Item 2 is common another option3
item2: export option3="i2_val3"
item2:
@echo "start item2: option3=$(option3)"
$(MAKE) generic_item
@echo "done item2"
# This is generic item that does everything
# basing on options settings
generic_item:
@echo "do generic option3=$(option3) [expecting i<X>_val3 here]"
Что я хочу, так это переопределить любую из опций в target и
затем вызовите универсальную процедуру в ‘generic_item’.
Проблема в том, что если option3 определен поверх Makefile, он передается без изменений во вложенный make. Если параметр 3 сверху закомментирован, то все работает, как ожидалось:
start item1:option3=i1_val3
make generic_item
make[1]: Entering directory `/tmp/make_items'
do generic option3=i1_val3 [expecting i<X>_val3 here]
make[1]: Leaving directory `/tmp/make_items'
done item1
start item2: option3=i2_val3
make generic_item
make[1]: Entering directory `/tmp/make_items'
do generic option3=i2_val3 [expecting i<X>_val3 here]
make[1]: Leaving directory `/tmp/make_items'
done item2
Я не хочу использовать $ (MAKE) option1=… option2 =… generic_item
синтаксис, поскольку он выглядит не очень хорошо, и может быть много вариантов
с длинными значениями и все это войдет в журнал и выглядит не очень хорошо.
Цель состоит в том, чтобы иметь одну общую цель, которая выполняет работу на основе значений опций (их много) и возможность расширять ее дополнительными целями, которым нужно только переопределять определенные значения / добавлять новые действия и оставлять остальное общей цели.
Пожалуйста, предложите другой подход, если мой выглядит неправильно.
Ответ №1:
Основное исправление заключается в добавлении -e
к submake
Я предлагаю ряд улучшений. Руководство GNU Make — это сокровищница для такого рода продвинутых сценариев.
Обратите внимание, что при подходе, показанном ниже, вложенный файл вряд ли необходим. Я делаю submake только тогда, когда
- Мне нужно перезагрузить основной Makefile из-за измененных включений (я считаю, что это запах дизайна и стараюсь этого избегать)
- Я хочу разделить работу по вложенным файлам
Для вашего удобства я придерживался вашего подхода submake, чтобы показать вам, что это можно сделать:
export option="glob_val"
.SECONDEXPANSION: # http://www.gnu.org/s/hello/manual/make/Secondary-Expansion.html
TARGETS=item1 item2 item3 item4 item5
all: $(TARGETS)
$(TARGETS): option="$(@)_val"
$(TARGETS):
@echo "start $@:option=$(option)"
$(MAKE) -e generic_item
@echo "done $@"
generic_item:
@echo "do generic option=$(option)"
Вывод make -s
start item1:option=item1_val
start item2:option=item2_val
start item3:option=item3_val
start item4:option=item4_val
start item5:option=item5_val
do generic option=item1_val
do generic option=item2_val
done item1
do generic option=item4_val
done item2
do generic option=item3_val
done item4
do generic option=item5_val
done item5
done item3
Комментарии:
1. Спасибо! -e — это то, чего не хватало.
2. @VLH: спасибо за согласие и добро пожаловать в StackOverflow! Обратная связь высоко ценится