I’m experiencing some weird permission denied errors that I have no idea where could be coming from.
$ go run .
Hello from go
$ make run
go run .
make: go: Permission denied
make: *** [Makefile:2: run] Error 127
$ make run2
echo "Make says hello" ; go run .
Make says hello
Hello from go
$ cat Makefile
run:
go run .
run2:
echo "Make says hello" ; go run .
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("Hello from go")
}
My terminal is bash running on Ubuntu 22.04.
What is the difference between my run
target and running go directly that can cause a permission denied error?
What’s the difference between run
and run2
that allow it to work in one but not in the other?
EDIT: Running make with -d
/ --trace
$ make -d run
<...snip...>
No need to remake target 'Makefile'.
Updating goal targets....
Considering target file 'run'.
File 'run' does not exist.
Finished prerequisites of target file 'run'.
Must remake target 'run'.
go run .
make: go: Permission denied
make: *** [Makefile:2: run] Error 127
$ make --trace run
Makefile:2: target 'run' does not exist
go run .
make: go: Permission denied
make: *** [Makefile:2: run] Error 127
$ make --trace run2
Makefile:5: target 'run2' does not exist
echo "Make says hello"; go run .
Make says hello
Hello from go
2
Answers
The issue you’re experiencing is likely due to different environment between your shell and shell executed by
Makefile
. If for example you have a shell alias forgo
this alias is not visible toMakefile
or if you have a custom path in you’re shell rc file it’s not visible toMakefile
. It’s hard to guess where the difference might be.You might want to try debug the issue by trying following in your
Makefile
:and run the same commands in your shell and compare results.
Note that the default shell for
Makefile
is/bin/sh
whereas you probably havebash
orzsh
.Here’s some handy defaults to configure your
Makefile
build:This is due to a bug in GNU make (actually it’s a bug in gnulib). It means that you have a directory named
go
, in some directory on yourPATH
(before the actual directory containing thego
executable).So if you have a directory
/usr/bin/go/.
and you have/usr/bin
on yourPATH
, you’ll see this issue.You should check your
PATH
and make sure to remove any directories that contain such subdirectories. If you can’t remove that directory from yourPATH
(it’s unusual to need directories containing subdirectories on yourPATH
but I guess it’s possible) and you can’t rename thego
directory to something else, you’ll have to ensure that GNU make invokes a shell, by adding a special character. Just;
is good enough: