Setting PATH within Makefile on Mac OS X (but it w

2019-07-31 16:48发布

问题:

I'm able to set PATH in a Makefile on Linux but not Mac OS X. With OS X, the PATH gets set but doesn't get used. Here's a demonstration:

On CentOS 6 with bash 4.1.2(1)-release and GNU Make 3.81

$ pwd
/tmp/experiment
$ find * -type f -ls
132133    4 -rw-rw-r--   1 tlim tlim      113 Aug 26 11:01 Makefile
132132    4 -rwxrwxr-x   1 tlim tlim       28 Aug 26 10:59 bin/myprog
$ cat Makefile 
export PATH := $(shell /bin/pwd)/bin:$(PATH)

what:
    @echo PATH=$$PATH
    @echo PATH=$(PATH)
    which myprog
    myprog
$ cat bin/myprog 
#!/bin/bash
echo HERE I AM.
$ make what
PATH=/tmp/experiment/bin:/usr/stack/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
PATH=/tmp/experiment/bin:/usr/stack/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
which myprog
/tmp/experiment/bin/myprog
myprog
HERE I AM.

Here's the exact same files run on a Mac OS X 10.9.4 with GNU Make 3.81:

$ pwd
/tmp/experiment
$ find * -type f -ls
51838886        8 -rw-rw-r--    1 tal              wheel                 113 Aug 26 07:01 Makefile
51838887        8 -rwxrwxr-x    1 tal              wheel                  28 Aug 26 06:59 bin/myprog
$ cat Makefile 
export PATH := $(shell /bin/pwd)/bin:$(PATH)

what:
    @echo PATH=$$PATH
    @echo PATH=$(PATH)
    which myprog
    myprog
$ cat bin/myprog 
#!/bin/bash
echo HERE I AM.
$ make what
PATH=/tmp/experiment/bin:/Users/tal/bin:/opt/local/sbin:/opt/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin
PATH=/tmp/experiment/bin:/Users/tal/bin:/opt/local/sbin:/opt/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin
which myprog
/tmp/experiment/bin/myprog
myprog
make: myprog: No such file or directory
make: *** [what] Error 1

As you can see, the PATH is getting set and exported into the environment. Both "echo $PATH" and "which myprog" show that the path is set. However, when running "myprog" the shell can't find it.

Update: If I add these two lines to the what recipe in the Makefile:

@echo SHELL=$$SHELL
@echo SHELL=$(SHELL)

Both Linux and Mac output:

SHELL=/bin/bash
SHELL=/bin/sh

Both have SHELL equal to /bin/bash in the environment before running make. This makes me think that having SHELL set in Makefile is just magic and is one of the many reason that The GNU Make Manual says to always set SHELL.

回答1:

It turns out the PATH variable is special and isn't exported unless "SHELL" is also set. In other words, if I add this one line to the Makefile it works on both Mac and Linux:

SHELL=/bin/bash

This, of course, makes me wonder why the Mac is different. Hopefully by documenting this here others that see this problem will also benefit. Plus, I'd like to know why the Mac is different, if it really is.