% Iris: micro-kernel for a capability-based operating system.
% cross-compiler.tex: Cross-compiler building instructions.
% Copyright 2009 Bas Wijnen <wijnen@debian.org>
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.

\documentclass{shevek}
\begin{document}
\title{Setting up a cross-compiler}
\author{Bas Wijnen}
\date{\today}
\maketitle
\begin{abstract}
This report details how I have set up a cross-compiler.  Since it was not
trivial, I think it may be useful for others.  After reading this, you should
be able to set up a cross-compiler yourself.  It is assumed that the host computer, where the compiler should be running, is a Debian machine.
\end{abstract}

\tableofcontents

\section{Introduction}
A cross-compiler is a compiler which builds code that should be run on a different platform.  This can be useful for building code for embedded devices which are incapable of running a compiler themselves, or where it is not practical to do so.  If you are reading this, you probably need one.  I'm sure you know why you do.  Possibly you have also found out that it is not trivial to set it up.  This is a step by step report of how I set up a cross-compiler for mipsel.  All problems I encountered (and solved) are explained.

A cross-compiler needs cross-binutils and some system libraries.  I shall first describe how to install these.

\section{Binutils}
To create a cross-compiler, cross-binutils are needed.  They must be built from
source.  I did \verb+apt-get source binutils+ to get the sources, then I cd'd into the source directory and did
\verb+TARGET=mipsel-linux-gnu fakeroot debian/rules binary-cross+ to build and
in the original directory \verb+dpkg -i *.deb+ (as root) to install them.

\section{System libraries}
libc6-dev and some other libraries must be installed in cross versions.
\textit{dpkg-cross} is used to build and install them.  However, that doesn't
resolve dependencies, and can't download files from a mirror.  So that's a
problem.  Furthermore, once the compiler is working, other cross-libraries may
be required for the actual cross-building.  Then again, the dependencies must
be resolved.  It is not practical to do that by hand.

For this purpose, I wrote a script which resolves dependencies of a packages,
filters them to remove the unneeded ones, downloads them and installs them with
dpkg-cross.  This is very hackish: it uses human-readable output of programs
like apt-cache to do its work.  This output can change its format, I suppose.
But so far I didn't find any other way, so it'll have to do.  At least it works
for me.  Note that the user running the script must be allowed to run
dpkg-cross as root using sudo.  This is achieved (for anyone, not just that
user) by adding to /etc/sudoers \verb+ALL ALL=NOPASSWD:/usr/bin/dpkg-cross+.

In /etc/dpkg-cross/cross-compile, you will need to add your gcc version to the
keepdeps line, in my case \verb+gcc-4.2-base+.  This didn't seem to be possible
with command line options (so the comment above that block probably refers only
to the removedeps line).

When this is done, cross-libraries can be installed using the script.  I needed
\verb+./cross-install libc6-dev libc6-dev-mips64 libc6-dev-mipsn32+.  This
results in packages with those names and \verb+-mipsel-cross+ appended.

\section{Gcc}
For gcc, I did \verb+apt-get source gcc-4.2+ (4.3 didn't work), followed by
\verb+export GCC_TARGET=mipsel+ and \verb+export DEB_CROSS_INDEPENDENT=yes+.
Then in the source directory \verb+debian/rules control+, and finally
\verb+dpkg-buildpackage -uc -us -b -rfakeroot+ and of course
\verb+dpkg --install *.deb+ in the original directory.  This failed for
gobjc++-4.2, which I didn't need anyway, so I removed it again.

That results in a cross compiler which can be called using
\verb+mipsel-linux-gnu-gcc+.

\section{Conclusion}
Setting up a cross-compiler is much harder than it should be.  Especially
sorting out the dependencies and downloading libraries is very hard.  It would
be good if this would be made easier.  My cross-install script does this, but
in a fragile and hackish way.  However, it does result in a usable
cross-building environment, where new libraries for cross-building can be
easily installed.

\end{document}
