如何在 make comment 中传递命令行参数
How to pass commanline argument near make comment
我为 运行 一个基于 lex 的程序写了这个 makefile:
all: getf lex
getf: gpplex
./gpplex $(ARGS)
lex: gpplex
./gpple
lex.yy.c: gpplex.l
flex gpplex.l
gpplex: lex.yy.c
gcc lex.yy.c -lfl -o gpplex
clean:
rm gpplex
我想修改,如果我 运行 命令 make filename.txt
那么 getf
的规则将 运行,传递 make
参数到程序,但如果我没有为 make
指定任何参数,那么 lex
目标必须 运行.
我怎样才能做到这一点?
完全没有办法做到这一点。
Make 的命令行由make 控制,它不是shell 脚本,您可以在其中传递任何您想要的内容。 make 的每个(非选项)参数要么是 运行 的目标名称,要么是变量赋值(如果它包含 =
)。就这些了。
你可以这样做:
make getf ARGS=filename.txt
或者您可以使用默认规则:
.DEFAULT: gpplex
./gpplex $@
.PHONY: $(MAKECMDGOALS)
哪个应该有效...这告诉 make“对于您不认识的任何目标,运行 此默认规则”。您需要 .PHONY 来强制 make 重建文件,即使它已经存在;如果你不想要,你可以把这个拿出来。
make
将所有非选项参数解释为要构建的目标名称的变量定义,具体取决于它们是否包含 =
字符。如果您没有任何构建这些目标的规则,那么 make
将失败。 POSIX make
不提供您描述的机制,但您可以通过要求用户使用变量定义来接近。所需的 make
命令类似于
make FILE=filename.txt
与之配套的 makefile 可能是
all: gpplex
./gpplex $(FILE)
gpplex: lex.yy.c
gcc lex.yy.c -lfl -o $@
lex.yy.c: gpplex.l
flex gpplex.l
clean:
rm gpplex
.PHONY: all clean
请注意,对于带参数和不带参数的情况,您不需要不同的规则;如果变量 FILE
没有在命令行(或环境中)定义,那么对它的引用将简单地扩展为空。
但是如果您愿意特别依赖 GNU make,那么您可以通过编写模式规则来匹配参数而不使用变量来处理参数:
all: gpplex
./gpplex
# Matches any target name given on the command line, unless it is the name of one of
# the other targets defined in this makefile.
# The FORCE prerequisite ensures that this rule runs even if the target is newer than
# gpplex
%: gpplex FORCE
./gpplex $@
gpplex: lex.yy.c
gcc lex.yy.c -lfl -o $@
lex.yy.c: gpplex.l
flex gpplex.l
# GNU make attempts to remake the makefile. This causes the attempt to do nothing
# instead of triggering the catch-all pattern rule
$(MAKEFILE_LIST):
:
clean:
rm gpplex
FORCE:
.PHONY: all clean FORCE
这有一个小问题,如果用户碰巧指定了为其定义显式规则的目标的名称,则将使用显式规则而不是包罗万象的模式规则。这可以通过将 $(MAKECMDGOALS)
添加到 .PHONY
的先决条件来解决,正如@MadScientist 的回答所建议的那样。
我为 运行 一个基于 lex 的程序写了这个 makefile:
all: getf lex
getf: gpplex
./gpplex $(ARGS)
lex: gpplex
./gpple
lex.yy.c: gpplex.l
flex gpplex.l
gpplex: lex.yy.c
gcc lex.yy.c -lfl -o gpplex
clean:
rm gpplex
我想修改,如果我 运行 命令 make filename.txt
那么 getf
的规则将 运行,传递 make
参数到程序,但如果我没有为 make
指定任何参数,那么 lex
目标必须 运行.
我怎样才能做到这一点?
完全没有办法做到这一点。
Make 的命令行由make 控制,它不是shell 脚本,您可以在其中传递任何您想要的内容。 make 的每个(非选项)参数要么是 运行 的目标名称,要么是变量赋值(如果它包含 =
)。就这些了。
你可以这样做:
make getf ARGS=filename.txt
或者您可以使用默认规则:
.DEFAULT: gpplex
./gpplex $@
.PHONY: $(MAKECMDGOALS)
哪个应该有效...这告诉 make“对于您不认识的任何目标,运行 此默认规则”。您需要 .PHONY 来强制 make 重建文件,即使它已经存在;如果你不想要,你可以把这个拿出来。
make
将所有非选项参数解释为要构建的目标名称的变量定义,具体取决于它们是否包含 =
字符。如果您没有任何构建这些目标的规则,那么 make
将失败。 POSIX make
不提供您描述的机制,但您可以通过要求用户使用变量定义来接近。所需的 make
命令类似于
make FILE=filename.txt
与之配套的 makefile 可能是
all: gpplex
./gpplex $(FILE)
gpplex: lex.yy.c
gcc lex.yy.c -lfl -o $@
lex.yy.c: gpplex.l
flex gpplex.l
clean:
rm gpplex
.PHONY: all clean
请注意,对于带参数和不带参数的情况,您不需要不同的规则;如果变量 FILE
没有在命令行(或环境中)定义,那么对它的引用将简单地扩展为空。
但是如果您愿意特别依赖 GNU make,那么您可以通过编写模式规则来匹配参数而不使用变量来处理参数:
all: gpplex
./gpplex
# Matches any target name given on the command line, unless it is the name of one of
# the other targets defined in this makefile.
# The FORCE prerequisite ensures that this rule runs even if the target is newer than
# gpplex
%: gpplex FORCE
./gpplex $@
gpplex: lex.yy.c
gcc lex.yy.c -lfl -o $@
lex.yy.c: gpplex.l
flex gpplex.l
# GNU make attempts to remake the makefile. This causes the attempt to do nothing
# instead of triggering the catch-all pattern rule
$(MAKEFILE_LIST):
:
clean:
rm gpplex
FORCE:
.PHONY: all clean FORCE
这有一个小问题,如果用户碰巧指定了为其定义显式规则的目标的名称,则将使用显式规则而不是包罗万象的模式规则。这可以通过将 $(MAKECMDGOALS)
添加到 .PHONY
的先决条件来解决,正如@MadScientist 的回答所建议的那样。