如何在Makefile中更改CC等变量的默认值

pab*_*ouk 14 variables makefile default-value gnu-make

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

  • CC - 默认情况下为C编译器 cc
  • CFLAGS - C编译器的标志,默认为空

我想在我的中指定一些我自己的默认值Makefile.在下面的示例中,我使用条件赋值运算符?=在运行时能够覆盖我的默认值make:

CFLAGS ?= CFLAGS_my_default
CC ?= CC_my_default

print:
    echo CC=$(CC) CFLAGS=$(CFLAGS)
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不会改变CC变量的值,因为原始默认值保持不变.CFLAGS由我的赋值设置,因为变量最初是空的:

$ make print
echo CC=cc CFLAGS=CFLAGS_my_default
CC=cc CFLAGS=CFLAGS_my_default
Run Code Online (Sandbox Code Playgroud)

从环境变量覆盖按预期工作:

$ 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
Run Code Online (Sandbox Code Playgroud)

如何更改变量的默认值,并且仍然可以在调用时覆盖它们make

pab*_*ouk 11

可以使用非条件赋值:

CFLAGS ?= CFLAGS_my_default
CC = CC_my_default

print:
    echo CC=$(CC) CFLAGS=$(CFLAGS)
Run Code Online (Sandbox Code Playgroud)

但是无法从环境变量中覆盖无条件设置的变量:

$ 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
Run Code Online (Sandbox Code Playgroud)

等等,调用时还有另一种设置变量的方法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
Run Code Online (Sandbox Code Playgroud)

这样,非条件设置变量也会被覆盖.此方法甚至可以在递归使用命令行中指定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
Run Code Online (Sandbox Code Playgroud)

  • 如果使用`-e`调用make,则无条件设置的变量可以被环境变量覆盖:`CC = CC_from_env CFLAGS = CFLAGS_from_env make -e print` (3认同)

jml*_*jml 5

我用它Makefile来运行GNU Make的一些测试并检查一些变量的原点和默认值:

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

$(call whatisit,CC)
$(call whatisit,CFLAGS)
Run Code Online (Sandbox Code Playgroud)

结果如下:

$ 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)
Run Code Online (Sandbox Code Playgroud)

如您所见,有两种类型的变量.这些类型在手册中定义.

第一组的变量(AR,AS,CC,...)具有default价值.第二组变量(ARFLAGS,ASFLAGS,CFLAGS,...)都默认为空字符串(即undefined).

默认情况下,它们可以通过环境或命令行覆盖.


设置undefined变量的默认值

对于undefined变量(以及其他用户变量),您只需使用?=运算符来设置可以通过环境或命令行覆盖的默认值.

CFLAGS ?= -Wall -Wextra -Werror
Run Code Online (Sandbox Code Playgroud)

设置default变量的默认值

更改default变量默认值的最佳方法是检查其原点并仅在需要时更改值.

ifeq ($(origin CC),default)
CC = gcc
endif
Run Code Online (Sandbox Code Playgroud)

结论

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)
Run Code Online (Sandbox Code Playgroud)

最终结果:

$ 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)
Run Code Online (Sandbox Code Playgroud)

可选的

您可以使用该MAKEFLAGS变量来禁用内置隐式规则和内置变量设置.这条路:

MAKEFLAGS += -rR
Run Code Online (Sandbox Code Playgroud)

这将清除许多默认设置(您可以使用它来检查make -p).但default变量(如CC)仍将具有默认值.