我可以将变量作为命令行参数传递给GNUMakefile吗?换句话说,我想传递一些参数,这些参数最终将成为Makefile中的变量。


当前回答

根据手册:

make中的变量可以来自运行make的环境。make启动时看到的每个环境变量都被转换为具有相同名称和值的make变量。但是,makefile中的显式赋值或带有命令参数的赋值会覆盖环境。

所以你可以(从bash):

FOOBAR=1 make

在Makefile中生成变量FOOBAR。

其他回答

根据手册:

make中的变量可以来自运行make的环境。make启动时看到的每个环境变量都被转换为具有相同名称和值的make变量。但是,makefile中的显式赋值或带有命令参数的赋值会覆盖环境。

所以你可以(从bash):

FOOBAR=1 make

在Makefile中生成变量FOOBAR。

假设你有一个这样的makefile:

action:
    echo argument is $(argument)

然后你可以称之为make action argument=something

还有一个选项没有在这里引用,它被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 $@.out $^ $(LDLIBS)
ifneq (,$(findstring r,  $(MAKEFLAGS)))
    ./$@.out
endif

all: $(SOURCES)

.PHONY: clean

clean:
    find . -name "*.out" -delete

有了它,你会:

构建并运行一个带有make-r class02的文件;全部建造或全部建造;构建并运行所有w/make-r(假设它们都包含某种断言内容,您只想测试它们)

如果您创建一个名为Makefile的文件,并添加一个类似于$(unittest)的变量那么即使使用通配符,也可以在Makefile中使用该变量

例子:

make unittest=*

我使用BOOST_TEST,并为参数--run_TEST=$(unittest)提供通配符然后我将能够使用正则表达式过滤掉我想要的Makefile测试运行

似乎命令args覆盖了环境变量。

生成文件:

send:
    echo $(MESSAGE1) $(MESSAGE2)

示例运行:

$ MESSAGE1=YES MESSAGE2=NG  make send MESSAGE2=OK
echo YES OK
YES OK