我可以将变量作为命令行参数传递给GNU Makefile吗? 换句话说,我想传递一些最终会成为Makefile变量的参数。
#1楼
如果你创建一个名为Makefile的文件并添加一个像$(unittest)这样的变量,那么即使使用通配符,你也可以在Makefile中使用这个变量
例如:
make unittest=*
我使用BOOST_TEST并通过参数--run_test = $(unittest)给出一个通配符然后我将能够使用正则表达式过滤掉我希望我的Makefile运行的测试
#2楼
最简单的方法是:
make foo=bar target
然后在你的makefile中你可以引用$(foo)
。 请注意,这不会自动传播到子品牌。
如果您正在使用子品牌,请参阅此文章:将变量传递给子品牌
#3楼
假设您有一个这样的makefile:
action:
echo argument is $(argument)
然后你会称之为make action argument=something
#4楼
从手册 :
make中的变量可以来自运行make的环境。 在启动时查看的每个环境变量都将转换为具有相同名称和值的make变量。 但是,makefile中的显式赋值或命令参数会覆盖环境。
所以你可以做(从bash):
FOOBAR=1 make
在Makefile中生成一个变量FOOBAR
。
#5楼
您有几个选项可以从makefile外部设置变量:
从环境 - 每个环境变量都转换为具有相同名称和值的makefile变量。
您可能还需要设置
-e
选项(也称为--environments-override
),并且您的环境变量将覆盖makefile中的赋值(除非这些赋值本身使用override
指令 。但是,不推荐使用它,并且它更好,灵活使用?=
赋值(条件变量赋值运算符,只有在尚未定义变量时才有效):FOO?=default_value_if_not_set_in_environment
请注意,某些变量不是从环境继承的:
-
MAKE
来自剧本名称 -
SHELL
要么设置在makefile中,要么默认为/bin/sh
(理由:命令在makefile中指定,并且它们是特定于shell的)。
-
从命令行 -
make
可以将变量赋值作为其命令行的一部分,与目标混合:make target FOO=bar
但是,除非在赋值中使用
override
指令 ,否则将忽略makefile中FOO
变量的所有赋值。 (效果与环境变量的-e
选项相同)。从父Make导出 - 如果从Makefile调用Make,通常不应该显式写这样的变量赋值:
# 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
不带参数。
#6楼
这里没有引用的另一个选项包含在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
。 例如..假设您正在研究c ++ 11中的线程,并且您已将研究划分为多个文件( class01
,..., classNM
),并且您希望:编译然后编译所有并单独运行或编译一个如果指定了一个标志(例如-r
,则一次运行它。 所以,你可以提出以下Makefile
:
CXX=clang++-3.5
CXXFLAGS = -Wall -Werror -std=c++11
LDLIBS = -lpthread
SOURCES = class01 class02 class03
%: %.cxx
$(CXX) $(CXXFLAGS) -o [email protected] $^ $(LDLIBS)
ifneq (,$(findstring r, $(MAKEFLAGS)))
./[email protected]
endif
all: $(SOURCES)
.PHONY: clean
clean:
find . -name "*.out" -delete
有了这个,你会:
- 构建并运行文件w /
make -r class02
; - 建立所有w /
make
或make all
; - 构建并运行所有w /
make -r
(假设它们都包含某种类型的断言,你只想测试它们)
#7楼
export ROOT_DIR=<path/value>
然后在Makefile中使用变量$(ROOT_DIR)
。