MinGw on Linux - HOWTO author marco corvi date july 2004 version 1.0 history: 2004-08-03 mc release v. 1.0 MinGw is a minimal toolchain for cross-compiling windows applications on Linux. 1. Installing MinGW ------------------------------------------------------------------ [1] Building MinGW Basically you need four pieces to compose the toolchain - the runtime mingw-runtime - the windows API mingw32 - the binutils (as, ld, ar, nm, etc.) - the compiler gcc You can download these from the MinGW website www.mingw.org. Go to the download section and get the files from the current distribution. This HowTo has been tested with mingw-runtime-3.3.tar.gz w32api-2.5.tar.gz binutils-2.13.90-20030111.tar.gz gcc-core-3.3.1-20030804-1.tar.gz gcc-g++-3.3.1-20030804-1.tar.gz You can get the runtime and w32api from the mingw-3.0.1.src.rpm, however this lags a little behind the current distribution. For example, in my case it contained the 3.0 runtime and the 2.3 w32api. Once you have got the archives, create a directory for MinGW > mkdir MinGW; cd MinGW There create a BASE directory and a build directory, > mkdir mingw build Go to the BASE directory and uncompress the runtime and windows API, > cd mingw > tar -xzf ../../mingw-runtime-3.3.tar.gz > tar -xzf ../../w32api-2.5.tar.gz Note. I use the env BASE to denote the root directory where MinGW is built. Next go to build directory and make the binutils > cd ../build > tar -xzf ../../binutils-2.13.90-20030111.tar.gz > cd binutils-2.13.90 > ./configure --target=mingw32 --prefix=../../mingw --disable-shared > make "LDFLAGS+=-s" > make install Note that the utilities are build with static libraries. Additional config options: --disable-nls --with-gcc --with-gnu-as --with-gnu-ld Finally make the compiler > cd .. > tar -xzf ../../gcc-core-3.3.1-20030804-1.tar.gz > tar -xzf ../../gcc-g++-3.3.1-20030804-1.tar.gz > cd gcc-3.3.1 > export PATH=../../bin:$PATH > ./configure --target=mingw32 --prefix=../../mingw \ --enable-languages=c,c++ > make "LDFLAGS+=-s --stack=0x0080000" > make install Note that you must export the path to the mingw32 binutils to make them available to the compiler. Also there are several other useful options for the gcc configure (see gcc-3.3.1-build.sh on the download website): --disable-nls --enable-threads --disable-win32-resigtry --disable-shared --without-x --without-newlib --enable-hash-synchronization --enable-sjlj-exceptions If every thing went well now you have a cross-compiler for windows on your Linux system. ------------------------------------------------------------------- [2] Testing MinGW The first example in every programming textbook is HelloWorld. So let's compile this famous application. -------------- hello.c -------------------------- #include int main( int argc, char ** argv ) { int i; printf("Hello Windows: \n"); for (i=1; i mingw32-gcc -o hello.exe hello.c after that you should have an executable that you can transfer to a windows machine and run in a MS-DOS console window: The outcome of the program is as expected: C:\MinGW\test>hello 1 2 Hello Windows: 1 2 The next step is a window application, a message box, ------------- whello.c -------------------------- #include int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrev, PSTR szCmd, int iCmd ) { MessageBox( NULL, "Hello Windows", "Hello Demo", MB_OK ); return (0); } ------------------------------------------------- To compile this you need the additional flag "-mwindows" that says it is a window application, > mingw32-gcc -o whello.exe whello.c -mwindows When you run in (on a Windows machine) you get a nice message box with title "Hello Demo", the text "Hello Windows", and an "OK" button, ------------------------ | Hello Demo |X|| |------------------------| | | | Hello Windows | | ------------------ | | | O K | | | ------------------ | ------------------------ ------------------------------------------------------------------- [3] Behind MinGw You have the basic tools of the GNU toolchain, and most of the compile takes place in a friendly environment. If you get more interested in the process here is a Makefile that breaks the compilation into steps - translating the C source into assembly - creating the object file .o - linking it with the C runtime and the libraries The envs are BASE=/path/to/MinGW/mingw TARGET=mingw32 BASE_LIBS=${BASE}/lib BASE_INCS=${BASE}/include and the PATH contains the directory with the mingw32 tools. ------------- Makefile -------------------------- AS = $(TARGET)-as CC = $(TARGET)-gcc LD = $(TARGET)-ld STRIP = $(TARGET)-strip # CFLAGS += --verbose CFLAGS += -g -Wall -isystem $(BASE_INCS) -L$(BASE_LIBS) LDFLAGS += -static WIN = -mwindows CON = -mconsole BASE_GCC = ${BASE_LIBS}/gcc-lib/mingw32/3.3.1 # can use either crt1.o or crt2.o ??? XTART1 = ${BASE_LIBS}/crt1.o XTART2 = ${BASE_LIBS}/crt2.o XTART = ${XTART1} START = ${BASE_GCC}/crtbegin.o ENDS = ${BASE_GCC}/crtend.o GCCLIB = -L${BASE_GCC} -lgcc LIBS = $(GCCLIB) -liberty -lmingw32 -lkernel32 -lcrtdll -lmsvcrt WLIBS = -luser32 -lmingw32 EXES = hello.exe whello.exe default: $(EXES) hello.exe: hello.o $(LD) $(LDFLAGS) -o $@ ${XTART} ${START} $< ${LIBS} ${ENDS} whello:.exe whello.o $(LD) $(LDFLAGS) -o $@ ${XTART} ${START} $< ${WLIBS} ${LIBS} ${ENDS} hello.o : hello.s $(AS) -o $@ $< whello.o : whello.s $(AS) -o $@ $< whello.s : whello.c $(CC) $(CFLAGS) -S -o $@ $< ${WIN} %.s : %.c $(CC) $(CFLAGS) -S -o $@ $< # $(STRIP) $@ clean: rm -f core *.o *.s *.exe $(EXES) ------------------------------------------------- (1) The directory BASE/lib (ie, /path/to/MinGW/mingw/lib) cannot be just a symbolic link to BASE/mingw32/lib because the compiler resolves include searches by starting from it and going upward and down in the tree. Better make BASE/mingw32/lib a symlink to BASE/lib (2) There is no need to have a /usr/TARGET/(bin|lib|include) hierarchy. (3) nm (ie, BASE/bin/mingw32-nm) is useful to look for symbols inside the libraries. Go to BASE/lib and do for i in *.a; do \ echo $i; ../bin/mingw32-nm $i | grep "symbol"; \ done; | less (4) The gcc specs file, BASE/lib/gcc-lib/mingw32/3.3.1/specs, is another useful source of information about the compile process. (5) There are several C runtimes: those beginning with 'g' are for profiling, those ending with 'S' are for shared libraries In any case you can look at the sources of mingw-runtime to see what they do. ------------------------------------------------------------------- [4] Installing MinGW Installing MinGW means to set up the toolchain in a place where every user can use it. This place is denoted by the PREFIX env. Usually PREFIX=/usr/local. So we have to make a system-wide BASE=$(PREFIX)/MinGW, copy the build directories "bin", "include", and "mingw32" there, and make a symlink "lib" to "mingw32/lib", # cd $BASE # mkdir $PREFIX/MinGW # cp -R bin include mingw32 $PREFIX/MinGW # cd $PREFIX/MinGW # ln -s mingw32/lib lib (Probably you need to be root to do these). Now you are ready to build your Windows applications using the installed MinGW. You need to - define the TARGET env, export TARGET=mingw32 - put the cross-compiler tools in your PATH, export PATH=$(BASE)/bin:$(PATH) ------------------------------------------------------------------- [5] MinGW on Windows You can download the Windows installer of MinGW, MinGW-3.1.0-1.exe and install the suite. In my case i installed it in C:\MinGW. It consists of bin doc include mingw mingw32 uninstall "bin" contains the executables and the mingw dll. "include" has the header files to compile with gcc. "mingw" is empty (can use it to put your programs). "mingw32" has a few executables and loader scripts. Now you can compile hello.c and whello.c under windows, C:\MinGW\test>gcc -o hello.exe hello.c C:\MinGW\test>gcc -o whello.exe whello.c and run them (with the same output as before, of course).