23

(GNU) make 使用几个变量,例如:

  • 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

4

2 回答 2

11

可以使用非条件赋值:

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进程的地方。

另一种方法是使用命令 switch 通过环境变量启用无条件设置变量的覆盖-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
于 2013-08-02T01:29:58.897 回答
9

我用它MakefileGNU Make运行了一些测试,并检查了一些变量的来源和默认值:

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)仍将具有默认值。

于 2017-03-22T17:39:44.597 回答