/sw, to be compatible with fink. On a standard linux box, the prefix should probably be /usr/local. Keep this in mind if you try this on a Linux or Unix box.
Switch Explaination --buildThe architecture of the host OS (usually autodetected) --hostThe architecture of the OS that the resulting program will run on --targetThe architecture of the OS that this program is intended to work with
Note the subtle difference between the --host and --target flags.
When building a cross compiler, both bintuils and gcc are configured with the --target set to the target operating system, but since they are cross compilers, they will run on the local host OS.
Thus we don't specify anything for the --host option.
For building libraries and binaries with our cross compiler, we would specify both the --target and --host flags to be the target operating system because the libraries or binaries are intended to actually run on that platform.
The architecture designations used by autoconf configure scripts usually are in the following format:
architecture-vendor-os
Sometimes the vender tag is left out. The following are several examples of common architecture tags used:
When configuring, if you don't know the full vender tag, you can often just use the platform-os name.i386-redhat-linux ppc-yellowdog-linux ppc-apple-darwin i686-pc-cygwin i386-mingw32 i386-pc-mingw32 i686-pc-cygwin i386-linux i686-linux sparc-linux sparc64-linux arm-linux
You can either get the source code for binutils and gcc directly from the pristine sources at ftp.gnu.org, or you can extract them from the redhat (or whatever distro you want to cross-compile for) sources, in this case SRPMS. By extracting them from the SRPM, you can guarranty that your cross compiler will be exactly the same as the redhat official compiler, thus allowing it to be used in a distributed compile environment with greater success.
In addition, you will also need to extract the glibc libraries from the redhat binary rpms (you need the -devel and -headers rpms for the header files). Although you can compile glibc with your cross compiler, you will need to bootstrap the compiler itself with a binary glibc for that target platform.
I use mc to browse into the src.rpm file, and copy out the source tarball and the patches. Then, using the spec file, I patch the source trees for binutils and gcc just like redhat patched them.
After unpacking and patching binutils, run configure in the root of the source tree with the --target set to i386-redhat-linux:
After a./configure --prefix=/sw --target=i386-redhat-linux
make and a make install, you should find the following files:
The basic assembler, linker, and binary manipulation tools are now installed./sw/bin/i386-redhat-linux-addr2line /sw/bin/i386-redhat-linux-ar /sw/bin/i386-redhat-linux-as /sw/bin/i386-redhat-linux-c++ /sw/bin/i386-redhat-linux-c++filt /sw/bin/i386-redhat-linux-cpp /sw/bin/i386-redhat-linux-g++ /sw/bin/i386-redhat-linux-gcc /sw/bin/i386-redhat-linux-gcc-3.3.2 /sw/bin/i386-redhat-linux-gccbug /sw/bin/i386-redhat-linux-gcov /sw/bin/i386-redhat-linux-ld /sw/bin/i386-redhat-linux-nm /sw/bin/i386-redhat-linux-objcopy /sw/bin/i386-redhat-linux-objdump /sw/bin/i386-redhat-linux-ranlib /sw/bin/i386-redhat-linux-readelf /sw/bin/i386-redhat-linux-size /sw/bin/i386-redhat-linux-strings /sw/bin/i386-redhat-linux-strip /sw/i386-redhat-linux/bin/ /sw/i386-redhat-linux/share/ /sw/i386-redhat-linux/man/ /sw/i386-redhat-linux/info/ /sw/i386-redhat-linux/man/ /sw/i386-redhat-linux/lib/
The runtime files needed for any glibc-based linux cross-compiler target are all the libraries that are part of the glibc package that are in /lib and /usr/lib.
These files can be extracted directly from the glibc rpm using the wonderful mc file manager on a redhat linux machine.
Press ENTER to open the rpm within mc, and then press ENTER to open the contents.cpio file.
Inside that archive you will find the actual files. We need to copy /lib/lib* and /usr/lib/lib* all to the /sw/i386-redhat-linux/lib folder. Note that because we are flattening the library files out into one directory we will have to fix broken symlinks.
Header files usually come from glibc-devel and glibc-headers. Put all header files and subdirectories in /sw/i386-redhat-linux/include.
Unpack the gcc source code and patch to taste. Then, inside the gcc source root, it is important that you create a directory and run configure inside that directory. Do not run configure in the root of gcc, or you will have build problems. For example:
To determine the appropriate configure options, it is sometimes helpful to use the native gcc on the target platform to determine the options that it was built with. To do this, run gcc with a -v option:cd gcc-3.3.2-1 mkdir i386-redhat-linux cd i386-redhat-linux ../configure --prefix=/sw --target=i386-redhat-linux
Although most native gcc distributions will compile will all possible languages enabled, most often you only want C, C++ and possibly objc or java. Use the$ gcc -v Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.3.2/specs Configured with: ../configure --target=i386-redhat-linux --prefix=/usr --enable-languages=c,c++,objc --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit Thread model: posix gcc version 3.3.2 20031022 (Red Hat Linux 3.3.2-1)
--enable-languages switch to specify the languages you want the cross compiler to support.
Except for the --prefix switch, you can pass all the flags to configure that the native compiler used. Just add the appropriate --target switch.
A working example of configuration is the following:
After configure, a../configure --target=i386-redhat-linux --prefix=/sw \ --enable-languages=c,c++ --enable-shared --enable-threads=posix \ --with-system-zlib --enable-__cxa_atexit
make and make install will install the cross compiler. At this point your cross compiler will be available as i386-redhat-linux-gcc or i386-redhat-linux-g++ etc.
i386-redhat-linux-gcc -o hello hello.c
./configure --target=i386-redhat-linux --host=i386-redhat-linux
Build using./configure --prefix=/sw --target=i386-pc-mingw32
make and install using make install. The installation will create the following files and directories:
/sw/bin/i386-pc-mingw32-addr2line /sw/bin/i386-pc-mingw32-ar /sw/bin/i386-pc-mingw32-as /sw/bin/i386-pc-mingw32-c++ /sw/bin/i386-pc-mingw32-c++filt /sw/bin/i386-pc-mingw32-cpp /sw/bin/i386-pc-mingw32-g++ /sw/bin/i386-pc-mingw32-gcc /sw/bin/i386-pc-mingw32-gcc-3.3.1 /sw/bin/i386-pc-mingw32-gccbug /sw/bin/i386-pc-mingw32-gcov /sw/bin/i386-pc-mingw32-ld /sw/bin/i386-pc-mingw32-nm /sw/bin/i386-pc-mingw32-objcopy /sw/bin/i386-pc-mingw32-objdump /sw/bin/i386-pc-mingw32-ranlib /sw/bin/i386-pc-mingw32-readelf /sw/bin/i386-pc-mingw32-size /sw/bin/i386-pc-mingw32-strings /sw/bin/i386-pc-mingw32-strip /sw/i386-pc-mingw32/bin/ /sw/i386-pc-mingw32/share/ /sw/i386-pc-mingw32/man/ /sw/i386-pc-mingw32/info/ /sw/i386-pc-mingw32/man/ /sw/i386-pc-mingw32/lib/
/sw/i386-pc-mingw32 folder that the binutils install created:
The mingw runtime consists of stubs for the GNU linker to use that correspond to the basic MSVCRT.DLL and friends shared libraries. You don't actually need the DLL itself to build a program that dynamically link against it.cd /sw/i386-pc-mingw32 tar -xvzf /path/to/mingw-runtime.tar.gz
The other required component is the collection of header files. This is contained in the w32api-2.4.tar.gz file. All of the standard C and C++ header files are there, and also Microsoft-specific header files written from scratch by the mingw developers.
Untar the w32api tarball in the /sw/i386-pc-mingw32 directory just like we did with the runtime tarball:
cd /sw/i386-pc-mingw32 tar -xvzf /path/to/w32api-2.4.tar.gz
Configuring and making our mingw cross compiler would look like this:Reading specs from ../lib/gcc-lib/mingw32/3.2.3/specs Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable-languages=c++,f77,objc --disable-win32-registry --disable-shared --enable-sjlj-exceptions Thread model: win32 gcc version 3.2.3 (mingw special 20030504-1)
cd gcc-3.3.1-20030804-1 mkdir i386-pc-mingw32 cd i386-pc-mingw32 ../configure --prefix=/sw --target=i386-pc-mingw32 --with-gcc --with-gnu-ld \ --with-gnu-as --enable-threads --disable-nls --enable-languages=c++,f77,objc \ --disable-win32-registry --disable-shared --enable-sjlj-exceptions make make install
PREFIX/ARCH/lib.
In our case, that is /sw/i386-redhat-linux/lib.
Copy the libraries (complete with symlinks) just as they appear in the devel package.
Header files should all go in PREFIX/ARCH/include, for example, /sw/i386-redhat-linux/include.
.dll files. You do need the .dll.a stubs, however
pkg-config is a convenient way of dealing with include files and linker paths, and it works in a cross-compiling environment just as well as in a native environment, with a few caveats.
You do not want to use the same .pc files for the cross-compile target as you do for your native host.
If you do, the program may compile but it will not link.
Instead, put .pc files in PREFIX/ARCH/lib/pkgconfig. Then edit the pc file and make sure that the paths are set to your real paths as they really are in the cross-compiling environment. For example, a .pc file may say that its include path is /usr/include/gtk-2.0, but in the cross-compile environment it should be set to /sw/i386-redhat-linux/include/gtk-2.0 in this case.
Once pkg-config is set up right, simply set the PKG_CONFIG_DIR environment variable before you run configure or make the program.