Cross Compiling from Linux
I prefer doing my development from linux, but I would still like to compile my software for other architectures (OSX, Windows, perhaps dos). Especially if I can build Makefile scripts so one command can build for all architectures.
- x86_64-w64-mingw32 (Windows 32bit & 64bit)
- i686-pc-mingw32 (Windows 32bit)
- x86_64-apple-darwin10 (OSX 10.6 32bit & 64bit)
- i586-pc-msdosdjgpp (Dos 32bit)
- x86_64-ubuntu1204-linux-gnu (Linux Deb based distro [ubuntu/debian])
x86_64-w64-mingw32 (Windows 32bit & 64bit)
The mingw-w64 project has been a godsend, it allows me to compile 32bit & 64bit software in the same toolchain. I believe it can also target WinCE, but I have yet to attempt this. gcc can link directly to dll files (if the symbol table is present). At the time this was posted, there seems to be 2 choices, trunk and the 1.0 snapshot. This was modified from my i686-pc-mingw32 toolchain, with some information from http://sourceforge.net/apps/trac/mingw-w64/wiki/Cross%20Win32%20and%20Win64%20compiler
Downloads
- Binutils 2.23.1 - ftp://ftp.gnu.org/gnu/binutils/binutils-2.23.1.tar.bz2
- GCC 4.8.0 - ftp://ftp.gnu.org/gnu/gcc/gcc-4.8.0/gcc-4.8.0.tar.bz2
- mingw-w64-v2.0.7 - http://downloads.sourceforge.net/project/mingw-w64/mingw-w64/mingw-w64-release/mingw-w64-v2.0.7.tar.gz
MingwRT Headers
GCC Requires some files from the mingw package to compile, so we will install them first
- cd mingw-w64-headers
- ./configure --prefix=/usr/x86_64-w64-mingw32/sysroot --host=x86_64-w64-mingw32
- make install
- ln -s x86_64-w64-mingw32 /usr/x86_64-w64-mingw32/sysroot/mingw
- install -d -m755 /usr/x86_64-w64-mingw32/sysroot/mingw/lib
Binutils
- mkdir build
- cd build
- ../configure --prefix=/usr --target=x86_64-w64-mingw32 --with-sysroot=/usr/x86_64-w64-mingw32/sysroot --enable-targets=x86_64-w64-mingw32,i686-w64-mingw32
- make
- make install
GCC Pass1
We will start by compiling a basic gcc compiler, just enough to compile the mingw headers. The full gcc suite requires us to install the mingw headers/libraries first
- mkdir build
- cd build
- ../configure --prefix=/usr --target=x86_64-w64-mingw32 --enable-languages=c,c++ --libexecdir=/usr/lib --disable-static --enable-threads=win32 --with-sysroot=/usr/x86_64-w64-mingw32/sysroot --enable-targets=all --with-cpu=generic
- make all-gcc
- make install-gcc
MingwRT Libraries
Now a full install of the mingw headers and libraries
- cd mingw-w64-crt
- ./configure --prefix=/usr/x86_64-w64-mingw32/sysroot --host=x86_64-w64-mingw32
- make
- make install
GCC Pass2
And now to do a full gcc install
- mkdir build
- cd build
- ../configure --prefix=/usr --target=x86_64-w64-mingw32 --enable-languages=c,c++ --libexecdir=/usr/lib --disable-static --enable-threads=win32 --with-sysroot=/usr/x86_64-w64-mingw32/sysroot --enable-targets=all --with-cpu=generic
- make
- make install
i686-pc-mingw32 (Windows 32bit)
I no longer use this compiler for my own projects, This will build a 32bit linux to windows toolchain using binutils/gcc/mingw, and in theory x86_64-w64-mingw32 should be able to do anything this compiler did
Cavets: The mingw32 project targets an earlier gcc. This information is here for historic information.
Downloads
- Binutils 2.20.1 - ftp://ftp.gnu.org/gnu/binutils/binutils-2.20.1.tar.bz2
- GCC 4.5.1 - ftp://ftp.gnu.org/gnu/gcc/gcc-4.5.1/gcc-4.5.1.tar.bz2
- Mingw32 Runtime 3.18 - http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/RuntimeLibrary/MinGW-RT/mingwrt-3.18/mingwrt-3.18-mingw32-src.tar.gz
- Win32 API 3.15-1 - http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/RuntimeLibrary/Win32-API/w32api-3.15/w32api-3.15-1-mingw32-src.tar.lzma
Patches
- http://nathancoulson.com/proj/cross/mingwrt-3.18-disable_thrd-1.patch: Disabled libmingwthrd.a, which will not build until after gcc pass2
- http://nathancoulson.com/proj/cross/w32api-fix_include_path-1.patch: Fixes the include path so that this package will compile
Binutils
- mkdir build
- cd build
- ../configure --prefix=/usr --target=i686-pc-mingw32 --with-sysroot=/usr/i686-pc-mingw32
- make
- make install
GCC - Pass 1
Without the mingw headers & libraries installed, we can only build a minimal gcc at this time.
- mkdir build
- cd build
- mkdir -p /usr/i686-pc-mingw32/sys-root/mingw/include
- ../configure --prefix=/usr --target=i686-pc-mingw32 --enable-languages=c --with-sysroot=/usr/i686-pc-mingw32/sys-root --libexecdir=/usr/lib --disable-static --disable-threads --without-headers
- make all-gcc install-gcc
Win32 API
To compile, this requires us to have an extracted mingw tarball at ../mingw. It also requires a patch to fix a -I path
- tar -xzf ../mingwrt-3.18-mingw32-src.tar.gz -C ..
- mv ../mingwrt-3.18-mingw32 ../mingw
- patch -Np1 -i ../w32api-fix_include_path-1.patch
- ./configure --prefix=/usr/i686-pc-mingw32
- make BUILDENV=mingw
- make install
Mingw Runtime - Pass 1
Unfortunately, we cannot compile the libmingwthrd.a until we install the full GCC suite. For now, just disable it. This package does not use gcc's search paths, so we force it to search in the sys-root for the w32api files
- patch -Np1 -i ../mingwrt-3.18-disable_thrd-1.patch
- CFLAGS="-g -O2 -I /usr/i686-pc-mingw32/sys-root/mingw/include" ./configure --prefix=/usr/i686-pc-mingw32/sys-root/mingw --host=i686-pc-mingw32
- make
- make install
GCC - Pass 2
Now that we have the mingw & win32 headers & libraries installed, we can build a fully functional gcc
- mkdir build
- cd build
- mkdir -p /usr/i686-pc-mingw32/sys-root/mingw/include
- ../configure --prefix=/usr --target=i686-pc-mingw32 --enable-languages=c,c++ --with-sysroot=/usr/i686-pc-mingw32/sys-root --libexecdir=/usr/lib --disable-static --enable-threads=win32
- make all-gcc install-gcc
Mingw Runtime - Pass 2
And of course, build the entirety of the mingw runtime
- CFLAGS="-g -O2 -I /usr/i686-pc-mingw32/sys-root/mingw/include" ./configure --prefix=/usr/i686-pc-mingw32/sys-root/mingw --host=i686-pc-mingw32
- make
- make install
x86_64-apple-darwin10 (OSX)
A linux to OSX Cross Compiler. By default, targets 64bit osx, but if you pass -m32 to gcc, it will compile for 32bit. I use odcctools for the linker, and gcc. Most of the articles I have read, suggest that using apple's version of gcc will lead to less headaches in the future, but I have not done any research into installing apple's gcc on a linux machine. It looks like odcctools upstream is no longer being updated, as there are later versions of cctools. At this time, GCC 4.7.1 failed to work as it was calling -no_compact_unwind. It looks like this flag is not present in the cctools used by odcctools.
Below is a list of related links, that may be of use
- http://devs.openttd.org/~truebrain/compile-farm/apple-darwin9.txt: openttd's direction on building a compiler targeting i686-apple-darwin9.
- http://svn.macosforge.org/repository/odcctools/: odcctools svn repository (Looks like it is maintained by Peter O'Gorman. An email sent to the gcc list has some further information http://gcc.gnu.org/ml/gcc/2009-08/msg00142.html
Downloads
- https://developer.apple.com/ios/download.action?path=/ios/ios_sdk_4.1__final/xcode_3.2.6_and_ios_sdk_4.3.dmg: libc & friends. This requires a Mac Dev account
- svn co http://svn.macosforge.org/repository/odcctools/trunk/ [I used Revision 159]
- GCC 4.6.3 - ftp://ftp.gnu.org/gnu/gcc/gcc-4.6.3/gcc-4.6.3.tar.bz2
Libraries
The download for xcode, is in the form of a image, and requires a bit of processing to access.
- dmg2img xcode-3.2.6_and_ios_sdk_4.3.dmg #convert to a .img file
- mkdir xcode
- mount xcode_3.2.6_and_ios_sdk_4.3.img xcode -o loop,offset=36864
Now, we need to extract the libraries
- xnu -xf Packages/MacOSX10.6.pkg
- gunzip Payload -c | cpio -i
- cp -a SDKs/MacOSX10.6.sdk/* /usr/x86_64-apple-darwin10/sysroot
- install -d -m755 /usr/x86_64-apple-darwin10/sysroot
- ln -s ../System/Library /usr/x86_64-apple-darwin10/sysroot/Frameworks
odcctools
Note: This requires gcc-4.4.6 or earlier, compiled for a 32bit host. I had some linking problems to libLTO.so, so I temporairly moved it
Binutils at this time, does not have enough support for Mach-O at this time. It does not sound like this is a goal for binutils to support.
- CC="gcc-4.4.6 -m32" CXX="g++-4.4.6 -m32" ./configure --prefix=/usr --target=x86_64-apple-darwin10 --with-sysroot=/usr/x86_64-apple-darwin10/sysroot
- make -C libstuff
- make -C ld64 SSL_LIBS="-lssl -lcrypto -ldl" # Otherwise complains that libdl is not found
- make
- make install
GCC
It appears that the latest gcc has some tests that do not like to run when cross compiling. To get around this, I set the variables manually in a config.cache file (Allows building libobjc), as well as applying a patch I found at GCC Bug 47836. There is a thread discussing the situation at http://gcc.gnu.org/ml/gcc/2011-03/msg00461.html which shows the workaround below. objc++, and c++ have simular failures that can be worked around, but I have yet to research that.
- mkdir -p x86_64-apple-darwin10/{i386/,}libobjc
- echo -e "gcc_cv_have_tls=yes\ngcc_cv_have_tls_set=set\nlt_cv_ld_exported_symbols_list=no" > x86_64-apple-darwin10/libobjc/config.cache
- echo -e "gcc_cv_have_tls=yes\ngcc_cv_have_tls_set=set\nlt_cv_ld_exported_symbols_list=no" > x86_64-apple-darwin10/i386/libobjc/config.cache
- mkdir gcc-build
- cd gcc-build
- ../configure --prefix=/usr --target=x86_64-apple-darwin10 --enable-languages=c,objc --libexecdir=/usr/lib --with-sysroot=/usr/x86_64-apple-darwin10/sysroot --with-as=/usr/bin/x86_64-apple-darwin10-as --disable-libssp --disable-libquadmath --disable-libgomp
- make
- make install