Почему ifeq работает по-разному при размещении в разных местах? - PullRequest
0 голосов
/ 18 апреля 2020

Я все еще учусь использовать make-файлы в windows, и я путаюсь с ifeq. То, что я пытаюсь сделать, когда я ввожу make Z=1 в моей командной строке, он скомпилирует мои файлы с -std=c++17.

Вот часть кода, которая меня смущает:

CXXFLAGS = -Wall -Werror

COMMONRECIPE = $(CXX) $(CXXFLAGS) $? -o $@ && @echo recompiled: $?

ifeq "$Z" "1"
    CXXFLAGS += -std=c++17
endif

работает полностью, как и ожидалось, без проблем. Однако, когда я изменяю порядок кода и помещаю переменную COMMONRECIPE под кодом, подобным следующему:

CXXFLAGS = -Wall -Werror

ifeq "$Z" "1"
    CXXFLAGS += -std=c++17
endif

COMMONRECIPE = $(CXX) $(CXXFLAGS) $? -o $@ && @echo recompiled: $?

, он больше не добавляет флаг -std=c++17, когда я делаю make Z=1, как если бы ifeq никогда не было даже там.

Вот полный код в make-файле:

CXXFLAGS = -Wall -Werror
.PHONY: default clean 

COMMONRECIPE = $(CXX) $(CXXFLAGS) $? -o $@ && @echo recompiled: $?

ifeq "$Z" "1"
    CXXFLAGS += -std=c++17
endif
ifeq "$(2A)" "1"
    CXXFLAGS += -std=c++2a
endif
ifeq "$W" "1"
    CXXFLAGS += -mwindows
endif
ifeq "$C" "1"
    CXXFLAGS += -mconsole
endif

default: test1.exe test2.exe test3.exe

test1.exe test1: test1.cpp
    $(COMMONRECIPE)

test2.exe test2: test2.cpp
    $(COMMONRECIPE)

test3.exe test3: test3.cpp
    $(COMMONRECIPE)

clean:
    del *.exe

1 Ответ

1 голос
/ 18 апреля 2020

О, я вижу проблему. Ваш первый пример был слишком урезанным: вы пропустили .PHONY, что и является причиной проблемы.

Проблема root в том, что вы присваиваете свои переменные назначения символам TAB. Таблицы являются специальными для создания и должны только использоваться для отступа строк рецепта, а не назначений make-файлов.

Имея это:

.PHONY: default clean 

ifeq "$Z" "1"
        CXXFLAGS += -std=c++17
endif

где CXXFLAGS присвоение имеет отступ с табуляции, вы фактически помещаете присвоение переменной в рецепт для цели .PHONY, как если бы вы написали это:

.PHONY: default clean 
        CXXFLAGS += -std=c++17

Помните, что пустые строки, строки комментариев и условные операторы типа ifeq не останавливают рецепт. Только строка без рецепта останавливает рецепт.

Хотя .PHONY является псевдо-целью и ее рецепт никогда не запускается, он все же является целью, и вы все равно можете создать рецепт для него.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...