Makefile 如何在makecomment附近传递commanline参数

Makefile 如何在makecomment附近传递commanline参数,makefile,gnu-make,flex-lexer,lex,Makefile,Gnu Make,Flex Lexer,Lex,我编写这个makefile是为了运行基于lex的程序: 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 我想修改它,如果我运行命令makefilename.txt,那么

我编写这个makefile是为了运行基于lex的程序:

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
我想修改它,如果我运行命令
makefilename.txt
,那么
getf
的规则将运行,将
make
参数传递给程序,但是如果我没有为
make
指定任何参数,那么
lex
目标必须运行


我怎样才能做到这一点呢?

确切地说,没有办法做到这一点

Make的命令行由Make控制,它不是一个shell脚本,您可以在其中传递任何您想要的内容。要生成的每个(非选项)参数要么是要运行的目标的名称,要么是变量赋值(如果它包含
=
)。就这些

您可以这样做:

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
这有一个小问题,如果用户碰巧指定了定义了显式规则的目标的名称,那么将使用显式规则,而不是catch-all模式规则。正如@MadScientist的回答所示,可以通过在
.PHONY
的先决条件中添加
$(MAKECMDGOALS)
来解决这个问题