Cross-compiling with Crossdev

Revision as of 18:53, November 2, 2014 by Sputnik (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Introduction

Crossdev is a great feature of Funtoo that allows you to easily make a basic toolchain for your embedded devices and alternate platform computers. It can be used for distcc for example, so a slow x86 or ARM computer can be assisted on compiles by a much faster x86_64 computer(s). Some, but not all, packages can also be compiled stand-alone without distcc on the faster machine. You can also use the faster 64 bit machine to make kernels for these slower machines, a big advantage.

This is quite a big subject and the aim of this article is mainly to help new users with some Funtoo specific things relating to cross-compiling that are unique to Funtoo. So we won't waste time here on things that are covered elsewhere, only those specific things.

Let's get started!

The first step is to install crossdev. Crossdev is written by Mike Frysinger who is quite a busy fellow and does a superb job. But occasionally there are little hiccups with crossdev. If ever you are having a problem with crossdev it doesn't hurt to try downgrading to previous versions. I say this because on the date this article is written, 11-1-14, there are issues with the two latest versions of crossdev - 20140917 and 20141030 (see https://bugs.funtoo.org/browse/FL-1703). But version 20140729 works flawlessly. I have seen this happen from time to time, nothing to worry about.

# emerge -av crossdev

Funtoo Specific Considerations

The most important thing to understand is that Funtoo gcc ebuilds are different from Gentoo ebuilds. This is because Daniel Robbins has made improvements to gcc to help with general usage. Unfortunately, a side effect has been that they no longer work with crossdev. But not to worry, there is an easy way around this issue and my understanding is that Funtoo intends to rectify it at a later date.

Another issue is that you cannot have a toolchain with exactly the same minor number as the current gcc on your system. You must use an ebuild of a slightly different vintage. I believe this issue occurs for Gentoo users also. For example, at the present time Funtoo current uses sys-devel/gcc-4.8.2-r3. So you could use gcc-4.8.1, or 4.8.0 but not any version of 4.8.2 (the revision -rx doesn't matter, can't do it). If you try to do that gcc will compile and then fail in the installation phase due to file collisions. In some cases with embedded devices you may wish to use much older versions, in which case this becomes a moot point.

Finally, a general issue with using crossdev with any distro is that you must sometimes juggle the various versions of binutils, gcc, glibc and linux-headers so that they are compatible with one another. This is the easiest problem to deal with, just use versions of the same time vintage, in extreme cases you may need to start changing revisions to get all of them to compile.

That's it, that's what you need to know.

GCC Ebuilds

The workaround to make gcc compile is to use Gentoo gcc ebuilds. They are readily available at the Gentoo attic: http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/?hid Going back historically for as far as you'd ever need. Go to the sys-devel/gcc folder and right click on a version and copy the link. I suggest a version that isn't even in the Funtoo tree, then there is no ambiguity about what is being used. Next copy it to your local repository, we'll assume /usr/local/portage here. So if you haven't already got a sys-devel/gcc directory there you could do

# install -d /usr/local/portage/sys-devel/gcc

Now go to that directory in your terminal and wget <the link you copied>. At the end will be some fluff you don't want, delete all the way back to the word .ebuild and hit enter. In a second or so you'll have that ebuild in your repository. If you haven't done this before you'll need to link the files directory from the tree, so that it can find patches, etc. So do this

# ln -s /usr/portage/sys-devel/gcc/files .

Finally you must create the manifest

# ebuild gcc-<version>.ebuild manifest

And now you are ready!

Really, that's it?

Yes. Well, one other thing that you may need to do, if you've chosen a gcc version that is in the Funtoo tree, crossdev may get confused and try to install the tree version. At the beginning of the crossdev run it creates links in the crossdev repository, most people will just want this to be their local repository. So you can let crossdev run for a few seconds to create those links and then cancel it with ctl-c. Then go to the crossdev repository and delete the gcc link and replace it with a link to /usr/local/portage/sys-devel/gcc. Here's an example in my local repository:

# ls -l /usr/local/portage/cross-avr
total 0
lrwxrwxrwx 1 root root 50 Nov  1 00:41 avr-libc ->/usr/portage/dev-embedded/avr-libc
lrwxrwxrwx 1 root root 47 Nov  1 00:41 binutils -> /usr/portage/sys-devel/binutils
lrwxrwxrwx 1 root root 32 Nov  1 00:41 gcc -> /usr/local/portage/sys-devel/gcc
lrwxrwxrwx 1 root root 42 Nov  1 00:41 gdb -> /usr/portage/sys-devel/gdb

Note that the link for gcc is different from the others, which point to the normal Funtoo Portage tree, it points to my local repository, where the Gentoo ebuilds are stored. Most of the time also you would be linked to sys-libs/glibc, avr-libc is a bit unusual but normal for avr cross toolchains.

Once the link is fixed (if it even needed fixing), just hit your up arrow to get the same crossdev command line again and let it run through this time. You'll be rewarded with a shiny new cross toolchain at the end..

Of course, there is a bit more to making a cross toolchain, but as stated at the beginning of this article, only the unique differences for Funtoo are shown here. You should find nearly all the rest you need to know at https://www.gentoo.org/proj/en/base/embedded/handbook/cross-compiler.xml?style=printable. Only the top 1/4 page is needed.

One note, at the current time (11-1-14) you need to preface your crossdev command line statement with USE="-sanitize". This is a known bug (not Funtoo specific) that will soon be fixed in crossdev. You will find -sanitize in the package.use files, but you still must do it on the command line, else gcc will fail. For example the following command line was successful for me today

# USE="-sanitize" crossdev --binutils 2.23-2 --g 4.8.1-r1 --l 1.8.0 -t avr -P -v