NMake 在使用 $(shell) 时返回错误

Posted

技术标签:

【中文标题】NMake 在使用 $(shell) 时返回错误【英文标题】:NMake returns error when using $(shell) 【发布时间】:2014-09-17 21:23:51 【问题描述】:

我是 nmake 的新手,需要修改构建脚本。我想执行一个命令并将结果捕获到一个变量中,然后将在整个脚本中使用该变量。但是,当尝试使用 shell 命令时,我收到以下错误消息:

makefile(4) : fatal error U1000: syntax error : ')' missing in macro invocation
Stop.

我整理了一个单行脚本来测试 shell 命令。

生成文件:

CMDRESULT = $(shell hostname)

all:
    echo $(CMDRESULT)

这里是使用的nmake版本:

>nmake /?

Microsoft (R) Program Maintenance Utility Version 11.00.60610.1
Copyright (C) Microsoft Corporation.  All rights reserved.

nmake 是否支持 shell 命令? nmake 中是否还有其他选项可以执行命令并捕获结果?

【问题讨论】:

请注意,nmake 只有 5 个关注者。最好为 Windows 和可能的 Powershell 添加标签,以获得了解问题的人的帮助。其他人可能会推荐更好的标签,这只是我的 80%Linux-20%Windows 世界观 ;-) ...祝你好运。 感谢您的建议。 【参考方案1】:

如果输出包含单行文本,则可以使用临时文件将另一个程序输出读取到 nmake 变量中。也可以使用外部脚本来修改多行输出并使该解决方案有效。将单行输出读取到 nmake 变量的示例:

!IF [hostname>hostname.tmp] == 0
H_NAME = \
!INCLUDE hostname.tmp
!IF [del hostname.tmp] == 0
!ENDIF
!ENDIF

这个[for execution]用来执行一些命令,比较程序的return code。它是在预处理期间完成的。在此处描述的 hack 之后,"Can't figure out how to read file from nmake" 用于从临时文件中读取一行。

【讨论】:

如果您从!INCLUDE 行中删除<> 可能会更安全? 也许rm 应该是del【参考方案2】:

没有。 Microsoft NMAKE 不能调用函数(如 shell)。 $ 运算符仅扩展 Nmake 变量。

Shell 也不是标准的 make 内置。这是一个 gnu make 扩展。

Nmake 只允许以两种方式调用(shell)命令,或者作为构建的一部分执行的命令,或者在预处理期间执行。如果在预处理期间调用,则只能返回退出代码。

您可以执行以下操作:

!IF [..dos command..] != 0 
   command
!ENDIF

或者你可以这样做:

all: 
   if comparison command

调用命令并与字符串进行比较的 DOS/Windows 命令并非微不足道,而是一个单独的问题。

更新:

我只是想展示一个如何实际实现这一目标的示例,因为我的原始答案有点简洁:

虽然这是一个老问题,但有一种方法可以解决所问的问题;它只是令人费解,就像批处理文件中的所有内容一样!

必须使用 make 导入环境变量和预处理器可以调用命令,然后递归调用 Makefile 的组合机制。它假定 Makefile 被称为 Makefile(没有扩展名,这是默认的)。

!IFNDEF MAKE
MAKE=NMAKE
!ENDIF
!IFNDEF SHELLVALUE
!   IF [echo off && FOR /F "usebackq" %i IN (`hostname`) DO  SET SHELLVALUE=%i && $(MAKE)  /$(MAKEFLAGS) /nologo /f $(MAKEDIR)\Makefile && exit /b  ] == 0
!     MESSAGE Make completed
!   ELSE
!     ERROR Error in nmake
!   ENDIF
!ELSE
# $(SHELLVALUE) now contains the string returned from the command USERNAME
!MESSAGE Shellvalue is $(SHELLVALUE)
#      Put the parts of the makefile that depend on SHELLVALUE here
!ENDIF
#
# To be a valid makefile it must have some rules to perform
all:
     @echo;$(SHELLVALUE)

是的,我知道这很可怕,但它确实演示了如何使用该技术,可以使用任何 shell 命令来完成,而不仅仅是 hostname

【讨论】:

来自 Sandman 现在已删除的答案:上述解决方案没有(据我所知,不能)将目标名称传递给递归 make,因为它不是 $(MAKEFLAGS )。因此,如果您有一个包含多个目标的重要 makefile,并在命令行上执行“nmake clean”之类的操作,您将使用默认目标(可能不是“clean”)调用“nmake”。 谢谢。我将再次使用我的示例,看看我能想出什么!

以上是关于NMake 在使用 $(shell) 时返回错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 nmake 为 VS2010 构建 Qt 返回链接错误

NMAKE:致命错误 U1077:“cl.exe”:返回代码“0x1”停止。在命令提示符下

使用 nmake 构建 wxWidgets 3.0.0 - 在错误位置创建的目录

收到错误:尝试创建/迁移/运行时在路径中找不到“nmake”

如何让 nmake 克服错误(make -k 的行为)

“NMAKE:致命错误 u1073”的修复方法是啥?