Подтвердить что ты не робот

Что означает $$ @и символ трубы в Makefile?

В следующем определении Makefile:

  • Что означает [email protected] во второй последней строке?
  • Как насчет символа | в средней строке?
define KERNEL_RULE
$(DESTDIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR)
    cp $(DESTDIR)/$(1) [email protected]
endef
4b9b3361

Ответ 1

(У вас есть плачевный выбор имен переменных, пусть меняются DESTDIR на SOURCE_DIR и оставляют только DEST_DIR.)

Предположим, вы писали обычное правило:

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo
    cp $(SOURCE_DIR)/foo $(DEST_DIR)/foo

Это работает, но избыточность вызывает беспокойство. Рано или поздно вы измените $(DEST_DIR)/foo в preq, но забудьте изменить его в правиле. И правило трудно читать. Поэтому мы добавили автоматическую переменную:

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo
    cp $(SOURCE_DIR)/foo [email protected]

Когда это правило выполняется, [email protected] будет расширено до имени цели, $(DEST_DIR)/foo. (Мы можем сделать еще лучше, но позвольте остановиться там.)

Теперь мы хотим убедиться, что $(DEST_DIR) существует до того, как это правило выполняется, но мы не хотим, чтобы оно было необходимым условием, потому что отсутствие этого каталога не должно быть достаточным для запуска этого правила. Поэтому мы делаем это предварительным условием для заказа:

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo | $(DEST_DIR)
    cp $(SOURCE_DIR)/foo [email protected]

Теперь мы требуем много правил, подобных этому, для разных целей, а вместо этого умный способ, мы будем использовать "консервированный рецепт" , своего рода шаблон для создания правил на лету.

# This won't work
define KERNEL_RULE
$(SOURCE_DIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(SOURCE_DIR)/$(1) | $(DEST_DIR)
    cp $(SOURCE_DIR)/$(1) [email protected]
endef

Проблема заключается в том, что, когда мы оценим это определение, [email protected] будет расширен, и поскольку он еще не является правилом, он будет расширяться до нуля. Поэтому мы меняем его на [email protected]:

# This will work
define KERNEL_RULE
$(SOURCE_DIR)/$(1) : kernel_modules
$(DEST_DIR)/$(1) : $(SOURCE_DIR)/$(1) | $(DEST_DIR)
    cp $(SOURCE_DIR)/$(1) [email protected]
endef

Когда Make вызывает это определение, [email protected] расширяется до [email protected], то если/когда он запускает правило, [email protected] будет расширяться до имени цели.