在Windows上使用Make时,`echo.`命令失败。

3

背景

我正在尝试编写一个半可移植的Makefile,将在没有MinGW或Cygwin的Windows上使用。因此,我基本上必须坚持Windows提供的标准命令。我知道UnxUtils,但我想尽可能避免使用它们。此外,如果可以的话,我想避免编写任何特殊的批处理脚本。该解决方案将由许多不熟悉Linux、Windows或命令行构建系统的人在许多不同的计算机上使用,因此不能依赖环境路径并且无法进行其他安装。该解决方案将替换一个现有系统,在某些越来越需要的高级制作系统功能方面存在严重缺陷,因此我正在尝试通过避免任何新软件安装来最小化更改的影响。

问题

我遇到的问题与make如何解释用作规则一部分的shell命令有关。我只想以可以作为几个不同规则的一部分被重定向到文件中的方式echo空行。在Windows中,唯一的方法是在echo命令之后立即添加一个.,没有任何空格:echo.。 然而,在规则中提供时,它会引起问题。

some_rule :
   @echo.
   @echo Text going to file > someFile.txt
   @echo. >> someFile.txt
   @echo Other text going to a file >> someFile.txt
   

在提供的例子中,第一行@echo.和第三行@echo. >> someFile.txt会导致一个错误:
process_begin: CreateProcess(NULL, echo., ...) failed.

我看到有些解释说第三行不应该有空格,而应该是@echo.>> someFile.txt,但是当我测试时没有任何区别。

解释

我非常确定问题出在make实现了隐式shell命令的手动查找,并将echo.检测为命令而不是echo。结果的错误是它没有找到echo..exe或等效的命令或可执行文件在环境路径中,从而触发上述错误。

问题

如何在makefile规则的一部分中实现一个命令以输出一个空行,使其在上面的情况下工作?我的实际makefile看起来更像以下内容,并希望替换ECHO变量,使其更像echo的Linux版本,或替换NEWLINE变量,以便以允许将其打印到终端或重定向到文件。

NEWLINE=echo.
ECHO=echo
SILENT=@

some_rule :
   $(SILENT)$(NEWLINE)
   $(SILENT)$(ECHO) Text going to file > someFile.txt
   $(SILENT)$(NEWLINE) >> someFile.txt
   $(SILENT)$(ECHO) Other text going to a file >> someFile.txt

我花了一些时间研究后发现,如果我在当前目录下创建一个名为echo..bat的文件,其中只包含一行echo.,那么就不会从makefile中得到错误。这表明我对makefile出错原因的分析是正确的。不幸的是,这个解决方案实际上会导致一个无限循环,因为echo..bat文件会无限递归调用自身,所以这不是一个可行的解决方案。 - mtalexan
3个回答

7

我会写可移植的Makefiles和脚本。您无需再次编写脚本即可实现所需功能。只要在任何一个上下文中使用语法正确的内容,就可以达到您想要的效果。

echo;

这将在Windows的NMake和Unix或Gnu make中的Bash或sh文件中都输出一个空行。这就是您需要的全部吗?

我简直不敢相信我没有想到这个。那绝对解决了我的问题。 - mtalexan

1
如果您可以在工作目录中创建一个只包含单个空白行的文本文件,那么more blank.txt将以合理的与操作系统无关方式显示该空白行。
此外,我刚刚发现this,它可能会有所帮助。我认为您可以创建自己的echo..bat批处理文件,但是给它以下内容:
@echo off
echo[

如何在Windows批处理和Linux Bash中运行单个脚本?

或者,忘记脆弱的echo..bat想法,制作一个名为blank.bat的通用shell脚本/批处理文件:

:; echo ""
:<<"::CMDLITERAL"
@echo.
::CMDLITERAL

我在Windows中创建了这个文件,然后将其复制到Linux和OSX中。通过正确的权限设置,它将在所有三个操作系统中输出一个空行!

我感到有点愚钝,因为没有想到使用其他替代方法来执行echo..bat脚本并防止无限递归调用自身,但这最终成为了最好的解决方案。我真的很喜欢Windows批处理和Linux Bash信息。我不太关心生成自定义操作系统特定的脚本,将其设置为命令,我只会将其纳入makefile配置体系中,从独立于操作系统的makefile中调用操作系统特定的目标来设置和清理任何系统生成的脚本。 - mtalexan
似乎 echo/ 也可以用来输出单个换行符。 - David R Tribble
@DavidRTribble 在Linux上 echo/ 将会出现 bash: echo/: 没有那个文件或目录 的错误提示。 - Bo R

0

我也遇到了非常类似的错误。我发现问题出在 PATH 环境变量中,我的 PATH 变量中有一个空条目。

PATH=<path1>;;<path2>

只需删除第二个分号,就可以消除错误。 我认为根本原因在于“CreateProcess”和“SearchPath”API。当搜索可执行文件时,它无法处理空条目。虽然不确定是否100%正确。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接