Cross Compiling

From Gnash Project Wiki

Jump to: navigation, search

How To Cross Compile Gnash & Cygnal

It seems like these days I get several requests for Gnash cross-compiling help weekly, so I thought I'd try to collect everything in one place. This will focus primarily on the ARM, as that seems to be what all the questions are about. There are several varieties of ARM processors, including the TI DaVinci, SnapDragon, i.MX51, to name a few.

It may be possible to build Gnash native on your target system, I do this all the time for anything at or over 400Mhz. While this may be slow (many hours to compile Gnash), you save much frustration, which is often worth the additional time. This works especially well for embedded GNU/Linux targets running a Debian or BSD derived distribution.

Other common ways of using a "fake" native system to cross compile are systems that use a target chroot to look native, but build cross. A well known system that works this way is OpenEmbedded. For OpenEmbedded builds of Gnash, look for the included bbfile, or there is another copy in the Gnash git sources. Another well known one is ScratchBox.

Unlike some applications, Gnash is designed to be cross-compiled. All this really takes is paying attention when configuring and building that all your paths are setup correctly to get only files for the target architecture. A common problem with many applications when cross compiling is that they accidentally try to link in native files instead of target ones.

Part of the fun of cross compiling isn't with Gnash. At least Gnash knows when it's being cross compiled, many of the popular libraries used on GNU/Linux systems do not. As a multimedia application, Gnash uses more than a few other libraries, like boost and libcurl. Getting these to cross compile is the main headache. For some targets, you may be able to use the sysroot I developed for Android. You may also be able to pick and choose headers and libraries from this [Android sysroot] and use them in your own custom sysroot. My warning on this is your mileage may vary... as these were primarily targeted towards working with my custom [Android Toolchain]

If you do build a custom sysroot, you may find these next links useful, as they cover what I've had to do for the Gnash Android port. The more generic help is on: [Building dependant packages], with the Android specific target info, that may be useful to others anyway, is at: [Android Dependencies].

While there are several ways to cross compile, Gnash uses a traditional GNU style sysroot. A Sysroot is simply a directory tree with all your files from include, lib, and share. If you look at your native system, you'll see these directories under /usr. This is the top level of your native sysroot in a sense. When configuring and compiling, the needed system files are looked for in /usr/include, /usr/lib, etc... So when cross configuring, you need to specify an alternate sysroot to where these files are for your target system. The option to change the sysroot from /usr when configuring Gnash is --with-sysroot=[path], where [path] is usually something like /usr/local/armel-linux. This will then be used as the top level directory for all the dependencies.

A sysroot is different from a chroot. A sysroot contains mostly just data files, like headers and libraries. A chroot is an entire installation of an operating system. Unlike a sysroot, a chroot contains all the system executables, utilities, and applications. While a chroot works well for building Gnash under alternate distributions of the same architecture, it doesn't work well when dealing with a target architecture that is substantially different than your build system.

So with Gnash, you also get to configure various other target specific features like the media handling layer, the user interface toolkit, and the renderer. The lets the developer tailor the configuration of Gnash to match the target. By default Gnash configures to use Gstreamer for media handling, AGG or Cairo for software rendering, and GTK and KDE4 toolkit support for GNOME and KDE.

I see a mix of target configurations, but these are usually either GTK and X11 based, regardless of the processor clock speed, or they don't use X11 at all, but instead use the framebuffer. The majority of framebuffer based devices don't support any hardware acceleration, so you need to use AGG or Cairo. For most applications, AGG is faster and has a smaller footprint than Cairo, especially if you aren't using GTK. As GTK uses Cairo anyway, for GTK that may be a better solution, you'll have to decide yourself.

Currently Gnash does support hardware acceleration of graphics using OpenGL, but the current quality of the rendering is poor, and the offloading to the GPU could be improved heavily. Work is being done on an OpenGLES renderer for Gnash, that will work much better on mobile devices like smartphones.

For hardware video decoding, Gnash uses VAAPI. This currently only works with the ffmpeg media handler, so to use this you'll need a recent version of ffmpeg, and libva. This only works with the newer graphics cards, many aren't supported. At this link can get more information on hardware video decoding support in Gnash. Ffmpeg also has better performance and a smaller footprint than Gstreamer as well, so it's commonly used on mobile devices.

Input Devices

When running Gnash without X11, you need to configure in support for input devices, like mice, touchscreen, or a keyboard. These devices are all probed for, and should automatically configure themselves correctly when running in a raw frame buffer. The default uses either a ps2 style keyboard and mouse (the little round connector), or a USB based one. The linux input event sub system is also supported. You can limit what is auto probed at configuration time with this option: --enable-input=touchscreen,events

Example

There is a wealth of target specific build information on the [Building Gnash] page on this wiki. You might want to see if your target has any existing notes on how to build for it.

So anyway for our example, let's assume we have our sysroot installed in /usr/local/armel-linux. Let's also pick a standard configuration, software renderer, ffmpeg for media, and a raw frame buffer. I'd configure Gnash like this:

../src/gnash/configure --enable-media=ffmpeg --enable-gui=fb --enable-renderer=agg \
--with-sysroot=/usr/local/arm/linux

This will build an executable that doesn't use X11, and should work for most target systems. It will use headers from /usr/local/arm-linux/include, and libraries from /usr/local/arm-linux/lib. Because it is using a framebuffer, input devices are also enabled for the build with the default set of supported devices.