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 - 在错误位置创建的目录