Как изменить значения по умолчанию таких переменных, как CC в Makefile

(GNU) make использует несколько variables, например:

  • CC - компилятор C по умолчанию CC
  • CFLAGS - флаги для компилятора C, по умолчанию пустые

Я хотел бы указать свои собственные значения по умолчанию для некоторых из них в моем Makefile. В приведенном ниже примере я использовал оператор условного присваивания ?=, чтобы переопределить мои значения по умолчанию при запуске make:

CFLAGS ?= CFLAGS_my_default
CC ?= CC_my_default

print:
    echo CC=$(CC) CFLAGS=$(CFLAGS)

К сожалению, это не меняет значение переменной CC, поскольку исходное значение по умолчанию остается там. CFLAGS устанавливаются моим назначением, поскольку переменная изначально была пустой:

$ make print
echo CC=cc CFLAGS=CFLAGS_my_default
CC=cc CFLAGS=CFLAGS_my_default

Переключение из переменных среды работает как ожидалось:

$ CC=CC_from_env CFLAGS=CFLAGS_from_env make print
echo CC=CC_from_env CFLAGS=CFLAGS_from_env
CC=CC_from_env CFLAGS=CFLAGS_from_env

Как изменить значения переменных по умолчанию и по-прежнему их переопределять при вызове make?

Ответ 1

Я использовал этот Makefile для запуска некоторых тестов с помощью GNU Make и проверки origin и значения по умолчанию для некоторых переменных:

define whatisit
$(info $(1) origin is ($(origin $(1))) and value is ($($(1))))
endef

$(call whatisit,CC)
$(call whatisit,CFLAGS)

Вот результаты:

$ make
CC origin is (default) and value is (cc)
CFLAGS origin is (undefined) and value is ()
$ # Environment
$ CC=clang CFLAGS=-Wall make
CC origin is (environment) and value is (clang)
CFLAGS origin is (environment) and value is (-Wall)
$ # Command line
$ make CC=clang CFLAGS=-Wall
CC origin is (command line) and value is (clang)
CFLAGS origin is (command line) and value is (-Wall)

Как вы видите, существует два типа переменных. Эти типы определены в руководстве.

Первый набор переменных (AR, AS, CC,...) имеет значения default. Второй набор переменных (ARFLAGS, ASFLAGS, CFLAGS,...) по умолчанию содержит пустую строку (т.е. undefined).

По умолчанию они могут быть переопределены средой или командной строкой.


Установить значение по умолчанию для переменных undefined

Для переменных undefined (а также других пользовательских переменных) вам просто нужно использовать оператор ?= для установки значения по умолчанию, которое может быть переопределено средой или командной строкой.

CFLAGS ?= -Wall -Wextra -Werror

Установить значение по умолчанию для переменных default

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

ifeq ($(origin CC),default)
CC = gcc
endif

Заключение

Makefile:

ifeq ($(origin CC),default)
CC  = gcc
endif
CFLAGS  ?= -Wall -Wextra -Werror

define whatisit
$(info $(1) origin is ($(origin $(1))) and value is ($($(1))))
endef

$(call whatisit,CC)
$(call whatisit,CFLAGS)

Конечный результат:

$ make
CC origin is (file) and value is (gcc)
CFLAGS origin is (file) and value is (-Wall -Wextra -Werror)
$ # Environment
$ CC=clang CFLAGS=-Wall make
CC origin is (environment) and value is (clang)
CFLAGS origin is (environment) and value is (-Wall)
$ # Command line
$ make CC=clang CFLAGS=-Wall
CC origin is (command line) and value is (clang)
CFLAGS origin is (command line) and value is (-Wall)

Дополнительно

Вы можете использовать переменную MAKEFLAGS, чтобы отключить встроенные неявные правила и встроенные параметры переменных. Таким образом:

MAKEFLAGS += -rR

Это очистит множество настроек по умолчанию (вы можете проверить это, используя make -p). Но переменные default (например, CC) будут по-прежнему иметь значение по умолчанию.

Ответ 2

Можно использовать не условное назначение:

CFLAGS ?= CFLAGS_my_default
CC = CC_my_default

print:
    echo CC=$(CC) CFLAGS=$(CFLAGS)

но безоговорочно заданные переменные не могут быть переопределены из переменных среды:

$ CC=CC_from_env CFLAGS=CFLAGS_from_env make print
echo CC=CC_my_default CFLAGS=CFLAGS_from_env
CC=CC_my_default CFLAGS=CFLAGS_from_env

Подождите, существует другой способ установки переменной при вызове make! - из аргументов командной строки:

$ make print CC=CC_from_cmdline CFLAGS=CFLAGS_from_cmdline
echo CC=CC_from_cmdline CFLAGS=CFLAGS_from_cmdline
CC=CC_from_cmdline CFLAGS=CFLAGS_from_cmdline

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

Другим методом является включение переопределения беспорядочно заданных переменных переменными среды с помощью командной строки -e:

$ CC=CC_from_env CFLAGS=CFLAGS_from_env make -e print
echo CC=CC_from_env CFLAGS=CFLAGS_from_env
CC=CC_from_env CFLAGS=CFLAGS_from_env