Broken Makefile after porting from linux to windows - windows

I have a very simple makefile that I ported from Linux to Windows
it only goes inside subfolders and calls other makefiles
all:
$(MAKE) clean
#(cd apps; $(MAKE))
clean:
cd apps; $(MAKE) clean;
the problem is that I don't understand how the #(command1; command2; command3;) syntax works and I'm unable to make it work even with the simplest of commands
For instance
all:
dir
works fine and it outputs the contents of the directory (and I'm in the right one)
all:
cd apps; dir
Does not work, it outputs
cd apps; dir The system cannot find the path specified.
Even worse if I keep the parentheses:
all:
#(dir)
outputs
process_begin: CreateProcess(NULL, (dir), ...) failed. make (e=2): The
system cannot find the file specified.
Can somebody please point me to the proper documentation? I know it must be very simple but all the guesswork so far failed and the documentation is too huge to read it all. I tried but I couldn't find what I'm looking for
Thanks

Related

Windows make - make (e=2): The system cannot find the file specified

I'm using the C++ SFML Library on Windows with Visual Studio Code. The clean target is causing an error message to display and I'm wondering what's happening and how I can fix it. This particular project is just my setup project to ensure things are working. My working directory is as follows:
TEST
Main.cpp
Makefile
My Makefile is the following and I'm using mingw32-make. It creates Main.o and Main.exe. For my question, you can ignore most things, my question is in regards to the clean target.
# Makefile for static linking.
CXX = g++
CXXFLAGS =
EXE = Main
OBJ = Main.o
MODULES = -lsfml-graphics-s -lsfml-window-s -lsfml-system-s -lopengl32 -lfreetype -lwinmm -lgdi32 -mwindows
HEADERS = -IC:\SFML\include -DSFML_STATIC
LIBRARIES = -LC:\SFML\lib
$(EXE): $(OBJ)
$(CXX) $(CXXFLAGS) -o $(EXE) $(OBJ) $(LIBRARIES) $(MODULES)
Main.o: Main.cpp
$(CXX) $(CXXFLAGS) -c Main.cpp -o Main.o $(HEADERS)
clean:
rm $(EXE) $(OBJ)
I am able to compile and run the program but when I do the clean target, I get the following error message.
rm Main Main.o
process_begin: CreateProcess(NULL, rm Main Main.o, ...) failed.
make (e=2): The system cannot find the file specified.
mingw32-make: *** [Makefile:17: clean] Error 2
I thought the issue might be that the ".exe" file extension is not present because if I manually enter "rm Main" I get another error message.
rm : Cannot find path 'C:\Users\Benjamin\PROGRAMMING_PROJECTS\CPP_PROJECTS\SFML_VSCode\TestNoCMake\Main' because it does not exist.
At line:1 char:1
+ rm Main
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\Benjam...estNoCMake\Main:String) [Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
But if I change it to "rm Main.exe" it deletes the file successfully. Upon seeing that, I tried editing my Makefile to have the ".exe" in it.
clean
rm $(EXE).exe $(OBJ)
But, I still end up getting the image in the first picture.
Why is this happening and how can I fix this?
I've seen some other questions about this particular error but they weren't helpful. My setup is also based on this youtube tutorial (https://www.youtube.com/watch?v=rZE700aaT5I&t=96s) and the person in the video did not have this issue. However, his tutorial did not cover the part where MinGW and make are installed, so maybe his and mine are different and it's causing the issue.
The error you're seeing is because the rm program is not found. It's not found because rm is a POSIX tool, and you are running on Windows. The GNU Make program on Windows can be built in various different ways, but the way you have built it means that when it wants to run a shell script it is invoking Windows cmd.exe as its shell.
The output you show from running the command "by hand" shows you are running it from PowerShell, not from cmd.exe so that's probably why you're seeing different behaviors.
You likely need to investigate the PATH variable and ensure that your POSIX tools appear in some directory on the PATH, if you want to write makefiles that use them.
Also I should mention, when writing makefiles you really always want to use forward slashes (/) and never backslashes when you are writing pathnames.

Windows 10 make tool from MinGW returns error 2 (e=2)

i'm trying to make the make utility work on windows through MinGW, but i keep getting error 2 while trying to make the make utility perform a task that isn't a command from MinGW.
test: test.cpp
g++ -o test test.cpp
clean:
rm ./*.exe
compiling works fine, but when i try to run clean, i get an error.
PS D:\Programs\C++\Test> make clean
rm ./*.exe
process_begin: CreateProcess(NULL, rm ./*.exe, ...) failed.
make (e=2): Impossibile trovare il file specificato.
makefile:5: recipe for target 'clean' failed
make: *** [clean] Error 2
but typing rm ./.exe directly into the windows powershell works just fine.
all the examples i could find online were about people calling programs that weren't linked in the windows PATH, but here it's not the problem, since make is linked to the PATH and rm ./.exe works on the powershell. any ideas?
thank you in advance.
The commands you use in Powershell aren't avaliable that way. The ones that are available are from the cmd (cmd.exe) command prompt. The command that removes files in the cmd prompt is erase.
All of this is because programs run as if they were launched in cmd.
For more commands, you should run help on the cmd prompt.
Also rm is just an alias for the legacy erase.

Makefile error make (e=2): The system cannot find the file specified

I am using a makefile in windows to push some files on a Unix server (here a text file "blob.txt" in the same folder of my makefile).
My makefile script is:
setup:
pscp blob.txt username#hostname:/folder/
I start a command prompt, go in the folder where blob.txt and the makefile are present and type:
make setup
Which results in:
pscp blob.txt username#hostname:/folder/
process_begin: CreateProcess(NULL, pscp blob.txt username#hostname:/folder/, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [setup] Error 2
In a #fail ... whereas if I enter directly the command in the command prompt:
pscp blob.txt username#hostname:/folder/
It works ... I really wonder why.
The error
process_begin: CreateProcess(NULL, pscp blob.txt username#hostname:/folder/, ...) failed.
make (e=2): The system cannot find the file specified.
is almost certainly complaining that Windows cannot find pscp.
This is almost certainly because the value of %PATH% (or whatever) is different when make spawns a shell/console then when you have it open manually.
Compare the values to confirm that. Then either use the full path to pscp in the makefile recipe or ensure that the value of PATH is set correctly for make's usage.
I didn't want to remove GIT's bin folder from the PATH variable (I am using a Windows machine), as I use it quite often. So I looked for a workaround, and here it is:
Add the <git-installation-directory>/usr/bin directory to your PATH variable too. This basically adds the rest of the linux-like commands that come with the "GIT bash" to your environment. After applying this, my makefiles ran normally again. :)
If you are curious about what shell is being invoked by make, just add $(info $(SHELL)) at the beginning of your makefile. The path/name of the shell being invoked is printed to the console as soon as you run make.
I know this is an old question that has been answered, but thought I'd and my experiences for anyone still running into this. I was getting the same cryptic error Colonel Beauvel (though with the windows MOVE command, not pscp):
process_begin: CreateProcess(NULL, move /y foo\bar.c .\baz.c, ...) failed.
make (e=2): The system cannot find the file specified.
Our CI was running the same Makefile and working perfectly. Turns out CI was using mingw32-make and I was using GNU make. Uninstalling GNU make (which got installed as part of an unrelated bulk package) and aliasing mingw32-make to 'make' works perfectly.
#user3869623's solution works for me. I'd like to share some details of mine to complete the picture.
My makefile contains below target:
clean:
#echo '$(OS)'
ifeq ($(OS),Windows_NT)
del /s *.o *.d *.elf *.map *.log
endif
When I run make clean, I see this error:
Since it says something went wrong with echo, so I change my makefile target to below:
clean:
ifeq ($(OS),Windows_NT)
del /s *.o *.d *.elf *.map *.log
endif
This time, make clean gives me this error:
I am surprised to see bash here since I am working in Windows command line.
Then I checked my %PATH%, I see this entry:
C:\DevTools\Git\bin
There's a bash.exe and sh.exe in that path. So I removed this entry, and it works fine now.
BUT I STILL DON'T KNOW WHY BASH GET INTO THIS???
ADD 1
As to why the C:\DevTools\Git\bin shows up in my %PATH%, because I am using Sublime and it always asks me for the Git binaries:
In my case, I had git\bin in my %PATH% which contains bash.exe and sh.exe.
Removing %GIT_HOME%\bin from the PATH worked for me.
To build on user3869623's response.
In my case i had git\bin in my %PATH% which contains bash.exe and sh.exe.. Removing %GIT_HOME%\bin from the PATH worked for me
While this recommendation may allow make to run, it will likely cause issues for git, especially if the makefile is installing software from a git repository.
A better solution is to simply change %GIT_HOME%\bin to %GIT_HOME%\cmd
For those who tried removing the git bin folder from PATH and it didn't work for them, search your PATH variables for any paths containing bash.exe.
In my case I found a variable linking to cygwin bin folder C:\cygwin64\bin, removed it and it worked.
I had the same issue, and this thread really helped me solve it. In my case, it was a conflict between make and the sh.exe that was visible through my path, due to both git and mingw64. To fix my issue, without breaking Git, I added these lines to the top of my batch file that calls make:
set path=%path:git\bin=;%
set path=%path:mingw64\bin=;%
set path=%path:usr\bin=;%
This hides the extra sh.exe instances from make for that instance only.
I ran into this problem recently and this question was one of the top hits for my searches.
None of the other answers here helped me. The fix, for me, was to put the binary name in quotes:
setup:
"pscp" blob.txt username#hostname:/folder/
-"pscp" blob.txt username#hostname:/folder/ # Failure is OK, `-` in front
I'm on windows.
By explicitly setting my compiler to gcc (instead of cl?) it solved my problem.
CC = gcc
I hope some people more knowledgeable than me could explain why changing the compiler would impact the makefile parsing.

Wrap a scons build process in a Makefile

I've written a scons build chain form a little C project, but I'm afraid users won't like to be told "You should install SCons first. Besides, it's really cool!" (expecially my professor, as he's kind of from the old guard).
Is there a way I can set up a Makefile that will wrap scons, not requiring it to be installed on the target system?
After looking for such a solution some time ago, I ended up writing a Makefile for this purpose.
Because SCons also comes as a drop-in userspace package scons-local (see the download page), one can fetch in and run it. Here is a dissectioned and commented version of my Makefile, which I also uploaded as a gist.
all: get_scons
#$(SCONS_EXE)
↑ The default action depends on scons being available, and simply runs the scons command (set later in the script) (the # symbol prevents make from printing the command)
SCONS_VERSION=2.3.4
scons-local-%.tar.gz:
curl -L http://sourceforge.net/projects/scons/files/scons-local/$(SCONS_VERSION)/scons-local-$(SCONS_VERSION).tar.gz > scons-local-$(SCONS_VERSION).tar.gz
touch scons-local-$(SCONS_VERSION).tar.gz
scons-local: scons-local-$(SCONS_VERSION).tar.gz
mkdir -p scons-local
tar xzf scons-local-$(SCONS_VERSION).tar.gz --directory scons-local
touch scons-local
↑ Set up the rules for fetching the tarball and unpack it into the scons-local directory
NATIVE_SCONS=$(strip $(shell which scons 2>/dev/null))
ifeq ($(NATIVE_SCONS),)
SCONS_EXE=python2 ./scons-local/scons.py
get_scons: scons-local
#echo "Couldn't find an installation of SCons, using a local copy"
else
SCONS_EXE=$(NATIVE_SCONS)
get_scons:
#echo "Found SCons installation at $(SCONS_EXE)"
endif
↑ Look for the scons executable in the search path (using the which command): if it is available, set up the get-scons target to simply print it is available. If, instead, it is not available, create the get-scons target instructing it to depend on the scons-local target defined earlier.
clean:
$(SCONS_EXE) -c
rm -rf scons-local
rm -f scons-local-*.tar.gz
.PHONY: all clean get_scons
↑ Finally, set-up the clean target that delegates to scons and deletes the local installation afterwards. The .PHONY rule tells make that the following rules do not correspond to files being created.
At this point, one could add more proxy rules of the kind:
mytarget: get_scons
#$(SCONS_EXE) mytarget
Which will invoke scons with the corresponding target.
Hope this is useful, feel free to correct me in case there's something wrong (I'm actually not a Makefile expert, and I'm trying not to become one by using SCons instead :P )

"make clean" issue in MSYS/Cygwin

I finally managed to compile a program in Windows, which took a while and would have not been possible without some help from here. It all works now, except: "make clean" yields
/bin/sh: del: command not found
Makefile:44: recipe for target `clean' failed
make: *** [clean] Error 127
In the makefile, the clean command looks like
clean:
del /S *.o *~ *.out [...], eliminating all resulting .o and executables resulting from make.
mingw64 is in the path, and I tried with cygwin/bin in the path and without, both with the same result. "Make" was done with mingw32-make in msys. I also tried "mingw-32-make clean" in msys, still no luck; I am also not sure if "make clean" is supported in Cygwin at all. I run the whole thing on Windows 7, 64 bit.
How can I fix this problem?
It seems like you are mixing your platforms. del is a cmd.exe builtin, which is why it cannot be found by Bash. The analog to del is rm.
Try running make under cmd.exe
or
editing the Makefile, replacing del /S with rm -f
It is also possible to create a file called makefile.defs in you project folder and overwrite the makefile variable RM which is automatically set to "del" by eclipse. The file is included by "makefile" in the [Name of Config] folder
my File just contains:
RM := rm -rf
This works fine for me.

Resources