Jesus 'n Jim

A mainly PC (some Mac) site w/Software, Computer Repair Info, How-To's on Using Computers
Technical Support 1-360-521-2060 (my business line cell)

Using/getting MinGW compiler(free C++/Ada/Fortran77/Java/objC)

 

overview

mingw-w64 is both a 32-bit target and a 64-bit target compiler that can reside on either a 64-bit or 32-bit OS host (at least for windows, other platforms are not so flexible).

I am unsure about the other platforms, as to whether they generate mac or linux code, or whether they generate windows code as a cross-compiler.

platforms:

  • cygwin
  • darwin(Mac Intel 64-bit)
  • linux
  • windows 32-bit and 64-bit target. can be hosted on a 32-bit or 64-bit machine, but 64-bit host only generates 64-bit code.

There is an 'MSYS' UNIX compiler development environment for making shared-library-based executables you can download separately, but it might be for windows only. it can run configure scripts and you can do makefiles with make to compile things like the fltk windowing toolkit (which compiles just fine).

the compiler provides complete access to the OS's system calls of course. for windows, it is similar to Microsoft Visual C++ style headers mostly, but some differences (not quite as easy).

Glossary

When I started working with cross-compilers like mingw-w64, I had to learn some new terms.

host
the OS the compiler runs on to compile code.
target
the target OS which will execute the code. just because you have a host and a target doesn't mean they necessarily match! (they do for borland). Take Windows CE 2.0 for example. Microsoft Visual C++ can compile for Windows CE and Windows XP and windsows 2000 and windows 9x/me, etc, some of these having a slightly different set of supported win32 calls. so it appears that each of these OS's is a different target I suppose, but really there are only 2 targets: 32-bit windows and 64-bit windows. I don't know what it's like on the mac. I hope they come out with a mac compiler in the mingw-w64 compiler set. I heard that mingw-w64 already runs under themac somehow, but I am not sure how. as an apple developer, you would know this when you visit apple xcode. in the mingw-w64 compilers, you have a separate compiler for each target (e.g. 32-bit and 64-bit, and multiply this for each OS, windows, linux, and BSD).
toolchain
the compiler and any periphery utilities that come with it, like the resource compiler, linker, dll tool, etc.
build environment
this would usually mean a UNIX/Linux build environment, because most source code is made in such a way that it requires the BASH shell and makefiles, and automake and autoconf and a number of other utilities including gcc to compile. in mingw and mingw-w64's case, this would imply MSYS, which must be installed and configured separately on windows.

0. Get the compiler

sf.net/projects/mingwbuilds GNU compiler collection(C++, ObjectiveC, Ada, Fortran77, Java)
32-bit+64-bit targets(output) compiler, available at sf.net/projects/mingwbuilds
GNU compiler set for Windows. C++ is Visual C++ compatible, but without ATL or MFC. It supports multithreading through POSIX PThreads. it generates 32/64-bit code through -march and other switches however this does not generate proper 64-bit executables, they have 32-bit headers. requires a different compiler (below) to do 64-bit code. stable, uses latest version of gcc from trunk. I believe the files ending in -1 and _1 are 64-bit, but I could be wrong.
mingw-w64 GNU compiler collection(C++, ObjectiveC, Ada, Fortran77, Java)
GNU compiler set for Windows. choose the sezero/personal build. C++ is Visual C++ compatible but without ATL or MFC. It supports multithreading through POSIX PThreads. it generates 32-bit and real 64-bit executables I think, however, the 64-bit executables require libgcc_s_sjlj-1.dll that is in the bin directory. I have not found a way to link in a library to make a monolithic executable. uses later version of gcc than the above compiler. The latest usable version of the compiler is the hand-compiled build with the name sezero. I believe the files ending in -1 and _1 are 64-bit, but I could be wrong. in this compiler, that's all of them.
takes some configuring to get working, like setting up fstab, hope you are familiar with UNIX (they help you out a little with an installer that gets you started)
apparently the posic version (?) has problems for now
these are really for the compiler developers, but there is a mac compiler in here I think
these are really for the compiler developers, but there is a mac compiler in here I think

1. compiler bugs

  • mingw/gcc does not accept microsoft/borland versions of 64-bit constants in which i64 is appended (case sensitive). it would be nice if the compiler accepted both the gcc method of LL or ll and the microsoft version of i64.
    for instance, unsigned __int64 = 0x1234567887654321Ui64; //ms/borland
    unsigned long long = 0x1234567887654321ULL; //gcc/djgpp/mingw
  • printf for the former uses %I64u. I know that printf for DJGPP uses %llu for the latter, but I can't remember if that causes a crash in mingw-generated code. since the example that microsoft has given for printf specifications gives the type as the last item in the specification, I have always found it to be the safest route wherever I go. especially since the constants are pretty much the same way.
  • ctype.h's tolower and toupper are useless to me as they are defined in the macro form and should be completely rewritten they are so useless - you can even use the ternary operator ?: to do the job in a macro! so why didn't someone do that in the first place?

I am working to get these fixed.

2. compiler niceties

  • while spelunking around _mingw.h because of an error, I found __int128. oh joy! I wonder how I can use it... [[failed. ohhh, too bad, it's not implemented yet. I am told no int128 types exist in the C++ standard, so they are not being added to GCC, and definitely not to stdint.h until such time as they do so somebody make a request! then all those GUIDs and UUIDs and be stored in a single number, and we can have bigger integers for computing and calculators.]]
  • automatic * and ? and ... expansion on the command-line into filenames, at least the sezero toolchain does this (DJGPP does this too). If this bugs you, you can turn it off using the following code outside of main():
    #if !defined(STRICMP_NOGLOB_H)
        #define STRICMP_NOGLOB_H "3.0"
    
        //STRICMP macro definitions and disable globbing (disable wildcard expansion)
        #if defined(__MINGW32__)
            #include <_mingw.h>
            //#include <_mingw_mac.h>
            #if defined(__MINGW64_VERSION_MAJOR)&&defined(__MINGW64_VERSION_MINOR)
                //mingw-w64
                int _dowildcard = 0; //disable globbing in mingw-w64
    	
    			//the following #undef is to make fsetpos() and fgetpos()
    			//which are better replacements for fseek() and ftell(), 64-bit!
    			//unfortunately, I think it does a lot more than just that...
    			#undef NO_OLDNAMES
    			
                #define STRNICMP _strnicmp
                #define STRICMP _stricmp
                #define STRCMP strcmp
                #define STRDUP _strdup
                #define STRLWR _strlwr
                #if defined(_WIN64)
                    //64-bit
                #else
                    //32-bit
                #endif
            #else
                //mingw
                int _CRT_glob = 0;
    			//the following #define is to make fsetpos() and fgetpos()
    			//which are better replacements for fseek() and ftell(), 64-bit!
    			//unfortunately, I think it does a lot more than just that...
    			#define __MSVCRT__
    			
                #undef __STRICT_ANSI__
                #define STRNICMP _strnicmp
                #define STRICMP _stricmp
                #define STRCMP strcmp
                #define STRDUP _strdup
                #define STRLWR _strlwr
            #endif
        #elif defined(__DJGPP__)
            //djgpp
            #define STRNICMP strnicmp
            #define STRICMP stricmp
            #define STRCMP strcmp
            #define STRDUP strdup
            #define STRLWR strlwr
            //http://www.delorie.com/djgpp/v2faq/faq16_2.html
            #include <crt0.h>
            char **__crt0_glob_function (char *arg) {
                return 0;
            }
        #elif defined(__BORLANDC__)
            //borland/embarcadero compilers
            #define STRNICMP _strnicmp
            #define STRICMP _stricmp
            #define STRCMP strcmp
            #define STRDUP _strdup
            #define STRLWR _strlwr
            //in the older compilers, you had to supply your own strpos
            //there is no globbing in these compilers
            #if defined(_WIN64)
                //64-bit
            #else
                //32-bit
            #endif
        #elif defined(_MSC_VER)
            //VC++
            #define STRNICMP _strnicmp
            #define STRICMP _stricmp
            #define STRCMP strcmp
            #define STRDUP _strdup
            #define STRLWR _strlwr
            //there is no globbing in these compilers
            #if defined(_WIN64)
                //64-bit
            #else
                //32-bit
            #endif
        #elif defined(__WATCOMC__)
            //OpenWatcom compilers
            //I don't have this compiler, so I don't know if I have these right.
            #define STRNICMP _strnicmp
            #define STRICMP _stricmp
            #define STRCMP strcmp
            #define STRDUP _strdup
            #define STRLWR _strlwr
            //these compilers don't do globbing
        #elif defined(__MWERKS__)
            //I don't know about this compiler since I have not tried it
            #define STRNICMP _strnicmp
            #define STRICMP _stricmp
            #define STRCMP strcmp
            #define STRDUP _strdup
            #define STRLWR _strlwr
            #if defined(_WIN64)
                //64-bit
            #else
                //32-bit
            #endif
            //I don't know about this compiler's ability to do globbing, I could find nothing on the internet.
            //so you must add noglobbing code here.
    	#elif defined(__GNUC__)
    		//some gcc not known about here
            //I don't know about non-mingw and non-DJGPP gcc's (like linux gcc's)
    		
    		//the following #undef is to make fsetpos() and fgetpos()
    		//which are better replacements for fseek() and ftell(), 64-bit!
    		//unfortunately, I think it does a lot more than just that...
    		//linux method of specifying 64-bit fpos_t for fgetpos() and fsetpos()
    		#define __USE_FILE_OFFSET64
    		#define __USE_LARGEFILE64
    		
            #define STRNICMP _strnicmp
            #define STRICMP _stricmp
            #define STRCMP strcmp
            #define STRDUP _strdup
            #define STRLWR _strlwr
            //these compilers do globbing, but support for globbing is compiler and platform-specific.
            //so you must add noglobbing code here.
        #endif
    
    #endif
    
    
  • c++0x
  • c99
  • TR1 in latest builds, which includes <random> which includes mt19937, the mersenne twister random number generator. you can mix and match algorithms and engines to make your own.
  • Standard C++ Library (STL)

3. Free Code you can include

Disclaimer: This code is provided without warranty and at your own risk. Nor am I saying it is fit for any purpose.

For this code to work, the comments must be put into a C++ file of some kind or a .h file. if you wish, you can C-ize the comments and delete the extraneous code.

#if defined(__MINGW32__)
#include <basetsd.h> //defines __int64 specifically for MinGW
#endif
#if defined(__BORLANDC__)
using namespace std; //required to make use of _strdup
#elif defined(__GNUC__)
char * _strdup(char * str) {
    return strdup(str);
}
#elif defined(_MSC_VER)
//do nothing, _strdup works on microsoft compiler
#else
char * _strdup(char * str) {
    char * p = (char *)malloc(strlen(str)+1);
    if (p != NULL) {
        strcpy(p, str);
    } else {
        yy_fatal_error("out of memory. lex bailing out.");
    }
    return p;
}
#endif


//this will loop forever if it never finds a null character!
//not defined in GCC, borland, or VC++.
int strpos(char s[], char c) {
    int i;
    for (i=0; s[i] != '\0'; i++) {
        if (s[i] == c) {
            return i;
        }
    }
    return -1;
}

There are a lot of -1 and _1 files in mingw, and I have no clue what they are. nobody documented them. I had thought that maybe they were 64-bit versions of the executables and libraries. I could be wrong. sombody email me and correct me.

4. Tips to get going

If you happen to have access to MSDN for Microsoft Visual C++ 6.0, you have the documentation you need to get going. But don't get excited and think you have access to ftell64 and fseek64. You may not (I can try to test and find out). those are from microsoft's latest compiler.

Switches:
-s strips out the huge debugging stuff.
-fpack-struct packs structures so you don't have surprising and gaping holes in them, but it does not work with iostream, fstream, istream, ostream, or locale.
-O is the highest optimization level you can get that generates good code.
-O2 and -O3 have higher optimization levels but causes corrupt/bad/bogus code.
-o filename sets the output file.

MinGW unfortunately does not [yet] use response files (such as @myfiles.lst that djgpp and borland uses). this means that if you are compiling with batch files and using %1 %2 ... %9 you are limited to 9 files (but you can do tricks with shift and variables to do 160) unless you resort to tricks with environment variables (I did with gw.cmd, it handles 160 files). Instead, you are supplied with make to do the job, which uses a Makefile. You really should use the MSYS make instead of the MinGW make. In fact, It is recommended that you do not install mingw make or remove it.

monolithic executables

If it happens to be an EXE, gcc/g++ will generate a monolithic executeable, unless you are using a 64-bit bersion of the compiler, in which case it requires a DLL to execute, c:\mingw-w32-bin_i686-mingw_20091224_sezero\mingw64-w32\bin\libgcc_s_sjlj-1.dll. You can can make a 64-bit monolithic executable by linking in c:\mingw-w32-bin_i686-mingw_20091224_sezero\mingw64-w32\lib\gcc\i686-w64-mingw32\4.4.3\libgcc.a.

compiler wrapper batch file for making vista/7-compatible executables

I have not verified its ability to make vista compatible executables, someone please let me know. the information I have is from an article from a linux person who got his information from somewhere else and couldn't verify. the 32 and 64-bit programs generated work OK on my XP computer (I don't know why the 64-bit programs work, other 64-bit programs never executed: 32-bit wrapper?).

to compile a generic program, I use the batch file gw.cmd.

It compiles for the i386 or x86-64 by you specifying 32 or 64 as the first parameter, and it defaults to 32-bit code if you specify nothing.

You can also specify a pack parameter to pack structures, but pack does not work with iostream or locale libraries/headers. gcc developers told me they didn't intend to fix that bug. if you pray about it, maybe it will get fixed. I find -fpack-struct necessary for disk I/O programs that use C++ libraries - and TR1 is probably coming (yay), which would make it even more necessary.

This batch file spares me from fussing with switches all the time. I don't want to memorize them. just don't choose open when you download it or you'll just get help flashing by and no download. save to the same directory as your project files and keep a backup copy.

Use cmd's call gw command to call the gw.cmd batch file inside a batch file to do your builds.

the batch file is now more accommodating to embedding in batch files. Now it can embed the manifest title and assemblyversion.

In order to see the help on gw, you really should set the properties on your cmd shell's Properties|Layout|Screen buffer|Height to at least 200. I set mine for 5000-9900 so I can scroll back and see what went by (error messages, etc).

Downloads:

Download Now
compiler-wrapper.zip (11/1/2012)


Download Now
buildboostmingw-w64-mingw.zip (4/12/2011)


when downloading, choose "Save File As" and do not open or run (or you will only see a cmd shell with a bunch of help text flashing by and then the shell quickly closing). but I probably don't have to tell you that. :-)

buildboostmingw-w64-mingw.zip is a zip file containing some necessary files to build the boost library using mingw or mingw-w64. instructions:

  1. download boost and unzip into a directory that has no spaces, preferably close to or extract to c:\ (it makes its own directory \boost_1_46_1)
  2. download and unzip buildboostmingw-w64-mingw.zip into boost_1_46_1\
  3. download and install the auto build (non-1.0) targeting win32 and win64 compilers.
  4. edit buildboost.cmd and configure the variables with your build environment.
  5. run buildboost clean install

Description of downloads:

gw.cmd

gw.cmd is a compiler wrapper batch file. it is supposed to add extra functionality like vista/7 code generation that the compiler normally doesn't give you.

without it, it's a pain to make a windows vista/7 executable and you have to change the files every time the version number changes. this way, you only change your build batch file version number whenever the build version number changes, instead of changing multiple manifest files and resource files. it also compiles your resource files and DLL's for you.

you can choose to use the compiler's runtime DLL, but by default it statically links everything into a monolithic executable. I prefer that kind of executable because most of my programs are small.

installcompiler.cmd

this is a batch file to partially install mingw-w64 compilers for gw.cmd compiler wrapper.

it simply uses 7-zip to extract the compiler zip files into the proper place on the hard drive in windows. it senses if the required 7-zip is not installed.

but it does not edit/configure the gw.cmd batch file because there are no built-in windows tools for doing that which everybody has.

gw.cmd and gw2.cmd How-to

Word of Warning: properly created manifest xml resources do not work with XP or earlier.

gw.cmd

to compile a .rc file in, simply specify rc somefilename.rc, for example, call gw 32 -manifest default rc somefilename.rc someapp exe someapp.cpp. the -manifest default tells the batch file to generate a manifest and a resource file and to compile it in coff format, and compile it into the exe. this makes it compatible with windows vista/7 I am told.

to skip the rc file and just include the manifest, call gw 32 -manifest -default someapp exe someapp.cpp or call gw 32 -manifest "someapp - a sample application" asInvoker false -assyver 1.0.0.0 someapp exe someapp.cpp

if you want to pack structures so there are no holes, use -pack. but it won't work with iostream or locale (gcc bug they won't fix, borland and microsoft compilers do not have this problem)

if you want debug code, use -debug.

if you want a manifest, use -manifest or --manifest followed by either the word default or defaults, which chooses executionLevel=asInvoker and uiaccess=false, or the -manifest switch can be followed by executionlevel and uiaccess. executionlevel values are: asInvoker, highestAvailable, requireAdministrator. uiaccess possible values are: true, false. You will be prompted for the Application Title and the Assembly Version if you use -manifest -default alone. I suggest you echo these strings to yourself for cut and paste when you make your build batch file.

if you want help, use no arguments, or use /? or /h or -? or -help or --help or /help or any other variation.

if you want 64-bit code, just specify 64.

if you want 32-bit code, just specify 32. this is the default.

for a specification document on manifest xml files, articles on compiling them into your executables using cygwin/mingw, and a list of commonly used compiler switches, refer to here.

for a list of useful #defines you can use for making your source code compiler independent, refer to here.

gw2.cmd

to compile a .rc file in, simply specify rc somefilename.rc, for example, call gw2 -manifest default rc somefilename.rc someapp exe someapp.cpp. the -manifest default tells the batch file to generate a manifest and a resource file and to compile it in coff format, and compile it into the exe. this makes it compatible with windows vista/7 I am told.

to skip the rc file and just include the manifest, call gw2 -manifest -default someapp exe someapp.cpp or call gw2 -manifest "someapp - a sample application" asInvoker false -assyver 1.0.0 someapp exe someapp.cpp - the build number will be filled in for you.

if you want to pack structures so there are no holes, use -pack. but it won't work with iostream or locale (gcc bug they won't fix, borland and microsoft compilers do not have this problem). instead, you should use #pragma pack(1) and #pragma pack() to finish.

if you want debug code, use -debug.

if you want a manifest, use -manifest or --manifest followed by either the word default or defaults, which chooses executionLevel=asInvoker and uiaccess=false, or the -manifest switch can be followed by executionlevel and uiaccess. executionlevel values are: asInvoker, highestAvailable, requireAdministrator (case-sensitive!). uiaccess possible values are: true, false (case-sensitive!). You will be prompted for the Application Title and the Assembly Version if you use -manifest -default alone. I suggest you echo these strings to yourself for cut and paste when you make your build batch file.

if you want help, use no arguments, or use /? or /h or -? or -help or --help or /help or any other variation.

gw2 automatically generates a 32\ and 64\ directory with the binaries and error files in them.

for a specification document on manifest xml files, articles on compiling them into your executables using cygwin/mingw, and a list of commonly used compiler switches, refer to here.

for a list of useful #defines you can use for making your source code compiler independent, refer to here.

adding a manifest for vista/7/8 compatibility

I have written a batch file for adding a manifest resource to the compilation for the mingw compiler. I have not yet figured out how to do this for the Borland compiler because I was having a hard time figuring out how to put in the resource into the EXE. I later learned that you compile the .rc file and link in the resulting .res file like it was a library.

check out these articles:
manifest 1.0 XML Schema (THE reference, O'Reilly has an XML Schema book if you have trouble reading it)
manifest xml reference
[BUG] Vista doesn't start application called "install" w/o being elevated.
how to embed a manifest into an exe with mingw tools only
article on using microsoft's manifest tool mt (documents the 1 or 2 thing)
article about manifest, clickonce, and elevated UAC levels like admin
the processorArchitecture post, mentions that the values are x86, MSIL, IA64, and AMD64 but I have seen elsewhere in manifests that it is X86 not x86. case insensitive?
excellent delphi article example on manifest XML assembly and .rc file contents, and
2000+ manifest (wikipedia) amanifest like this is the only one that works, I will show you what I use
The XP Theme Manifest
msdn article on resource assembly numbers
adding DLL's and other dependent files to your manifest
Visual Styles (more on manifests)
manifest 1.0 specification
<trustinfo> element documentation
designing apps for windows 7 UAC
Fixing an app using Private Assembly
system32 msvcrt.dll and manifests
msvcrt.dll in <dependency> enlightening - shows you both the mscrt.dll maniferst and the exe manifest section you should have (this only works IF yours is not an older one and has a manifest, VC++2010 does not)
VC++2010 no longer requires manifests (see related post) What does this all mean for windows developers? NOTHING! windows 2008 R2, 7, vista, 2008 still require a manifest. sorry guys and gals.
troubleshooting manifest-related issues
compatibility manifest (by the way, this doesn't work).
find out why your external manifest is being blocked

the only manifest that works. period. (windows 9x+)

I have tried many article's advice on how to get a manifest to work. no advice works except for this manifest.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
        <ms_asmv2:security>
            <ms_asmv2:requestedPrivileges>
                <ms_asmv2:requestedExecutionLevel level="asInvoker">
                </ms_asmv2:requestedExecutionLevel>
            </ms_asmv2:requestedPrivileges>
        </ms_asmv2:security>
    </ms_asmv2:trustInfo>
</assembly>

the UTF-8 (upper-case) is the only proper way to write UTF-8. most people ()including Adobe Dreamweaver) incorrectly use utf-8 lower-case. this is not valid for XML, HTML, or XHTML.

symptoms that you have done something wrong with your manifest in XP:

in this case, cross-platform manifest not coded properly.  
unless it is PERFECT, it will not execute.

Sun 02/12/2012 16:41:45.26|C:\prj\df\df-3.13\win\32|>df -unit 512
The system cannot execute the specified program.

Sun 02/12/2012 16:41:45.27|C:\prj\df\df-3.13\win\32|>

If you:

  • try to add features like <dependency> or <compatibility> to a cross-platform manifest
  • try to execute a 64-bit .exe on a 32-bit machine

you will get "_____ is not a valid win32 application" error dialog.

If you forgot a manifest and you try to run an console app on a 2008 R2 system or windows 7, UAC will require you to run as administrator or give you errors in your program.

XML Manifests can be:

  • a normal windows resource
  • a .ocx.manifest or .exe.manifest or .dll.manifest file alongside the .exe or .dll or .ocx

cross-platform manifest (9x+)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
        <ms_asmv2:security>
            <ms_asmv2:requestedPrivileges>
                <ms_asmv2:requestedExecutionLevel level="asInvoker">
                </ms_asmv2:requestedExecutionLevel>
            </ms_asmv2:requestedPrivileges>
        </ms_asmv2:security>
    </ms_asmv2:trustInfo>
</assembly>

You need to know that this is XML. you can use whatever identifier you want for the code items above as long as its all the same (it's a namespace). you can even use a namespace for assembly if you want, just put an :identifier after xmlns and use the identifier in front of assembly like identifier:assembly and it should work just fine. this works because in the namespace certain elements and attributes work. I am not sure, but I think this is because there is some sort of XML Schema attached to the namespace (an .xsd file) somehow, I don't understand that much of XML yet.

Apparently on XP SP3, <description> element and having the uiAccess="true|false" (false being the default if uiAccess not specified) attribute on the <requestedExecutionLevel> element is allowed. both are open/close tags. But I DON'T know if <description> works on other platforms. <compatibility> and <dependency> cause interesting errors in this cross-platform manifest on XP. XP SP3 bucks anything else you try. Windows 9x also works with uiAccess="false" (the default).

how to create an XML Manifest with mingw/mingw-w64

  1. Create some xml file containing your manifest, e.g. app.dll.manifest
  2. 1 for exe, 2 for dll. #include "winuser.h"
    2 RT_MANIFEST "app.dll.manifest"
    should be added to your .rc file, compiled to a .o (.obj for borland). I have seen 1 24 "app.exe.manifest", but all it does is cause windres to crash/GPF.
  3. Using windres you compile the .rc into an object file (.o)
  4. link the object file (.o) together with all the other object files to your final executable using gcc or g++. if you are compiling a dll, use the -shared switch
windres --input=app.rc --input-format=rc --output=app.res --output-format=coff
g++ -shared -o app.dll app.cpp app.res -lmsvcr90

or

windres --input=app.rc --input-format=rc --output=app.res --output-format=coff
g++ -o app.exe app.cpp app.res -lmsvcr90

the msvcr90 microsoft runtime I don't know about, it seems to be only needed for the python language, from what I have seen on google. It is probably best to leave it out (it does not come with mingw).

The filesystem hooks will query the virtual store first (And only read the "real" location [c:\program files\whatever] if the file is not found in the virtual store) for applications without a manifest. (quote from someone in bug tracker in sf.net)

link to where gw.cmd is, info on mingw compiler and where to get it in 64-bit and both 32-bit versions.

make sure when you download that you save the file rather than open/run it.

to compile a .rc file in, simply specify rc somefilename.rc, for example, call gw 32 -manifest default rc somefilename.rc someapp exe someapp.cpp. the -manifest default tells the batch file to generate a manifest and a resource file and to compile it in coff format, and compile it into the exe. this makes it compatible with windows vista/7 I am told.

to skip the rc file and just include the manifest, call gw 32 -manifest default someapp exe someapp.cpp

if you want to pack structures so there are no holes, use pack. but it won't work with iostream or locale (gcc bug they won't fix, borland and microsoft compilers do not have this problem)

if you want debug code, use debug.

if you want a manifest, use manifest or -manifest or --manifest followed by either the word default or defaults, which chooses executionLevel=asInvoker and uiaccess=false, or the -manifest switch can be followed by executionlevel and uiaccess. executionlevel values are: asInvoker, highestAvailable, requireAdministrator. uiaccess possible values are: true, false. You will be prompted for the Application Title and the Assembly Version. I suggest you echo these strings to yourself for cut and paste when you make your build batch file.

if you want help, use no arguments, or use /? or /h or -? or -help or --help or /help or any other variation.

if you want 64-bit code, just specify 64.

if you want 32-bit code, just specify 32. this is the default.

for a specification document on manifest xml files, articles on compiling them into your executables using cygwin/mingw, and a list of commonly used compiler switches, refer to here.

for a list of useful #defines you can use for making your source code compiler independent, refer to here.

to compile a 32-bit app using mingw 5.1.6, app named df manually

df.manifest.rc:

#include "winuser.h"
1 RT_MANIFEST "df.exe.manifest"

manifest xml windows resource df.dll.manifest:

build 49, version 2.8.0, x86 architecture,

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
	<assemblyIdentity
     version="2.8.0.49"
     processorArchitecture="x86"
     name="df"
     type="win32"/>
	<description>df - show disk free space and usage in SI units with graph or in bytes</description>
	<!-- Identify the application security requirements. -->
	<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
		<security>
			<requestedPrivileges>
				<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
			</requestedPrivileges>
		</security>
	</trustInfo>
</assembly>

build. please note that it is required to set the path to the compiler's bin directory before using the compiler's executables.

SET PATH=c:\mingw\bin;%PATH%

c:\mingw\bin\windres.exe --input=df.manifest.rc --input-format=rc --output=df.manifest.res --output-format=coff

c:\mingw\bin\g++.exe -Wall -W -O -s -fstack-check  -IC:/libpq/;c:/libpq/server/libpq/;c:/mingw/include -Lc:/libpq/;c:/mingw/lib -o df.exe df.cpp prsinum.cpp df.manifest.res

where the program's name is df.exe version 2.8.0.0 (enforce the 0.0.0.0 version format in microsoft's sample or you will end up with an executable that will not execute even on XP) and it is a 32-bit application. asInvoker and uiAccess should probably not be changed if you want oneclick install capability.

to compile a 64-bit app with mingw-w64 (32-bit version), app named df manually

df.manifest.rc:

#include "winuser.h"
1 RT_MANIFEST "df64.exe.manifest"

manifest xml windows resource df.dll.manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
	<assemblyIdentity version="2.8.0.0"
     processorArchitecture="AMD64"
     name="df64"
     type="win32"/>
	<description>df64 - show disk free space and usage in SI units with graph or in bytes</description>
	<!-- Identify the application security requirements. -->
	<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
		<security>
			<requestedPrivileges>
				<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
			</requestedPrivileges>
		</security>
	</trustInfo>
</assembly>

build. please note that it is required to set the path to the compiler's bin directory before using the compiler's executables. use the hand-built compiler.

SET PATH=c:\mingw-w32-bin_i686-mingw_20091224_sezero\mingw64-w32\bin;%PATH%

c:\mingw-w32-bin_i686-mingw_20091224_sezero\mingw64-w32\bin\windres.exe --input=df64.manifest.rc --input-format=rc --output=df64.manifest.res --output-format=coff

c:\mingw-w32-bin_i686-mingw_20091224_sezero\mingw64-w32\bin\g++.exe -Wall -W -O -s -fstack-check  -IC:/libpq/;c:/libpq/server/libpq/;c:/mingw-w32-bin_i686-mingw_20091224_sezero/mingw64-w32/include -Lc:/libpq/;c:/mingw-w32-bin_i686-mingw_20091224_sezero/mingw64-w32/lib -o df64.exe df.cpp prsinum.cpp df64.manifest.res c:\mingw-w32-bin_i686-mingw_20091224_sezero\mingw64-w32\lib\gcc\i686 -w64-mingw32\4.4.3\libgcc.a

where the program's name is df64.exe version 2.8.0.0 (enforce the 0.0.0.0 version format in microsoft's sample or you will end up with an executable that will not execute even on XP) and it is a 32-bit application. asInvoker and uiAccess should probably not be changed if you want oneclick install capability.

build 32-bit df using mingw 5.1.6 and gw.cmd batch file, making it vista-7 compatible

before doing any work with gw.cmd, you will need to edit gw.cmd and put in your compiler's bin and include paths, and configure which (32-bit or 64-bit mingw-w64 compiler) you are going to use. all this is done at the top of the file through environment variable settings, and the possible values and descriptions are given in the file.

call gw 32 -manifest "df - show disk free space and usage in SI units with graph or in bytes" asInvoker false -assyver 2.8.0.0 df exe df.cpp prsinum.cpp

build 32-bit df using mingw 5.1.6 and gw.cmd batch file

before doing any work with gw.cmd, you will need to edit gw.cmd and put in your compiler's bin and include paths, and configure which (32-bit or 64-bit mingw-w64 compiler) you are going to use. all this is done at the top of the file through environment variable settings, and the possible values and descriptions are given in the file.

call gw 64 -manifest "df - show disk free space and usage in SI units with graph or in bytes" asInvoker false -assyver 2.8.0.0 df64 exe df.cpp prsinum.cpp

Valid manifest XML values

Valid values for processorArchitecture are:

  • IA64:the intel processor used on some 64-bit servers.
  • AMD64:64-bit AMD processor
  • x86:32-bit intel architecture. I could be wrong, but it could also include the core i7 processor as well (someone please verify?).
  • MSIL:I don't know what this is.

Valid values for requestedExecutionLevel uiAccess attribute are:

  • false:apps that are not providing accessibility.
  • true:must be Authenticode signed. should be only used for UI Assistive Technology apps.

Valid values for requestedExecutionLevel level attribute are:

  • asInvoker: standard user app. runs with same access token as parent process. recommend you go with this one for most apps.
  • highestAvailable: runs with highest privs obtainable. for mixed-mode apps.
  • requireAdministrator: app runs only for administrators. recommended for admin-only apps. internal elevation points are not needed.

gw.cmd docs

docs updated 5/19/2011 - always follow the built-in docs, they should be much more up-to-date and have more errors fixed or be more explanatory.

  • replaced default -lstdc++ compiler switch with -cpp or -c++
  • replaced default -std=c++0x compiler switch with -c++0x or -cpp0x
  • replaced default -lgcc and -static-libgcc compiler switches with -monolithic
  • better automation of handling semi-required DLL's (I think I got it right)
Sun 11/20/2011 16:42:50.00|C:\u|>gw
if you need to reset gw, do the following: gw reset
-----environment variables set, including path.
gw - batch file compiler wrapper for MinGW and MinGW-w64's g++ (C++) compiler.
usage:
    gw2 [-[-]?|/?|-[-]h[elp]|/h[elp]] [-[-]v[er[sion]]|/v[er[sion]]] [-reset|/reset]
    gw2 [-[-]mono[lith[ic]]|-[-]static] [-[-]cpp0x|c++0x|c++11|cpp11] [-[-]stdcpp|stdc++] [-[-]pack] [-[-]noopt|lowopt|-O|-O0|-O1|-O2|-O3|-O4] [-[-]windows] [-[
-]console] [-[-]debug|-g] [-[-]rc file.rc] [-[-]reset] [[-[-]manifest] [-[-]default[s]|app_title_string_in_double_quotes executionlevel uiaccess] [-[-]assemblyv
ersion 1.0.0.0] [-[-]msvcrt90] [-[-]lBASELIBNAME] baseNameOfEXEorDLLorOCX /exe|/dll|/ocx|[-][-]exe|[-][-]dll|[-][-]ocx sourcefile [sourcefile ...]

-? or /? or -h or --help or -help or /help or no arguments gives this help.
-v or /v or /ver or /version or -version gives the version of gw.cmd
every switch can operate off of -, --, or / except the optimization switches.
defaults to 32-bit code and -O (lowopt) optimization due to bad code generation at higher optimization levels!
for 32-bit, a monolithic windows executeable will be created. for 64-bit, a dll is required.  I don't know how to get around that: email me.
[-[-]reset] resets the variables of this batch file (such as the path - path is sticky unless you change from 32-bit to 64-bit. necessary if you change the batc
h file).
[-[-]v[er[sion]]|/v[er[sion]]] gives the version of this batch file.
[-[-]?|/?|-[-]h[elp]|/h[elp]] gives this help.
[-[-]pack] does the -fpack-struct and removes holes between structures.
[-[-]noopt|lowopt|-O|-O0|-O1|-O2|-O3|-O4] specifies optimization levels. -lowopt is same as -O. -O2 and -O3 on gcc used to generate bad code before gcc 4.6.0.
[-[-]lBASELIBNAME links in libBASELIBNAME.a (specifies a library to include).
[-[-]debug|-g], generate debug info in the executeable for debugging with gdb.  otherwise, it is stripped with -s -fstack-check to make smaller executeables.
[-[-]rc filename.rc] filename specifies a windows resource you wish to compile and automatically link in. in.
[-[-]windows] specifies a windows program.  can be used in conjunction with -console.
[-[-]console] specifies a console program  can be specified alone or with -windows.
[-[-]ass[embl]yver[sion] 1.0.0.0] specifies version number for manifest - should match your program's version number.  default is 1.0.0.0 or 0.0.0.0 and this fe
ature only works if you specify a manifest.  you myst manually give the build number in this batch file.
[-[-]ass[embl]yname Company.Product.Program] only works if you specify a manifest.  no spaces or tabs allowed.
[-[-]msvcrt90] specifies linking in with msvcrt90 library, which means dependency on the msvcrt90.dll, which gcc does not come with. prevents monolithc executab
les.
[-[-]usedll] do not make monolithic .EXE, use runtime DLL
[-[-]cpp0x|-[-]c++0x|-[-]c++11|-[-]cpp11] uses the -std=c++0x and -lstdc++ compiler switches and prevents monolithic executables, and copies libstdc++-6.dll wit
h the files.
[-[-]mono[lith[ic]]|-[-]static] uses the -lgcc and -static-libgcc compiler switches.
[-[-]stdcpp|-[-]stdc++] uses the -lstdc++ compiler switch.
[-[-]OS xpvista78|vista78] specifies the OS or collection of OS's that can run.  xpvista may or may not run on 9x/me.
errors and warnings are kept in the file errgw.

<someapp>.manifest.rc and <someapp>.manifest.res and and <someapp>.exe.manifest is created to make a manifest for vista/7 compatibility.
[-[-]manifest apptitle executionlevel uiaccess]
[-[-]manifest [-][-]default[s]]
executionlevel=asInvoker|highestAvailable|requireAdministrator
apptitle if it contains spaces or punctuation should be in double-quotes (").
uiaccess=true|false
manifest should be specified before exe name.
-manifest default or -manifest defaults is the same as -manifest asInvoker false
you will be prompted for manifest's app title.
if 64, copies and overwrites the required dll into the current directory.
see http://msdn.microsoft.com/en-us/library/bb756929.aspx for manifest documentation
there are 2 important dll's, libgcc_s_sjlj-1.dll and libstdc++-6.dll and there are 32 and 64-bit versions.  There is no easy/proper static linking for libstdc++
.
future note to self: ignore -stdc++ and handle it as default, since -lstdc++ is now a required part of the compiler.  nothing works without it.
example: gw 64 -stdc++ -os xpvista78 -pack -manifest "rattledisk - 5000 random disk seeks" asInvoker false -assyver 1.0.0.4950 -assyname JimMichaels.DiskWipe.Ra
ttleDisk rattledisk exe rattledisk.cpp biosdsk2.cc
example: gw 32 -stdc++ -os xpvista78 -manifest "convert phone letters to digits" asInvoker false -assyver 1.0.0.12 -assyname JimMichaels.Phone.Phone phone exe p
hone.cpp
example: gw -stdc++ -os xpvista78 netapp exe netapp.cpp -luser32 -lwsock32 -lws2_32
example: gw -stdc++ -os xpvista78 -manifest "network application" asInvoker false -assemblyversion 2.8.0.0 -assyname JimMichaels.NetSuite.NetApp netapp exe -rc
menus.rc netapp.cpp -luser32 -lwsock32 -lws2_32
example: gw -stdc++ -os xpvista78 -manifest -default -assyver 2.8.0.0 -assyname JimMichaels.NetSuite.NetApp netapp exe -rc menus.rc netapp.cpp -luser32 -lwsock3
2 -lws2_32
!edit top of gw.cmd to put in your PATH to MinGW bin\ directory etc.!

Sun 11/20/2011 16:42:51.42|C:\u|>

gw2.cmd docs

docs updated 5/19/2011 - always follow the built-in docs, they should be much more up-to-date and have more errors fixed or be more explanatory.

differences between gw.cmd and gw2.cmd:

  • 32 and 64 were removed as possible arguments.
  • this batch file now generates both 32 and 64-bit executables in sequence, the 32-bit stuff in the 32\ directory, and the 64-bit stuff in the 64\ directory.
    • DLLs now auto-copied into 32\ and 64\ directories.
    • specific EXEs automatically deleted and compiled into 32\ and 64\ directories.
    • error file errgw{32|64}{projectname} (the error file) now put into 32\ and 64\ directories. this means you don't have to rename it anymore.
  • it assumes AMD64 for processor architecture for 64-bit and x86 for processor architecture for 32-bit. you can edit this setting in one of the 2 environment variables (procarch32 and procarch64) if you wish.
  • procarch removed from if-switch section.
  • -assemblyversion (-assyver) is now specified by 3 numbers instead of 4 (example: 0.0.0). an autoincrement buildnumber (this is an environment variable) is automatically appended to put in the 4th number.
  • replaced default -lstdc++ compiler switch with -cpp or -c++
  • replaced default -std=c++0x compiler switch with -c++0x or -cpp0x
  • replaced default -lgcc and -static-libgcc compiler switches with -monolithic
  • better automation of handling semi-required DLL's (I think I got it right)
Sun 11/20/2011 16:37:38.76|C:\u|>gw2
if you need to reset gw2, do the following: gw2 --reset
-----environment variables set, including path.
gw2 - batch file compiler wrapper for MinGW-w64's g++ (C++) compiler.
usage:
    gw2 [-[-]?|/?|-[-]h[elp]|/h[elp]] [-[-]v[er[sion]]|/v[er[sion]]] [-reset|/reset]
    gw2 [-[-]mono[lith[ic]]|-[-]static] [-[-]cpp0x|c++0x|c++11|cpp11] [-[-]stdcpp|stdc++] [-[-]pack] [-[-]noopt|lowopt|-O|-O0|-O1|-O2|-O3|-O4] [-[-]windows] [-[
-]console] [-[-]debug|-g] [-[-]rc file.rc] [-[-]reset] [[-[-]manifest] [-[-]default[s]|app_title_string_in_double_quotes executionlevel uiaccess] [-[-]assemblyv
ersion 1.0.0] [-[-]msvcrt90] [-[-]lBASELIBNAME] baseNameOfEXEorDLLorOCX /exe|/dll|/ocx|[-][-]exe|[-][-]dll|[-][-]ocx sourcefile [sourcefile ...]

[-[-]v[er[sion]]|/v[er[sion]]] gives the version of this batch file.
[-[-]?|/?|-[-]h[elp]|/h[elp]] gives this help.
every switch can operate off of -, --, or / except the optimization switches.
defaults to -O (lowopt) optimization due to bad code generation at higher optimization levels!
[-[-]reset] resets the variables of this batch file (such as the path - path is sticky. necessary if you change batch file).
[-[-]pack] does the -fpack-struct and removes holes between structures.
[-[-]noopt|lowopt|-O|-O0|-O1|-O2|-O3|-O4] specifies optimization levels. -lowopt is same as -O. -O2 and -O3 on gcc used to generate bad code before gcc 4.6.0.
[-[-]lBASELIBNAME|lBASELIBNAME] links in libBASELIBNAME.a (specifies a library to include).
[-[-]debug|-g], generate debug info in the executeable for debugging with gdb.  otherwise, it is stripped with -s -fstack-check to make smaller executeables.
[-[-]rc filename.rc] filename specifies a windows resource you wish to compile and automatically link in. in.
[-[-]windows] specifies a windows program.  can be used in conjunction with -console.
[-[-]console] specifies a console program  can be specified alone or with -windows.
[-[-]msvcrt90] specifies linking in with msvcrt90 library, which means dependency on the msvcrt90.dll, which gcc does not come with.
[-[-]usedll] do not make monolithic .EXE, use runtime DLL
[-[-]cpp0x|-[-]c++0x|-[-]c++11|-[-]cpp11] uses the -std=c++0x and -lstdc++ compiler switches and prevents monolithic executables, and copies libstdc++-6.dll wit
h the files.
[-[-]mono[lith[ic]]|-[-]static] uses the -lgcc and -static-libgcc compiler switches.
[-[-]stdcpp|-[-]stdc++] uses the -lstdc++ compiler switch.
[-[-]os xpvista78|vista78] specifies the OS or collection of OS's that can run.  xpvista may or may not run on 9x/me.
errors and warnings are kept in the files 32\errgw and 64\errgw.

[-[-]ass[embl]yver[sion] 1.0.0] specifies version number for manifest - should match your program's version number.  default is 1.0.0 or 0.0.0 and this feature
only works if you specify a manifest.  the build number is set automatically at the top of this batch file and made the last 4th number.  it must be in this for
mat.
[-[-]ass[embl]yname Company.Product.Program] only works if you specify a manifest.  no spaces or tabs allowed.
<someapp>.manifest.rc and <someapp>.manifest.res and and <someapp>.exe.manifest is created to make a manifest for vista/7 compatibility.
[-[-]manifest apptitle executionlevel uiaccess]
[-[-]manifest [-][-]default[s]]
executionlevel=asInvoker|highestAvailable|requireAdministrator
apptitle if it contains spaces or punctuation should be in double-quotes (").
uiaccess=true|false
manifest should be specified before exe name.
-manifest default or -manifest defaults is the same as -manifest asInvoker false
you will be prompted for manifest's app title.
copies and overwrites the EXEs, errgw and required DLLs into the 64\ and 32\ directories.
see http://msdn.microsoft.com/en-us/library/bb756929.aspx for manifest documentation
there are 2 important dll's, libgcc_s_sjlj-1.dll and libstdc++-6.dll and there are 32 and 64-bit versions.  There is no easy/proper static linking for libstdc++
.
future note to self: ignore -stdc++ and handle it as default, since -lstdc++ is now a required part of the compiler.  nothing works without it.
example: gw2 -stdc++ -os xpvista78 -pack -manifest "5000 random disk seeks" asInvoker false -assyver 2.0.0 -assyname JimMichaels.DiskWipe.RattleDisk rattledisk
exe rattledisk.cpp biosdsk2.cc
example: gw2 -stdc++ -os xpvista78 -manifest "convert phone letters to digits" asInvoker false -assyver 3.19.39 -assyname JimMichaels.Phone.Phone phone exe phon
e.cpp
example: gw2 -stdc++ -c++11 -os xpvista78 netapp exe netapp.cpp -luser32 -lwsock32 -lws2_32
example: gw2 -stdc++ -c++11 -os xpvista78 -manifest "network application" asInvoker false -assemblyversion 2.8.0 -assyname JimMichaels.NetSuite.NetApp phone net
app exe -rc menus.rc netapp.cpp -luser32 -lwsock32 -lws2_32
example: gw2 -stdc++ -c++11 -os xpvista78 -c++11 -manifest -default -assyver 2.8.0 -assyname JimMichaels.NetSuite.NetApp netapp exe -rc menus.rc netapp.cpp -lus
er32 -lwsock32 -lws2_32
!edit top of gw2.cmd to put in your PATH to MinGW bin\ directory etc.!
Sun 11/20/2011 16:40:51.81|C:\u|>

include directory

mingw-w64's include directories are multiple instead of just one like normal compilers, so you will have your work cut out for you just finding the files or directories in question. from a cmd shell, do dir/s/b math.h or dir/s/b vector

c++ STL headers do not have a .h file extension on them for the most common ones like iostream and iomanip and fstream and ostream, vector, etc. older Borland compilers used .h on all their headers (in borland c++ 5.5.1, which I point to on this site), so you have have to switch those out in #ifdefs. That was 2006. I don't think any modern compiler uses .h in STL anymore.

libraries and library directory

mingw-w64's lib directories are multiple instead of just one like normal compilers, so you will have your work cut out for you just finding them. from a cmd shell, do dir/s/b libgdi32.a

microsoft and borland compilers simply name the libraries gdi32.lib according to the DLL names. mingw prepends the word lib and changes .lib to .a

if you need case-insensitve string compares for STL, BOOST has this, and it is available as a separate compile normally, but supposedly it is part of mingw (which mingw? I think it's the other one at mingw.org).

TR2 is coming, and it will include boost, which has case insensitive compares.

#include <boost/algorithm/iequals.hpp>
if (boost::iequals(str1, str2)) {
	//do something when case insensitive equal
}
but right now you must compile boost for yourself, or, if you have a microsoft compiler, install the binary which you probably have to pay for from boostpro.com.

how to build boost with bjam (msvc example - currently bjam does not recognize mingw)

packing structs with no holes

by default, the compiler will leave holes in your user-defined structs. to prevent this, use #pragma pack(). this is available on both gcc and VC++ and because it's on VC++, it's probably also on Borland.

glossary

i686 - 32-bit target cpu
x86_64 - 64 bit target cpu
4.8.2 - GCC version
release - GCC type
posix - threads
win32 - threads
dwarf - exception
rt_v3 - mingw-w64 runtime version
rev0 - build revision
SEH - only for 64-bit
DWARF - only for 32-bit
SJLJ toolchains are multilib and you can build 32 and 64 bit application with one toolchain.