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
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 your PATH (before the actual directory containing the go executable).
So if you have a directory /usr/bin/go/. and you have /usr/bin on your PATH, 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 your PATH (it's unusual to need directories containing subdirectories on your PATH but I guess it's possible) and you can't rename the go directory to something else, you'll have to ensure that GNU make invokes a shell, by adding a special character. Just ; is good enough:
run:
go run . ;
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 for go this alias is not visible to Makefile or if you have a custom path in you're shell rc file it's not visible to Makefile. It's hard to guess where the difference might be.
You might want to try debug the issue by trying following in your Makefile:
echo $(PATH)
command -v go
and run the same commands in your shell and compare results.
Note that the default shell for Makefile is /bin/sh whereas you probably have bash or zsh.
Here's some handy defaults to configure your Makefile build:
LANG=en_US.UTF-8
SHELL=/bin/bash
.SHELLFLAGS=--norc --noprofile -e -u -o pipefail -c
Related
I have a very simple makefile that I'm trying to execute in git-bash on a Windows 10 machine.
The contents of the makefile are:
start:
source env.sh
Where env.sh is a local file that exists.
If I execute the command make start I receive the following error:
process_begin: CreateProcess(NULL, source env.sh, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [Makefile:2: start] Error 2
However, if I execute source env.sh at the command prompt all is well and I receive no error at all.
I've seen other posts like this Windows 10 Makefile error make (e=2): The system cannot find the file specified which report a similar error, but the linked question is to do with docker being on the path which I don't think applies here.
Is there any reason why the makefile errors but typing the command does not?
On Windows by default, GNU make always runs the Windows cmd.exe shell. The recipe that you're running here is a bash command.
You say it works at the command prompt but that's because the command prompt you're using is from Git bash; if you opened a Windows terminal and typed that command it wouldn't work.
If you want to use a different shell than the default you need to set the SHELL make variable in your makefile:
SHELL := <path to git bash>
Setup: macOS, bash, inside tmux. I use make installed via homebrew.
When running make with my Makefile, I get
protoc -I=foo/bar/proto --cpp_out=foo/bar/proto foo/bar/proto/foo.proto
make: *** No rule to make target 'foo/bar/proto/foo.pb.h', needed by 'proto'. Stop.
make: *** Waiting for unfinished jobs....
When I instead run gmake, the program is successful:
protoc -I=foo/bar/proto --cpp_out=foo/bar/proto foo/bar/proto/foo.proto
protoc -I=foo/bar/proto --python_out=foo/bar/proto foo/bar/proto/foo.proto
But the binaries are exactly the same:
$> readlink -f `which make`
/usr/local/Cellar/make/4.2.1_1/bin/gmake
$> readlink -f `which gmake`
/usr/local/Cellar/make/4.2.1_1/bin/gmake
How is this possible?
It was suggested that this question is a duplicate, which doesn't seem to be the case. I am aware, that the system-make is not necessarily GNU make or not a current version. But as proven above, the two commands refer to the exact same binary.
My environment:
I have recently installed MinGW and GNUWin32 on my Windows 10 pc.
I can compile with g++ successfully without using a make file.
With a makefile, make finds g++ to do compiles.
Problem:
My Clean rule is failing with:
make: /bin/sh: Command not found
make: *** [clean] Error 127
I edited my makefile to have only the following:
RM = C:\WFF\GNUWin32\bin\rm.exe
clean :
whoami
where rm
${RM} *.o *.exe
When I execute make, this is the result:
whoami
tilt
where rm
c:\WFF\GNUWin32\bin\rm.exe
C:\WFF\GNUWin32\bin\rm.exe *.o *.exe
make: /bin/sh: Command not found
make: *** [clean] Error 127
Observations:
whoami works
where works and finds rm.exe
but, through the macro substitution for ${RM}, rm.exe is not found
I tried both of the following with weird results:
executed the make file this way: make SHELL=cmd.exe
added this to the makefile: SHELL = C:\Windows\System32\cmd.exe
For each, make seems to
call cmd.exe
execute the comand whoami
and stops
I enter exit, and make continues
call cmd.exe
execute where rm
and stops
I enter exit, and make continues
etc.
If I enter exit too many times, the window is closed, which doesn't surprise me.
Question: any idea what I can do to debug this or solve it?
I am trying to run Makefile in cygwin.
Error msg:
$ make /cygdrive/d/IoT/trunk/Macchina/TestBed/Makefile
make.exe: *** No rule to make target `/cygdrive/d/IoT/trunk/Macchina/TestBed/Makefile'. Stop.
You don't give make the makefile as an argument like that.
cd to that directory and run make.
Or if that makefile is intended to be used from other directories as well then you can try make -f /cygdrive/d/IoT/trunk/Macchina/TestBed/Makefile.
I have the following simple makefile:
all:
fat_imgen.exe
Where fat_imgen.exe is an executable in the same directory as the makefile. When I try and run this however this happens:
>make
fat_imgen.exe
make: fat_imgen.exe: Command not found
make: *** [all] Error 127
If I run fat_imgen from that same command prompt then it starts as expected - why can't make find fat_imgen.exe?
This is all running under Mingw / Windows.
When using a simple commend like the name of an executable, GNU make will start the executable directly. If the directory where the executable is found is not in the PATH/path, make will fail.
If you put the directory in the path, your makefile should work normally.
Also, as suggested in a comment by #AlexFarber, by adding './' GNU make will assume a more complex command (since not all shells are created equal), and hand the command over to the configured shell. That will work, since the shell is created in the directory where the command is then found.