Множественные операторы if в условных обозначениях makefile

#makefile

#makefile

Вопрос:

В документации make говорится, что синтаксис сложного условного выражения следующий:

 conditional-directive-one
text-if-one-is-true
else conditional-directive-two
text-if-two-is-true
else
text-if-one-and-two-are-false
endif
  

Но я не понимаю, как использовать этот синтаксис для перезаписи следующего фрагмента кода:

 ifeq ($(option), 1)
CC=gcc
@echo use gcc
else ifeq($(option), 2)
CC=clang
@echo use clang
else
CC=mipsel-linux-gcc
@echo use mipsel-linux-gcc
endif

#first target
foo: ;
  

Комментарии:

1. Я не понимаю, почему вы хотите «переписать» этот код. Есть ли с этим проблема? Если да, то в чем проблема? Я укажу на две вещи: во-первых, вам нужен пробел после ifeq in else ifeq($(option), 2) . Во-вторых, этот синтаксис был добавлен в GNU make в версии 3.81, поэтому, если у вас более старая версия, он недоступен.

2. Я опускаю пробел после ifeq и мои text-if-one-is-true , text-two-is-true , text-if-one-and-two-are-false блоки содержат рецепты перед первой целью (они здесь не показаны). Из-за этих двух причин мой Makefile не работает.

3. Извините, но я все еще не понимаю. Вам нужно добавить пробел после ifeq , а не опускать его. Задавая вопросы, пожалуйста, показывайте минимальный пример реальной проблемы, а не другой пример, который может не показывать проблему. Также, пожалуйста, вырежьте и вставьте точное сообщение об ошибке, которое вы видите. В вашем комментарии вы упоминаете «содержать рецепты перед первым целевым объектом», что является ошибкой совершенно другого типа, которая не может произойти только с примером makefile, который вы показываете выше.

4. Я имею в виду, что я пропустил пробел после ifeq , из-за чего файл make не работает. И я не знаю, что я не могу писать рецепты до первой цели, поэтому я удаляю их из кода предыдущей версии.

Ответ №1:

Использование вашего makefile:

 ifeq ($(option), 1)
    CC=gcc
    @echo use gcc
else ifeq($(option), 2)
    CC=clang
    @echo use clang
else
    CC=mipsel-linux-gcc
    @echo use mipsel-linux-gcc
endif

#first target
foo:
    echo CC $(CC)
  

Я получаю следующую ошибку:

 $ make
Makefile:4: Extraneous text after `else' directive
Makefile:6: *** commands commence before first target.  Stop.
  

Редактирование makefile в соответствии с предложением от @MadScientist (т. е. пробел после ifeq ):

 ifeq ($(option), 1)
    CC=gcc
    @echo use gcc
else ifeq ($(option), 2)
    CC=clang
    @echo use clang
else
    CC=mipsel-linux-gcc
    @echo use mipsel-linux-gcc
endif

#first target
foo:
    echo CC $(CC)
  

Я получаю:

 $ make
Makefile:9: *** commands commence before first target.  Stop.
  

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

 ifeq ($(option), 1)
    CC=gcc
else ifeq ($(option), 2)
    CC=clang
else
    CC=mipsel-linux-gcc
endif

$(info CC is $(CC))

#first target
foo:
    @echo foo
  

Из этого я получаю:

 $ make
CC is mipsel-linux-gcc
foo
  

Смотрите https://www.gnu.org/software/make/manual/html_node/Make-Control-Functions.html#index-error для получения дополнительной информации о $(info ...) — вы можете поместить это в условные обозначения, если хотите, но зачем это вам? :->

Комментарии:

1. Спасибо, но ответ Максима такой простой и элегантный.

Ответ №2:

ИМХО, ifeq инструкции занимают слишком много места, их сложнее вводить и читать. Лучшая альтернатива:

 CC.1 := gcc
CC.2 := clang
CC := $(or ${CC.${option}},mipsel-linux-gcc)
$(info "Using ${CC}")