Search code examples
windowsbuildmakefile

`echo.` Fails in Make on Windows


Background

I'm attempting to write a semi-portable Makefile that will be used on Windows without MinGW or Cygwin. As a result I pretty much have to stick to standard commands provided by Windows. I'm aware of UnxUtils, but I'd like to avoid using them as much as possible. Additionally, I'd like to avoid having to write any special batch scripts if I can help it. The solution will be used on many different computers by people that aren't particularly familiar with Linux, Windows, or command-line build systems, so environment paths can't be relied on and additional installations aren't possible. The solution will replace an existing system that's severely lacking in some of the more advanced make system features which are approaching necessity so I'm trying to minimize impact of changes by avoiding any new software installs.

Problem

The problem I'm encountering has to do with how make interprets shell commands used as part of a rule. I simply want to echo a blank-line in a way that can also be redirected to a file as part of a few different rules. In Windows, the only way to echo a blank line is to add a . immediately after the echo command, without any spaces: echo.. When provided as a line in a rule it causes issues though.

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

In the example provided, the first line @echo. and the third line, @echo. >> someFile.txt, cause an error:

process_begin: CreateProcess(NULL, echo., ...) failed.

I've seen some explanations that say there shouldn't be a space on the third line and it should instead be @echo.>> someFile.txt, but that makes no difference when I tested it.

Explanation

I'm pretty sure the issue comes from the fact that make implements a manual look up of the implicit shell command and is detecting echo. as the command rather than echo. The resulting error is that it didn't find echo..exe or the equivalent as either a command or executable in the environment path, triggering the error indicated above.

Question

How do I implement a command as part of a makefile rule to output a blank line such that it would work in the case above? My actual makefile looks more like the following, and I'm hoping to replace either the ECHO variable so it operates more like the Linux version of echo, or the NEWLINE variable so it can actually output a blank line in a way that allows it to either be printed to the terminal or redirected to a file.

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

Solution

  • I write both portable Makefiles and portable scripts. You can achieve what you desire without making another script. You can just use something which is syntactically correct in either context.

    echo;
    

    This will echo a blank line in both Batch files on Windows in NMake and in Bash or sh on unix or Gnu make. Surely that is all you need?