【问题标题】:How to pass commanline argument near make comment如何在cmake注释中传递命令行参数
【发布时间】:2020-11-12 18:52:58
【问题描述】:

我为运行基于 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 参数传递给程序,但如果我没有为@987654325 指定任何参数@ 然后lex 目标必须运行。

我怎样才能做到这一点?

【问题讨论】:

    标签: makefile gnu-make flex-lexer lex


    【解决方案1】:

    完全没有办法做到这一点。

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

    你可以这样做:

    make getf ARGS=filename.txt
    

    您也可以使用默认规则:

    .DEFAULT: gpplex
            ./gpplex $@
    
    .PHONY: $(MAKECMDGOALS)
    

    应该可以工作...这告诉 make“对于您不认识的任何目标,运行此默认规则”。即使文件已经存在,您也需要 .PHONY 强制 make 重建文件;如果你不想这样,你可以把它拿出来。

    【讨论】:

      【解决方案2】:

      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
      

      这有一个小问题,如果用户碰巧指定了定义了显式规则的目标的名称,那么将使用显式规则而不是包罗万象的模式规则。正如@MadScientist 的回答所暗示的,这可以通过将$(MAKECMDGOALS) 添加到.PHONY 的先决条件来解决。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-22
        • 2016-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-25
        • 1970-01-01
        • 2020-08-27
        相关资源
        最近更新 更多