<< Newer Article #199 Older >>

Solving the Windows Vista Build Issues

Finally! I've worked my way through the remining mingw build issues. Below is a summary of the issues and steps for working around all of them. Turns out only one of the bugs is an actual mingw bug. The rest have to do with other parts of the environment.

The first problem I encountered was that the built-in paths within the mingw environment were no longer working. This is an actual mingw bug that has been tracked down to a change in the way the Microsoft standard C libraries handle invalid parameters. Older versions of the DLL would not check invalid parameters and go down potentially untested code paths with them. The versions in Vista do stricter parameter checking. Some calls made by the mingw tools pass invalid parameters to one of the functions and fail, causing the internal paths to quit working.

The symptom of this problem is that you can't run gcc because it can't find some of its subcomponents in the internal paths. Furthermore, even if you work around that issue, gcc can't find the standard include paths when compiling, nor can it find the standard lib paths when linking. To fix this, I updated the MAME makefile a while back with some hacks, but it turns out that a simple environment variable change will solve the real problem. However, neither solution solves the search path problem, so you must also configure your PATH variable to include the mingw\libexec\gcc\mingw32\3.4.2 path in your build tools.

In summary:

Fix #1: Set the environment variable GCC_EXEC_PREFIX to point to the root of your mingw install.
Fix #2: Add %GCC_EXEC_PREFIX%\libexec\gcc\mingw32\3.4.2 to your search PATH.

Edit: I got a response from someone who said this didn't work. Turns out that GCC_EXEC_PREFIX only works if it points to a directory immediately off the root of your hard disk for some reason. So c:\mingw works fine, but c:\tools\mingw won't. You may have to alter the locations of your mingw directory to make this work.

The second problem I encountered is that I would often see "Cannot fork" errors during the build. I originally thought these errors were coming from the make utility, but eventually I determined that it was the sh.exe that was the problem. See, when make launches subprocesses to run its commands, it needs a command-line shell environment to run them in, in case the commands redirect output (since that requires support of a shell). By default, GNU make under Windows will look for sh.exe and use that to launch commands. If sh.exe isn't present, then it will create a batch file and use cmd.exe, which is the Windows shell. As an experiment, I went ahead and deleted the copy of sh.exe in the mingw/bin directory and sure enough, things started working again without errors.

But I wasn't quite done yet. On my new C2D machine, I wanted to take advantage of both cores by compiling with the -j 2 option. Unfortunately, make doesn't support the -j option when using batch files and cmd.exe. So I needed sh.exe, but obviously couldn't stick with the one I had. I tried the one from both msys and cygwin, and neither of them worked as-is in the mingw environment. So then I thought, well, all sh.exe is required to do is run the specified command. I already wrote a tool similar to that for builing with the Visual Studio compilers. So I adopted vconv.c into a sh.c, which is a new, minimal sh.exe implementation that works and allows multi-threaded builds. So,

Fix #3: Replace the sh.exe in mingw/bin with the version here.

And that's it! So really it comes down to 2 bugs: one in mingw caused by stricter parameter checking, and one in the ancient version of sh.exe that I was including with the build environment.