I am trying to have my Makefile echo text without the trailing new line, but am unable to. I am experiencing the behavior on OS X (on Linux everything works as expected).
a:
@echo -n "hello"
b:
@echo -n hello
c:
@/bin/echo -n "hello"
Output:
$make a
-n hello
$make b
hello$make c
hello$
In other words, the make a
is broken. What exactly is happening? Is make using a built-in echo? Clearly the presence of the double quotes changes the behavior, but why?
As discovered by @chepner, using the full path to /bin/echo
in the makefile understands the -n flag correctly.
The problem comes from the unfortunate interaction of two facts.
First, make
has two modes of operations depending on the complexity of the recipe to be run:
make
will directly run the recipe with its builtin commands. This is what happens in your b
case.make
will spawn a shell to interpret and run the recipe. This is what happens in your a
case.Second, make
uses /bin/sh
as a shell but the functionality of /bin/sh
is implemented differently on Mac OS X and Linux:
/bin/sh
is implemented by bash
. Also on Mac OS X, bash
is compiled with --enable-strict-posix-default
. One consequence of this flag is that the echo
command does not understand the -n
flag./bin/sh
is implemented by dash
which is less strict with respect to POSIX specification. Therefore the flag -n
is implemented in the echo
command.BTW, the Makefile buitlin echo
command understands the -n
flag which explains why the b
case always works.
The clean and portable way of fixing your problem is to replace your @echo -n
recipes with @printf
recipes.