我可以将变量作为命令行参数传递给GNU Makefile吗?换句话说,我想传递一些最终将成为Makefile中变量的参数。
最简单的方法是:
make foo=bar target
然后在您的makefile中,您可以引用$(foo)。请注意,这不会自动传播到子制作。
$(foo)
如果您正在使用sub-make,请参阅本文:将变量传递给子制造商
假设你有一个这样的makefile:
action:echo argument is $(argument)
你可以叫它make action argument=something
make action argument=something
从手册:
make中的变量可以来自make运行的环境。每个make启动时看到的环境变量都会转换为具有相同名称和值的make变量。但是,makefile中的显式赋值或使用命令参数会覆盖环境。
所以你可以这样做(从bash):
FOOBAR=1 make
在您的Makefile中生成变量FOOBAR。
FOOBAR
您有几个选项可以从makefile外部设置变量:
从环境-每个环境变量都转换为具有相同名称和值的makefile变量。
您可能还想设置-e选项(又名--environments-override),您的环境变量将覆盖在makefile中的赋值(除非这些赋值本身使用#2指令。但是,不推荐这样做,并且使用?=赋值(条件变量赋值操作符,只有在变量尚未定义时才会生效)更好和更灵活:
-e
--environments-override
?=
FOO?=default_value_if_not_set_in_environment
请注意,某些变量不是从环境继承的:
MAKE
SHELL
/bin/sh
从命令行-make可以将变量赋值作为命令行的一部分,与目标混合:
make
make target FOO=bar
然后makefile中#0变量的所有赋值都将被忽略,除非你在赋值中使用#1指令。(效果与环境变量的-e选项相同)。
从父Make导出-如果您从Makefile调用Make,您通常不应该像这样显式编写变量赋值:
# Don't do this!target:$(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
相反,更好的解决方案可能是导出这些变量。导出变量会使其进入每个shell调用的环境中,并且从这些命令进行调用会按照上面指定的方式选择这些环境变量。
# Do like thisCFLAGS=-gexport CFLAGStarget:$(MAKE) -C target
您还可以通过使用不带参数的export导出所有变量。
export
如果您创建一个名为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.aelseranlib archive.aendif
它涉及验证给定参数是否出现在MAKEFLAGS中。例如…假设你正在研究c++11中的线程,并且你已经将研究划分为多个文件(class01,…,classNM),并且你想要:编译所有文件并单独运行,或者一次编译一个并在指定标志的情况下运行它(例如-r)。所以,你可以想出以下Makefile:
MAKEFLAGS
class01
classNM
-r
Makefile
CXX=clang++-3.5CXXFLAGS = -Wall -Werror -std=c++11LDLIBS = -lpthread SOURCES = class01 class02 class03 %: %.cxx$(CXX) $(CXXFLAGS) -o $@.out $^ $(LDLIBS)ifneq (,$(findstring r, $(MAKEFLAGS)))./$@.outendif all: $(SOURCES) .PHONY: clean clean:find . -name "*.out" -delete
有了这个,你会:
make -r class02
make all
make -r
export ROOT_DIR=<path/value>
然后在Makefile中使用变量$(ROOT_DIR)。
$(ROOT_DIR)
似乎命令参数覆盖了环境变量。
创建文件:
send:echo $(MESSAGE1) $(MESSAGE2)
示例运行:
$ MESSAGE1=YES MESSAGE2=NG make send MESSAGE2=OKecho YES OKYES OK