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 echos, 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?