CMake-generated MinGW Makefile has quoting errors - windows

I was trying to build zlib with CMake 3.9.0, output set to MinGW Makefiles, and noticed upon trying to call mingw32-make in the output dir that there was a weird error message which very much looks like a quoting error to me.
D:\zlib-1.2-11> mingw32-make
[ 2%] Generating zlib1rc.obj
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
C:\Program Files\mingw-w64\x86_64-7.1.0-win32-seh-rt_v5-rev0\mingw64\bin\windres.exe: preprocessing failed.
CMakeFiles\zlib.dir\build.make:60: recipe for target 'zlib1rc.obj' failed
mingw32-make[2]: *** [zlib1rc.obj] Error 1
CMakeFiles\Makefile2:103: recipe for target 'CMakeFiles/zlib.dir/all' failed
mingw32-make[1]: *** [CMakeFiles/zlib.dir/all] Error 2
Makefile:139: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
What could be the cause of this error and how can I fix it? If it were only zlib, I could scrape the net for pre-built binaries, but this has happened with some other builds, too.

This appears to be a bug in MinGW's version of windres.exe, although I'm also going to heap some blame onto CMake for it's appalling method of invoking windres, which is what is causing this to fail.
The Problem
CMake understands that Windows Resource .rc files are a thing, and that they are compiled with the Windows Resource Compiler (aka windres.exe), which it wraps in the default variable CMAKE_RC_COMPILER.
The problem is, that rather than just invoking windres like a normal person, CMake thinks it's being clever by invoking it like so...
cmd.exe /C "cd /D C:\Users\username\zlib-1.2.11\build && "C:\Program Files\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev0\mingw64\bin\windres.exe" -D GCC_WINDRES -I C:/Users/username/zlib-1.2.11 -I C:/Users/username/zlib-1.2.11/build -o C:/Users/username/zlib-1.2.11/build/zlib1rc.obj -i C:/Users/username/zlib-1.2.11/win32/zlib1.rc"
Evidently it doesn't understand the notion of the current working directory, or the system path variable (which it used to find windres in the first place). If we were to simplify the command, it would look like this...
windres -D GCC_WINDRES -I.. -I. -ozlib1rc.obj -i ../win32/zlib1.rc
Those two commands carry the exact same meaning, except the second one actually works.
The Solution
We have to step in and stop CMake from trying to be clever.
cmake .. -DCMAKE_RC_COMPILER=windres
I have MSVC 2017 installed, and CMake assumes that I want to use that by default, despite none of its environment variables being set and it not being in the path (in normal usage, one must invoke the vcvars64.bat file before using MSVC, this behaviour predates CMake). So I have to use -G "MinGW Makefiles", except that I also have sh.exe in my path (because Git), and that just blows CMake's mind, so I need the command...
cmake .. -G"MSYS Makefiles" -DCMAKE_RC_COMPILER=windres

The CMake file author should have quoted strings containing unknown filesystem paths, i.e. variables and the VERBATIM option also avoids headaches:
if(MINGW)
# This gets us DLL resource information when compiling on MinGW.
if(NOT CMAKE_RC_COMPILER)
set(CMAKE_RC_COMPILER windres.exe)
endif()
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj"
COMMAND "${CMAKE_RC_COMPILER}"
-D GCC_WINDRES
-I "${CMAKE_CURRENT_SOURCE_DIR}"
-I "${CMAKE_CURRENT_BINARY_DIR}"
-o "${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj"
-i "${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc"
VERBATIM)
set(ZLIB_DLL_SRCS "${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj")
endif(MINGW)

Related

MinGW cc1plus.exe fatal error (file exists)

I recently installed a new SSD on my machine, and when I did a clean install of windows I got Visual Studio Code, and was about to get the c++ extension up and running, so I got MinGW, and tried to install the GCC and G++ compilers... And low and behold, after trying a lot of solutions, it is still not working properly on this computer image.
When I try to test the compiler after I got MinGW installed properly, this is what it output:
gcc.exe -Wp,-v -E -xc -dD -x c++ nul
ignoring nonexistent directory
"c:\mingw\bin\../lib/gcc/mingw32/6.3.0/../../../../mingw32/include"
ignoring duplicate directory
"c:/mingw/lib/gcc/../../lib/gcc/mingw32/6.3.0/include/c++"
ignoring duplicate directory
"c:/mingw/lib/gcc/../../lib/gcc/mingw32/6.3.0/include/c++/mingw32"
ignoring duplicate directory
"c:/mingw/lib/gcc/../../lib/gcc/mingw32/6.3.0/include/c++/backward"
ignoring duplicate directory
"c:/mingw/lib/gcc/../../lib/gcc/mingw32/6.3.0/include"
ignoring duplicate directory
"/mingw/lib/gcc/mingw32/6.3.0/../../../../include"
ignoring duplicate directory "c:/mingw/lib/gcc/../../include"
ignoring duplicate directory
"c:/mingw/lib/gcc/../../lib/gcc/mingw32/6.3.0/include-fixed"
ignoring nonexistent directory
"c:/mingw/lib/gcc/../../lib/gcc/mingw32/6.3.0/../../../../mingw32/include"
ignoring duplicate directory "/mingw/include"
#include "..." search starts here:
#include <...> search starts here:
c:\mingw\bin\../lib/gcc/mingw32/6.3.0/include/c++
c:\mingw\bin\../lib/gcc/mingw32/6.3.0/include/c++/mingw32
c:\mingw\bin\../lib/gcc/mingw32/6.3.0/include/c++/backward
c:\mingw\bin\../lib/gcc/mingw32/6.3.0/include
c:\mingw\bin\../lib/gcc/mingw32/6.3.0/../../../../include
c:\mingw\bin\../lib/gcc/mingw32/6.3.0/include-fixed
End of search list.
cc1plus.exe: fatal error: nul: No such file or directory
compilation terminated.
Error: 1
The odd part is that the cc1plus.exe is in the MinGW directory, and I even added it to the include path later to see if that would help, and still nothing. I'm not quite sure how to proceed.
This bug has become the bane of my existence for the last week. If anyone has any ideas I'd really appreciate the help. I've had success with MinGW in the past, but for some reason it's giving me problems this time.
Your commandline is:
gcc.exe -Wp,-v -E -xc -dD -x c++ nul
The error:
cc1plus.exe: fatal error: nul: No such file or directory
is the C++ compiler (cc1plus.exe) telling you that the input file nul
does not exist. That will be because there is no file called nul in the current directory.
The Windows CMD NUL device is a virtual device to which the output of a command may be
redirected ( command >NUL) to throw it away. It is not a file.
If you want to test that the compiler can be successfully invoked with this commandline,
then write a program such as:
main.cpp
int main()
{
return 0;
}
Save it in the current directory and run:
gcc.exe -Wp,-v -E -xc -dD -x c++ main.cpp
Close your IDE and go your program folder and open folder with your IDE. Then run and check to see if your problem is solved.

Error fatal - No such file or directory

I have installed the cds library with command ./build.sh -b 64 -z '-std=c++0x' -l '-L /usr/lib/x86_64-linux-gnu' --with-boost /usr/include/boost --amd64-use-128bit at build folder.
After I tried to compile the example init.cpp of src folder, I typed this in terminal: g++ init.cpp -o init, and terminal showed: fatal error: cds/init.h: No such file or directory.
What should I do for compilation command in this case?
Thanks.
For general troubleshooting in cases like this, i would recommend finding where on the system the file got installed (if your build.sh actually installed the file). You would be able to find the missing header file using
find / -path '*/cds/init.h' 2>/dev/null
Then you need to supply two parameters to g++:
First one gets the compiler to know about the include files from the install directory
-I path_to_folder_one_step_above_cds_folder
Second one gets the linker to know about the librarys location. If the library file is called libcds.so, you can find it by running
find / -name libcds.so 2>/dev/null
So for linking, you supply the flag
-L path_to_folder_one_step_above_libcds.so
In your case you might not need the -L flag, since most of your library supposedly is header only.
UPDATE: the build.sh script is printing out important information at the top, starting with "Building with the following options:". The important bits will be "Compile options:" and "Link options:". Those should be enough to solve your specific option.
UPDATE2: build.sh also exports some flags which might include more options. You can print them out directly after running build.sh by running
echo LDFLAGS=$LDFLAGS
echo CFLAGS=$CFLAGS
echo CXXFLAGS=$CXXFLAGS
you are likely to need to pass all these options to g++ when compiling and linking against that library. LDFLAGS are specific to the linker only. Both the other ones are needed for compiling c++ files.

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.

Visual Studio Compiler and recursive Make

I've got a really scary error message while using the visual studio compiler with recursive make.
This is my setup:
Top level Makefile:
.PHONY: test
test:
$(MAKE) -C subdir
Makefile in subdir:
.PHONY: all
all:
cl.exe /nologo /c src/interface.cpp
The compilation succeeds but I always recieve this warning:
unrecognized source file type 'cl', object file assumed
This warning only appears when I invoke make using the top level Makfile. If I change the directoy to subdir and run make no error appears.
cl.exe is known to make by running vcvarsall.bat before running make.
I really hope you can help me.
Thanks in advance.
The problem was, that I had a variable holding the filename of the compiler and I exported that variable from Make. So the command was cl.exe cl.exe... Thanks!

How can I compile "Triangle" using makefiles on a Windows machine

I have just discovered a mesh generator called triangle, found here http://www.cs.cmu.edu/~quake/triangle.html
I am having some issues building this using the make files that are provided. When I passed in the makefile to my visual studio via the command prompt, I got an error
Microsoft (R) Program Maintenance Utility Version 11.00.50727.1
Copyright (C) Microsoft Corporation. All rights reserved.
NMAKE : fatal error U1073: don't know how to make './triangle.c'
Stop.
I have no idea how to debug this.
Eh? Did you read the copious comments in makefile? Just remove -DLINUX from CSWITCHES. Do not try to build showme. Use gcc.
So, with cygwin installed (don't forget the make and gcc packages):
C> bash --login
$ vim makefile
Remove -DLINUX, then
$ make triangle
cc -O -I/usr/X11R6/include -L/usr/X11R6/lib -o ./triangle ./triangle.c -lm
$ make tricall
cc -O -I/usr/X11R6/include -L/usr/X11R6/lib -DTRILIBRARY -c -o ./triangle.o \
./triangle.c
cc -O -I/usr/X11R6/include -L/usr/X11R6/lib -o ./tricall ./tricall.c \
./triangle.o -lm
$ ./triangle.exe
triangle [-prq__a__uAcDjevngBPNEIOXzo_YS__iFlsCQVh] input_file
-p Triangulates a Planar Straight Line Graph (.poly file).
-r Refines a previously generated mesh.
...
Easy, no?
That is a makefile. nmake is not actually a make program, or to be clear, it doesn't conform to the POSIX definition of make. It can't be used with this makefile. Assuming you don't want to go find a POSIX-based system (GNU/Linux, Mac OSX, Solaris, etc.) to work with this on, you'll need to either (a) compile it by hand (it doesn't look like there are too many files) or (b) get a copy of make for your Windows system. There are various ports of GNU make for Windows; probably the easiest one for you to get is from MinGW: http://sourceforge.net/projects/mingw/files/MinGW/Extension/make/make-3.82-mingw32/
Compiling this on windows is gonna make your head sore... It's not portable. I think I saw a few Linux Syscalls in there.
So like the previous answer said, either install a Linux distribution or get yourself MiniGW or CygWin - My Personal favorite.
I agree with getack that building on Windows in general is a recipe for headaches. But triangle by Jonathan Richard Shewchuk is (an awesome) single-file program with no dependencies, so in this case you are fine:
1) Install the microsoft SDK (it's free for the command line stuff).
2) Then create the following file build.bat in the folder with the unpacked source files:
REM Compile Triangle using Microsoft C compiler
REM You must install the msvc SDK
REM Janus, 2013
"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd"
cl /DNO_TIMER /DCPU86 triangle.c
3) Run the build.bat file. This should create a nice triangle.exe.
Background: The call to C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd is required to set up the environment for the microsoft build system. Alternatively the SDK installs a Windows SDK 7.1 Command Prompt where SetEnv is run. See this page for details.
Janus answer worked for after some work. If you are having issues using the bat file he wrote, open SetEnv.cmd (Paste C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd in any file-browser / cmd and hit enter). Then navigate to the project with "cd Path". Than type "cl /DNO_TIMER /DCPU86 triangle.c". Basically its the bat file executed manually. (The bat didnt work for me)

Resources