从命令行传递额外的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中对FOOvariables的所有赋值都将被忽略 。 (效果与环境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立所有瓦特/ makemake all ;
  • build立并运行所有的w / make -r (假设它们都包含某种特定的断言,而你只是想testing它们)