我可以将变量作为命令行参数传递给GNU Makefile吗?换句话说,我想传递一些最终会成为Makefile变量的参数 .
您有几个选项可以从makefile外部设置变量:
您可能还想设置 -e 选项(又名 --environments-override ),您的环境变量将覆盖makefile中的赋值(除非这些赋值本身使用override directive . 但是,'s not recommended, and it'更好更灵活地使用 ?= 赋值(条件变量)赋值运算符,它只有在尚未定义变量时才有效:):
-e
--environments-override
?=
FOO?=default_value_if_not_set_in_environment
请注意,某些变量不是从环境继承的:
MAKE 来自脚本名称
MAKE
SHELL 要么在makefile中设置,要么默认为 /bin/sh (基本原理:命令在makefile中指定,并且它们是特定于shell的) .
SHELL
/bin/sh
From command line - make 可以将变量赋值作为其命令行的一部分,与目标混合:
make
make target FOO=bar
但是,除非在赋值中使用override directive,否则将忽略makefile中 FOO 变量的所有赋值 . (效果与环境变量的 -e 选项相同) .
FOO
# Don't do this! target: $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
相反,更好的解决方案可能是导出这些变量 . 导出变量使其进入每个shell调用的环境中,并且使用这些命令进行调用将按照上面的指定选择这些环境变量 .
# Do like this CFLAGS=-g export CFLAGS target: $(MAKE) -C target
您还可以使用 export 不带参数导出所有变量 .
export
最简单的方法是:
make foo=bar target
然后在你的makefile中你可以参考 $(foo) . 请注意,这不会自动传播到子品牌 .
$(foo)
如果您使用的是子品牌,请参阅此文章:Communicating Variables to a Sub-make
假设您有一个这样的makefile:
action: echo argument is $(argument)
你会称之为 make action argument=something
make action argument=something
来自manual:
make中的变量可以来自运行make的环境 . 在启动时查看的每个环境变量都将转换为具有相同名称和值的make变量 . 但是,makefile中的显式赋值或命令参数会覆盖环境 .
所以你可以做(从bash):
FOOBAR=1 make
导致Makefile中的变量 FOOBAR .
FOOBAR
export ROOT_DIR=<path/value>
然后在Makefile中使用变量 $(ROOT_DIR) .
$(ROOT_DIR)
如果你创建一个名为Makefile的文件并添加一个像$(unittest)这样的变量,那么即使使用通配符,你也可以在Makefile中使用这个变量
例如:
make unittest=*
我使用BOOST_TEST并通过参数--run_test = $(unittest)给出一个通配符然后我将能够使用正则表达式过滤掉我希望我的Makefile运行的测试
这里没有引用的另一个选项包含在Stallman和McGrath的GNU Make书中(参见http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html) . 它提供了一个例子:
archive.a: ... ifneq (,$(findstring t,$(MAKEFLAGS))) +touch archive.a +ranlib -t archive.a else ranlib archive.a endif
它涉及验证给定参数是否出现在 MAKEFLAGS 中 . 例如..假设您're studying about threads in c++11 and you' ve将您的研究划分为多个文件( class01 ,..., classNM ),并且您希望:编译然后单独运行或一次编译一个并在指定标志时运行它(例如 -r ) . 所以,你可以拿出以下 Makefile :
MAKEFLAGS
class01
classNM
-r
Makefile
CXX=clang++-3.5 CXXFLAGS = -Wall -Werror -std=c++11 LDLIBS = -lpthread SOURCES = class01 class02 class03 %: %.cxx $(CXX) $(CXXFLAGS) -o $@.out $^ $(LDLIBS) ifneq (,$(findstring r, $(MAKEFLAGS))) ./$@.out endif all: $(SOURCES) .PHONY: clean clean: find . -name "*.out" -delete
有了这个,你会:
构建并运行一个文件w / make -r class02 ;
make -r class02
build all w / make 或 make all ;
make all
构建并运行所有w / make -r (假设它们都包含某种类型的断言,你只想测试它们)
make -r
7 回答
您有几个选项可以从makefile外部设置变量:
您可能还想设置
-e
选项(又名--environments-override
),您的环境变量将覆盖makefile中的赋值(除非这些赋值本身使用override directive . 但是,'s not recommended, and it'更好更灵活地使用?=
赋值(条件变量)赋值运算符,它只有在尚未定义变量时才有效:):请注意,某些变量不是从环境继承的:
MAKE
来自脚本名称SHELL
要么在makefile中设置,要么默认为/bin/sh
(基本原理:命令在makefile中指定,并且它们是特定于shell的) .From command line -
make
可以将变量赋值作为其命令行的一部分,与目标混合:但是,除非在赋值中使用override directive,否则将忽略makefile中
FOO
变量的所有赋值 . (效果与环境变量的-e
选项相同) .相反,更好的解决方案可能是导出这些变量 . 导出变量使其进入每个shell调用的环境中,并且使用这些命令进行调用将按照上面的指定选择这些环境变量 .
您还可以使用
export
不带参数导出所有变量 .最简单的方法是:
然后在你的makefile中你可以参考
$(foo)
. 请注意,这不会自动传播到子品牌 .如果您使用的是子品牌,请参阅此文章:Communicating Variables to a Sub-make
假设您有一个这样的makefile:
你会称之为
make action argument=something
来自manual:
所以你可以做(从bash):
导致Makefile中的变量
FOOBAR
.然后在Makefile中使用变量
$(ROOT_DIR)
.如果你创建一个名为Makefile的文件并添加一个像$(unittest)这样的变量,那么即使使用通配符,你也可以在Makefile中使用这个变量
例如:
我使用BOOST_TEST并通过参数--run_test = $(unittest)给出一个通配符然后我将能够使用正则表达式过滤掉我希望我的Makefile运行的测试
这里没有引用的另一个选项包含在Stallman和McGrath的GNU Make书中(参见http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html) . 它提供了一个例子:
它涉及验证给定参数是否出现在
MAKEFLAGS
中 . 例如..假设您're studying about threads in c++11 and you' ve将您的研究划分为多个文件(class01
,...,classNM
),并且您希望:编译然后单独运行或一次编译一个并在指定标志时运行它(例如-r
) . 所以,你可以拿出以下Makefile
:有了这个,你会:
构建并运行一个文件w /
make -r class02
;build all w /
make
或make all
;构建并运行所有w /
make -r
(假设它们都包含某种类型的断言,你只想测试它们)