在 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
)。我该如何更换它?如果替换在两个构建系统中都有效,那就完美了。
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
为了补充 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。
我在某个黑暗的角落找到了这方面的文档,所以我想我应该在这里分享它以进行一般说明。 (编辑
static:
@if test -f $(FileName); then \
echo something; \
else \
echo some other thing; \
fi
注意各处的续行标记。
如果您需要在
CMD.EXE
中执行此操作,那么也许您可以使用
IF EXIST $(FileName) COMMAND ELSE COMMAND
构造执行类似操作。