I have a really simple Makefile
that's doing source
to set ENV variables. But it doesn't work if I call it from Makefile
I get this error
make dev
source ./bin/authenticate.sh
make: source: No such file or directory
make: *** [dev] Error 1
The script exists.
If I run this in command-line it works.
source ./bin/authenticate.sh
Works!
This is my Makefile
test:
pytest -s
dev:
source ./bin/authenticate.sh
I'm using OSX. I'm not sure if this would make a difference.
The makefile is a text file that contains the recipe for building your program. It usually resides in the same directory as the sources, and it is usually called Makefile .
Script written as a Makefile, a developer file type that is used for compiling and linking programs from source code files; stores instructions using the GNU make standard. NOTE: Makefiles more commonly are created with the filename Makefile, which does not have a file extension.
$(shell) is a special function in gmake that runs an external command and captures the output for use in the makefile. For example, you could get the current working directory like this: CWD=$(shell pwd) all: @echo This makefile lives in $(CWD).
tldr; lose the source
, use the dot (.
)
Longer explanation follows...
It doesn't work because make
is looking for a source
program in the $PATH
. This fails because source
is a (non-POSIX) shell builtin, not an executable program on any conventional UNIX-like system.
I was able to replicate failure shown in the question; the following (much abridged) output was generated on Ubuntu 16.04 with GNU Make v4.1:
$ strace -f -s65536 -- make dev 2>&1 | grep 'authenticate'
read(3, "test:\n\tpytest -s\n\ndev:\n\tsource ./bin/authenticate.sh\n", 4096) = 53
write(1, "source ./bin/authenticate.sh\n", 29source ./bin/authenticate.sh
[pid 32100] execve("/usr/local/sbin/source", ["source", "./bin/authenticate.sh"], [/* 82 vars */]) = -1 ENOENT (No such file or directory)
[pid 32100] execve("/usr/local/bin/source", ["source", "./bin/authenticate.sh"], [/* 82 vars */]) = -1 ENOENT (No such file or directory)
[pid 32100] execve("/usr/sbin/source", ["source", "./bin/authenticate.sh"], [/* 82 vars */]) = -1 ENOENT (No such file or directory)
[pid 32100] execve("/usr/bin/source", ["source", "./bin/authenticate.sh"], [/* 82 vars */]) = -1 ENOENT (No such file or directory)
[pid 32100] execve("/sbin/source", ["source", "./bin/authenticate.sh"], [/* 82 vars */]) = -1 ENOENT (No such file or directory)
[pid 32100] execve("/bin/source", ["source", "./bin/authenticate.sh"], [/* 82 vars */]) = -1 ENOENT (No such file or directory)
You can see that make
made six failed attempts to find the source
program; i.e., one for each component of my $PATH
.
If source
is changed to .
, make
changes its strategy; instead of trying to find and execute a program, it just passes the rule body to the system shell:
$ strace -f -s65536 -- make dev 2>&1 | grep 'authenticate'
read(3, "test:\n\tpytest -s\n\ndev:\n\t. ./bin/authenticate.sh\n", 4096) = 48
write(1, ". ./bin/authenticate.sh\n", 24. ./bin/authenticate.sh
[pid 32122] execve("/bin/sh", ["/bin/sh", "-c", ". ./bin/authenticate.sh"], [/* 82 vars */]) = 0
[pid 32122] open("./bin/authenticate.sh", O_RDONLY) = 3
The kind of shell used by make
determines which shell builtins get expanded within each Makefile
rule. You can tell make
to use a shell of your choosing like so:
$ cat Makefile
SHELL = /bin/bash
test:
pytest -s
dev:
source ./bin/authenticate.sh
Since bash
defines the builtin source
as a synonym for .
, the rule using source
now succeeds:
$ strace -f -s65536 -- make dev 2>&1 | grep 'authenticate'
read(3, "SHELL = /bin/bash\ntest:\n\tpytest -s\n\ndev:\n\tsource ./bin/authenticate.sh\n", 4096) = 71
write(1, "source ./bin/authenticate.sh\n", 29source ./bin/authenticate.sh
[pid 32573] execve("/bin/bash", ["/bin/bash", "-c", "source ./bin/authenticate.sh"], [/* 82 vars */]) = 0
[pid 32573] open("./bin/authenticate.sh", O_RDONLY) = 3
References:
do cd bin && source authenticate.sh
it works
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With