Hi, Trying the following makefile: test: command -v ls I get the following result: $ make command -v ls make: command: Command not found make: *** [test] Error 127 $ sh -c 'command -v ls' /bin/ls but POSIX sayeth | An execution line is built from the command line by removing any | prefix characters. Except as described under the at-sign prefix, the | execution line shall be written to the standard output, optionally | preceded by a <tab>. The execution line shall then be executed by a | shell as if it were passed as the argument to the system( ) interface, | except that the shell −e option shall also be in effect. The cause is that "make" expects to be run on a POSIX system, where non-special shell builtins like "command" would be available for use by execvp (see sh_cmds[] in job.c). See the explanation by Jilles Tjoelker at http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=43;bug=436466 for more details. I can imagine two fixes, and both seem separately valuable: a. one hand hand, introducing a new package to provide those non-special builtins that are not provided by some pseudo-essential package (using alternatives to deal with alternative implementations where necessary): #!/bin/sh command -p ${0##*/} "$@" b. on the other hand, teaching "make" to handle ENOENT from execvp by falling back to the shell. (The shell can print a message about it if that ENOENT was actually due to a missing shared library or interpreter.) This way, "make" could even use shell builtins that are not mandated by POSIX when the system shell happens to implement them. This report is about (b). Thoughts?
URL:
<http://savannah.gnu.org/bugs/?47171>
Summary: please fall back to system() when command is not
found on $PATH
Project: make
Submitted by: srivasta
Submitted on: Tue 16 Feb 2016 02:34:37 PM CST
Severity: 3 - Normal
Item Group: Enhancement
Status: None
Privacy: Public
Assigned to: None
Open/Closed: Open
Discussion Lock: Any
Component Version: None
Operating System: None
Fixed Release: None
Triage Status: None
If you had stated that the bug is that the ".POSIX" target doesn't conform to
this (from make info):
`.POSIX'
If `.POSIX' is mentioned as a target, then the makefile will be
parsed and run in POSIX-conforming mode. This does _not_ mean
that only POSIX-conforming makefiles will be accepted: all advanced
GNU `make' features are still available. Rather, this target
causes `make' to behave as required by POSIX in those areas where
`make''s default behavior differs.
In particular, if this target is mentioned then recipes will be
invoked as if the shell had been passed the `-e' flag: the first
failing command in a recipe will cause the recipe to fail
immediately.
Then I think you'd be right. In fact, in adding ".POSIX:" to your makefile
_still_ results in the same error, so I would classify the bug as belonging
to the .POSIX target failure to act "as if the shell had been passed the `-e'
flag".
Note that trying your makefile with "SHELL := /bin/sh -e" does result in the
expected behavior, though its only a w/a.
If you had stated that the bug is that the ".POSIX" target doesn't conform to
this (from make info):
`.POSIX'
If `.POSIX' is mentioned as a target, then the makefile will be
parsed and run in POSIX-conforming mode. This does _not_ mean
that only POSIX-conforming makefiles will be accepted: all advanced
GNU `make' features are still available. Rather, this target
causes `make' to behave as required by POSIX in those areas where
`make''s default behavior differs.
In particular, if this target is mentioned then recipes will be
invoked as if the shell had been passed the `-e' flag: the first
failing command in a recipe will cause the recipe to fail
immediately.
Then I think you'd be right. In fact, in adding ".POSIX:" to your makefile
_still_ results in the same error, so I would classify the bug as belonging to
the .POSIX target failure to act "as if the shell had been passed the `-e' flag".
Note that trying your makefile with "SHELL := /bin/sh -e" does result in the
expected behavior, though its still a bug.
URL:
<https://savannah.gnu.org/bugs/?58420>
Summary: PATH changes are not applied in $(shell) function
Project: make
Submitted by: srivasta
Submitted on: Wed 20 May 2020 06:21:52 PM CDT
Severity: 3 - Normal
Item Group: Bug
Status: None
Privacy: Public
Assigned to: None
Open/Closed: Open
Discussion Lock: Any
Component Version: 4.3
Operating System: None
Fixed Release: None
Triage Status: None
--- BEGIN ---
PATH := /nonexistent:$(PATH)
default:
@echo "make variable PATH=$(PATH)"
@echo "in target commands, PATH=$$PATH"
@echo "in \$$(shell commands), PATH=$(shell echo "$$PATH")"
--- END ---
'make' generates the output for me:
make variable
PATH=/nonexistent:/home/ben/bin:/usr/lib/ccache:/usr/local/sbin:/usr/sbin:/sbin:/home/ben/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
in target commands,
PATH=/nonexistent:/home/ben/bin:/usr/lib/ccache:/usr/local/sbin:/usr/sbin:/sbin:/home/ben/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
in $(shell commands),
PATH=/home/ben/bin:/usr/lib/ccache:/usr/local/sbin:/usr/sbin:/sbin:/home/ben/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
I can't see any documentation that says the PATH variable is special, so I
think this is a bug. I would guess that make defers evaluating the PATH
variable into the environment, in case it's recursively expanded, but only
re-evaulates it before running target commands.
Ben.