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).
echo is a bash shell builtin, but when you run it from makefile, it is the program version
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.
Something about the quotes confuses make
. Your code behaves the same for me, but the following works as expected:
help:
@echo -n Shouldn\'t print a newline
Hardcoding the path to the executable also works:
help:
@/bin/echo -n "Shouldn't print a newline"
The Mac OS X man page for echo
, while discussing the existence of shell built-in echo
s, mentions that the echo
of sh(1)
does not support the -n
option, but that fails to explain (to me, anyway) why my first alternative works.
Confirmation that make
is using sh
to execute the commands by default. In
SHELL = bash
help:
@echo -n "Shouldn't print a newline"
@echo -n Shouldn\'t print a newline
both echo statements behave the same (no newlines printed). So without that variable, we have bash
pretending to be sh
, but evaluating the two lines differently. Question 1: why? Question 2: is the second line the native bash
echo or /bin/echo
, rather than the emulated sh
echo
?