将 nmake 与通配符目标一起使用

Using nmake with wildcarded targets

使用 nmake 我有以下生成文件,它目前正在执行我需要它执行的操作。 mycmd(程序为 运行)将获取一个 .inp 文件并生成一个 .out 文件。我可以根据需要制作尽可能多的 .inp 文件,而且 makefile 不必更改。它将全部找到它们并制作所有相关的 .out 文件。

#####################################################################################
# A SUFFIXES declaration is required in order to later use the rule with target .inp.out
#####################################################################################
.SUFFIXES: .inp

#####################################################################################
# Here, NMAKE will expand *.inp in the prereq list for all, into the list of *.inp
# files in the directory, and then it will start a new NMAKE instance, specifying the
# goals to build all those files.
#####################################################################################
all: *.inp
  $(MAKE) $(**:.inp=.out)

#####################################################################################
# $(*B) represents the current target's base name minus the path and the file extension
#####################################################################################
.inp.out:
  mycmd -i $(*B).inp -o $(*B).out

我的问题是,如何进一步增强此 makefile,以便我可以 运行 它用于一组 .inp 文件,所以不是 *.inp 而是说, ABC*.inp?

对您的 makefile 进行简单修改即可。添加新的 $(pattern) 宏:

.SUFFIXES: .inp

pattern = *                             # new macro; defaults to *

all: $(pattern).inp                     # use it!
  @$(MAKE) -nologo $(**:.inp=.out)

.inp.out:                               # dummy stub for testing
  @echo mycmd -i $(*B).inp -o $(*B).out
  @type NUL > $(*B).out

然后在命令行中覆盖pattern。例如,nmake -nologo pattern=ABC*.


更新: makefile 中的命令行:

  $(MAKE) $(**:.inp=.out)
如果字符串 $** 太长,

将失败并返回 fatal error U1095: expanded command line ... too long。在我的系统上,这种情况发生在大约 32800 个字符处。

开头加感叹号!(见here)好像不行,可能是没有简单的$**。有两种解决方法:

  !call set a=$** & call nmake %%a:.inp=.out%%

或:

  !for %a in ($**) do nmake -nologo %~na.out

这些都比你原来的慢两倍左右,有一个什么都不做的 mycmd 存根。 (这里的 for 循环并不是真正的循环,因为 $** 只是一个单项。)

另一种解决方案是保留原始 makefile,并使用 DOS 命令,例如:

for %a in (ABC*.inp) do nmake -nologo %~na.out

这里的语法 %~na 删除了变量 %a 的扩展名。

这比仅使用 makefile 稍慢,但不会慢很多。例如,对于 600 个 inp 文件和一个 mycmd 存根,在我的系统上此命令需要 20 秒,而 makefile 需要 15 秒。