(*) Or at least a bit easier.
Last weekend at the talk given by Rob Bishop of the Raspberry Pi Foundation at Austin Hackerspace, I got up and spoke a little about some work I’d been doing around cross-compiling for the Pi using LTIB (the Linux Target Image Builder). As LTIB has now made the Raspberry Pi an officially supported platform, I thought I’d write up something to introduce it to the community at large.
[ Update: See also my posts on Using QEMU to build for the Pi, and Using distcc to make cross-compiling for the Pi even easier! ]
First, some background:
When you build software on the same type of system that it’s going to run on, it’s called building natively. If you’ve been around Linux for a while, this is what you’re used to doing. You build on x86, for an x86 target.
Cross-compiling is when you build on one platform to run on another. Building on x86 for an ARM target like the Pi, for instance.
Why would I want to?
Speed! My desktop machine is something like 50 times faster than my Raspberry Pi. The Linux kernel takes about 3 hours to build natively on the Pi, and less than 10 minutes to build on my desktop machine.
What about Virtual Box, or QEMU?
Both are fine choices. I’ve done QEMU. It’s considerably faster than building natively on the Pi, but it still gets blown away by cross-compiling.
Are there disadvantages to cross-compiling?
Sure. The main one is that cross-compiling is much more complex than building natively or using an emulator. You have to get specialized versions of the C compiler, linker, etc. (collectively called the toolchain) for your host/target combination. You have to ensure that the package build system knows how to use the right toolchain. When it comes time to link your software, it must be against libraries that are also compiled for your target, which are going to be in directory locations other than the standard ones.
And some packages (I’m talking to you, Python, Apache, and MAME) weren’t written with cross compilation in mind. These packages might compile program A, and then run A on the build system in order to build programs B, C and D. So you have to know that A needs to be built for the x86, even though B, C and D are to be run on the Pi.
You have to dig in, root around, and hack things together to make things work. All in all, it can be a huge pain in the ass.
Wait! There’s hope!
There’s a project called LTIB (the Linux Target Image Builder) that is designed to make cross-compiling much easier. LTIB is designed to build an entire Linux distribution (really, a rootfs; it’s only a distro if you distribute it) for a variety of platforms using cross-compilers. It hides much of the complexity from you, and automates most of the task.
I was aware of LTIB because I used if for work. It was great, but it didn’t support the Pi.
As you can see from the screenshots above, LTIB uses the same menu interface as the Linux kernel. If you’re comfortable building a custom kernel, you’ll do just fine in LTIB.
LTIB lets you pick the toolchain, kernel, & userspace packages you want to install. You can even choose Busybox, instead of the full-sized versions of many common UNIX utilities. And you can add your own packages fairly easily, too!
LTIB downloads the source tarballs from a repository (or looks at places on your local network or disk), expands them, builds everything for the target architecture, and creates a root file system. In the Raspberry Pi’s case, LTIB will generate a bootable SD card image, ready to be copied to a card via dd.
On my desktop machine, I can build a basic image for the Pi from scratch, including the kernel, and write it to an SD card all in under 10 minutes. Subsequent builds are even faster since LTIB caches previous build output and rebuilds only what it needs to.
Sounds great, sign me up!
Go to LTIB.org and follow the download instructions. Bitshrine.org isn’t able to host the official RPi toolchains, so an RPM containing all three of them is available at https://github.com/downloads/midnightyell/RPi-LTIB/raspberrypi-tools-9c3d7b6-1.i386.rpm. You may either install this yourself via rpm -i, or place the rpm file in /opt/ltib/pkgs, and LTIB will install it for you on the first run.
How exactly do I run this thing?
For now, I refer you to the LTIB documentation. Once it’s installed, start with ./ltib -c
I’ll write up more step-by-step instructions in a later post. I’ll also write a walkthrough on how to add your own packages, and tips on getting LTIB to successfully cross-compile them.
Please keep in mind that LTIB for Pi isn’t perfect. Many of the supported packages are out-of-date. Some may not build. Not all of the packages have correct dependency information.
But if you need a low-memory usage Linux for your Pi, this is a hell of a start.
Why did you do this?
Mostly as a learning experience. I wanted to make my own cross-compiling toolchain and rootfs. I wanted to have Linux running in as little RAM as possible so that more would be available to my applications. And I had already been working on related things at work, so I was fairly far along the learning curve when I started.