在 NMake 中测试文件是否存在

问题描述 投票:0回答:4

在 GNU Make 的 makefile 中,我使用这个惯用法来测试文件是否存在:

static:
ifeq ($(wildcard $(FileName)),)
    # do something when the file doesn't exist
else
    # do something different when it does
endif

但它在 NMake 中不起作用(

fatal error U1000: syntax error : ')' missing in macro invocation
)。我该如何更换它?如果替换在两个构建系统中都有效,那就完美了。

makefile nmake
4个回答
10
投票

Nmake 可以运行预处理器指令:

http://msdn.microsoft.com/en-us/library/7y32zxwh.aspx

条件可能会有所不同,但 Exists() 是其中之一:

http://msdn.microsoft.com/en-us/library/8t2e8d78.aspx

!IF EXISTS(foo.txt)

最后使用命令行,http://msdn.microsoft.com/en-us/library/wkxa7sac.aspx

!IF [cmd /C IF NOT EXIST "foo.txt" exit 1]

无论哪种方式,这都应该可以工作,使用上面的 !IF 是完整的示例:

!IF !EXISTS(foo.txt)
!ERROR Unable to locate foo.
!ELSE
!MESSAGE I Found foo!
!ENDIF

8
投票

为了补充 Jack Kelly 的建议,您可以在 CMD.EXE shell 中测试是否存在。 NMake 还包括创建临时 .cmd 文件并执行它的功能。

这是 (n)makefile 语法的示例,我将其用于“检查语法”目标。它通过执行编译来检查多文件项目中单个 C# 源文件中的语法。

check-syntax :
    <<flymake-build.cmd  $(CS_SOURCE)
SETLOCAL ENABLEDELAYEDEXPANSION
set errorlevel=
for %%I in (%*) do if NOT x%%I == x$(FLYMAKE_ORIGINAL) (
   set filesToBuild=!filesToBuild! %%I
)
$(_CSC) /t:module $(LIBSREF) $(FLYMAKE_CHECK) !filesToBuild!
ENDLOCAL && exit /b %errorlevel%
<<

“flymake-build.cmd”是创建的临时cmd文件的名称。双尖括号 (

<<
) 表示在执行文件之前进入临时文件的内容的开头和结尾。

第一行文件名

之后的内容是传递给 .cmd 文件的参数。在此示例中,参数是名为 CS_SOURCE 的 makefile 变量的内容。就我而言,这只是项目中的文件名列表。 Makefile 变量也将在临时文件的文本中展开。你可以看到我指的是编译器(

_CSC
)和一些其他符号。

在 .cmd 代码中,您可以执行 for 循环、if 语句等任何您喜欢的操作。这是一个常规的 .cmd 文件。

如果您希望nmake响应.cmd文件中的命令生成的错误(例如,终止构建),那么您需要使用

exit /b

方法来结束cmd。


我在某个黑暗的角落找到了这方面的文档,所以我想我应该在这里分享它以进行一般说明。 (

编辑

这是链接。)


2
投票


2
投票

static: @if test -f $(FileName); then \ echo something; \ else \ echo some other thing; \ fi

注意各处的续行标记。

如果您需要在

CMD.EXE

中执行此操作,那么也许您可以使用

IF EXIST $(FileName) COMMAND ELSE COMMAND
构造执行类似操作。
    

© www.soinside.com 2019 - 2024. All rights reserved.