从命令行传递额外的variables
我可以将variables作为命令行parameter passing给GNU Makefile吗? 换句话说,我想传递一些参数,最终将成为Makefile中的variables。
你有几个选项来设置makefile外部的variables:
-
从环境 – 每个环境variables被转换成具有相同名称和值的makefilevariables。
你也可以设置
-e
选项(aka--environments-override
),你的环境variables将覆盖makefile中的赋值(除非这些赋值本身使用了override
指令 ,但是这不是build议的,它更好,灵活使用?=
赋值(条件variables赋值运算符,只有在variables尚未定义时才有效):FOO?=default_value_if_not_set_in_environment
请注意,某些variables不能从环境中inheritance:
-
MAKE
是从脚本的名字中获得的 -
SHELL
可以在makefile中设置,或者默认为/bin/sh
(基本原理:命令在makefile中指定,它们是shell专用的)。
-
-
从命令行 –
make
可以将variables赋值作为其命令行的一部分,与目标混合在一起:make target FOO=bar
但是,除非在赋值中使用
override
指令 ,否则在makefile中对FOO
variables的所有赋值都将被忽略 。 (效果与环境variables的-e
选项相同)。 -
从父级Make导出 – 如果从Makefile调用Make,通常不应该像这样显式编写variables赋值:
# Don't do this! target: $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
相反,更好的解决scheme可能是导出这些variables。 导出variables使其进入每个shell调用的环境中,并且从这些命令进行调用,如上所述select这些环境variables。
# Do like this CFLAGS=-g export CFLAGS target: $(MAKE) -C target
您也可以通过使用不带参数的导出来导出所有variables。
最简单的方法是:
make foo=bar target
然后在你的makefile中你可以引用$(foo)
。 请注意,这不会自动传播到子版本。
如果您使用子版本,请参阅此文章:将variables传递给子版本
假设你有这样的makefile:
action: echo argument is $(argument)
然后你会把它叫做make action argument=something
从手册 :
make中的variables可以来自make的运行环境。 每个启动时看到的环境variables都会被转换成具有相同名称和值的makevariables。 但是,makefile或命令参数中的显式赋值会覆盖环境。
所以你可以做(从bash):
FOOBAR=1 make
导致Makefile中的variablesFOOBAR
。
如果你创build一个名为Makefile的文件并添加一个像这样的variables$(unittest),那么即使使用通配符,你也可以在Makefile中使用这个variables
例如:
make unittest=*
我使用BOOST_TEST,并通过给参数–run_test = $(unittest)通配符,然后我将能够使用正则expression式过滤掉我想要我的Makefile运行的testing
export ROOT_DIR=<path/value>
然后使用Makefile中的variables$(ROOT_DIR)
。
还有另外一个选项,这个选项在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
它涉及validation给定的参数是否出现在MAKEFLAGS
。 举个例子..假设你正在学习关于c ++ 11中的线程,并且已经把你的学习分成了多个文件( class01
,…, classNM
),并且你想要:编译然后all并且单独运行或者编译一个并且如果指定了一个标志(例如-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
有了这些,你会:
- build立并运行一个文件w /
make -r class02
; - build立所有瓦特/
make
或make all
; - build立并运行所有的w /
make -r
(假设它们都包含某种特定的断言,而你只是想testing它们)