user5184385
user5184385

Reputation:

Shell function in makefile may not work

From the docs:

The 'shell' function performs the same function that backquotes ('`') perform in most shells: it does "command expansion". This means that it takes as an argument a shell command and evaluates to the output of the command. The only processing 'make' does on the result is to convert each newline (or carriage-return / newline pair) to a single space. If there is a trailing (carriage-return and) newline it will simply be removed.

Version 1 of makefile, is:

foo := $(shell echo 'bar'; foo)

all:
    @echo 'foo is: $(foo)'

.PHONY: all

Running, we get:

/bin/sh: 1: foo: not found
bar
foo is: 

Version 2 of makefile, is:

foo := $(shell echo 'bar'; false)

all:
    @echo 'foo is: $(foo)'

.PHONY: all

Running, we get:

foo is: bar

Now, given the above quote from the documentation:

The 'shell' function performs the same function that backquotes ('`') perform in most shells: it does "command expansion".

We try and compare the following:

# Equivalent to version 1 of makefile above.
$ foo=`echo 'bar'; foo`
sh: 1: foo: not found
$ echo ${foo}
bar

# Equivalent to version 2 of makefile above.
$ foo=`echo 'bar'; false`
$ echo ${foo}
bar

So, not only is the shell function not consistent, but it differs from "command expansion" of shells, referenced to, in the docs, cited above!

Is there a rationale behind all this?

Upvotes: 0

Views: 722

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 753585

Converting a comment into a substantiated answer.

The exit status from echo 'bar'; foo is 127; the exit status from echo 'bar'; false is 1. Exit status 127 means that the command failed to execute in some way.

In the comment, I said that my suspicion is that make treats the two exit statuses differently.

When I create makefile.v3 that contains:

foo := $(shell echo 'bar'; exit ${exit})

all:
    @echo 'foo is: $(foo)'

.PHONY: all

and run it as shown:

$ make -f makefile.v3
foo is: bar
$ make -f makefile.v3 exit=0
foo is: bar
$ make -f makefile.v3 exit=1
foo is: bar
$ make -f makefile.v3 exit=127
bar
foo is: 
$ make -f makefile.v3 exit=128
foo is: bar
$ make -f makefile.v3 exit=129
foo is: bar
$ make -f makefile.v3 exit=126
foo is: bar
$ make -f makefile.v3 exit=255
foo is: bar
$

As hypothesized in the comment, the exit status of 127 is treated differently by make.

(For the record: tested with GNU Make 3.81 on Mac OS X 10.10.4.)

Upvotes: 1

Related Questions