Using Sourcery G++ Lite for ARM GNU/Linux

Target Kernel Requirements

The GNU C library supplied with Sourcery G++ Lite uses the new EABI-based kernel syscall interface. This means applications compiled with Sourcery G++ require at least a 2.6.16 kernel with EABI syscalls enabled.

Compiling for ARMv4t systems

By default Sourcery G++ generates Linux binaries that require an ARMv5 or later CPU. To build applications or libraries capable of running on ARMv4t CPUs, use the -march=armv4t command-line option.

Runtime libraries suitable for ARMv4t systems are supplied in the armv4t subdirectory.

Code compiled for ARMv4t is ABI compatible with ARMv5 code. Code and binaries compiled for different architectures may be mixed freely.

Caution

There are several other ways to tell the compiler to generate ARMv4t code. However -march=armv4t must be used when linking to ensure the correct libraries and startup code are selected.

NEON SIMD Code

Sourcery G++ includes preliminary support for automatic generation of NEON SIMD vector code. Autovectorization is a compiler optimization where loops involving normal integer or floating-point code are transformed into loops that use NEON SIMD instruction to process several data elements at once.

To enable generation of NEON vector code specify -ftree-vectorize -mfpu=neon -mfloat-abi=softfp. -mfpu=neon also enables generations of VFPv3 scalar floating-point code.

Sourcery G++ also includes preliminary support for manual generation of NEON SIMD code using C intrinsic functions. These intrinsics, the same as those supported by the ARM RVCT compiler, are defined in the arm_neon.h header and are documented in the 'ARM NEON Intrinsics' section of the GCC manual. The options -mfpu=neon -mfloat-abi=softfp must be specified to use these intrinsics; -ftree-vectorize is not required.

NEON support is still under active development. It has not been subject to extensive testing, and may not yet take full advantage of all the features provided by the NEON architecture.

Using Sourcery G++ Lite on GNU/Linux Targets

In order to run and debug programs produced by Sourcery G++ on a GNU/Linux target, you must install runtime support files on the target. You may also need to set appropriate build options so that your executables can find the correct dynamic linker and libraries at runtime.

The runtime support files, referred to as the sysroot, are found in the arm-none-linux-gnueabi/libc directory of your Sourcery G++ Lite installation. The sysroot consists of the contents of the etc, lib, sbin, and usr directories. There may be other directories in arm-none-linux-gnueabi/libc that contain additional sysroots customized for particular combinations of command-line compiler flags, or multilibs. Refer to the section called “Library Configurations” for a list of the included multilibs in this version of Sourcery G++ Lite.

There are three choices for installing the sysroot on the target:

  • You can install the files in the filesystem root, replacing the system-provided files. All applications automatically use the Sourcery G++ libraries. This method is primarily useful when you are building a GNU/Linux system from scratch. Otherwise, overwriting your existing C library may break other applications on your system, or cause it to fail to boot.

  • You can install the sysroot in an alternate location and build your application with the -rpath and --dynamic-linker linker options to specify the sysroot location.

  • You can install the sysroot in an alternate location and explicitly invoke your application through the dynamic linker to specify the sysroot location. If you are just getting started with Sourcery G++ Lite, this may be the easiest way to get your application running, but this method does not support use of the debugger.

Setting the environment variable LD_LIBRARY_PATH on the target is not sufficient, since executables produced by Sourcery G++ depend on the Sourcery G++ dynamic linker included in the sysroot as well as the Sourcery G++ runtime libraries.

Installing the Sysroot

If you are modifying an existing system, rather than creating a new system from scratch, you should place the sysroot files in a new directory, rather than in the root directory of your target system.

If you choose to overwrite your existing C library, you may not be able to boot your system. You should back up your existing system before overwriting the C library and ensure that you can restore the backup even with your system offline.

When running Sourcery G++ on a GNU/Linux host, you have the alternative of installing the sysroot on the target at the same pathname where it is installed on the host system. One way to accomplish this is to NFS-mount the installation directory on both machines in the same location, rather than to copy files.

In many cases, you do not need to copy all of the files in the sysroot. For example, the usr/include subdirectory contains files that are only needed if you will actually be running the compiler on your target system. You do not need these files for non-native compilers. You also do not need any .o or .a files; these are used by the compiler when linking programs, but are not needed to run programs. You should definitely copy all .so files and the executable files in usr/bin and sbin.

You need to install the sysroot(s) corresponding to the compiler options you are using for your applications. The tables in the section called “Library Configurations” tell you which sysroot directories correspond to which compiler options. If you are unsure what sysroot is being referenced when you build your program, you can identify the sysroot by adding -v to your compiler command-line options, and looking at the --sysroot= pathname in the compiler output.

Using Linker Options to Specify the Sysroot Location

If you have installed the sysroot on the target in a location other than the file system root, you can use the -rpath and --dynamic-linker linker options to specify the sysroot location.

First find the correct sysroot directory and dynamic linker for your selected multilib. Refer to the section called “Library Configurations”. In the following steps, sysroot is the absolute path to the sysroot directory on the target corresponding to your selected multilib. For the default multilib, the dynamic linker path relative to the sysroot is lib/ld-linux.so.3. This is used in the example below.

If you are using Sourcery G++ from the command line, follow these steps:

  1. When invoking arm-none-linux-gnueabi-gcc to link your executable, include the command-line options:

    -Wl,-rpath=sysroot/lib:sysroot/usr/lib \
    -Wl,--dynamic-linker=sysroot/lib/ld-linux.so.3

    where sysroot is the absolute path to the sysroot directory on the target corresponding to your selected multilib.

  2. Copy the executable to the target and execute it normally.

Note that if you specify an incorrect path for --dynamic-linker, the common failure mode seen when running your application on the target is similar to

> ./hello
./hello: No such file or directory

or

> ./hello
./hello: bad ELF interpreter: No such file or directory

This can be quite confusing since it appears from the error message as if it is the ./hello executable that is missing rather than the dynamic linker it references.

Specifying the Sysroot Location at Runtime

You can invoke the Sourcery G++ dynamic linker on the target to run your application without having to compile it with specific linker options. To do this, follow these steps:

  1. Build your application on the host, without any additional linker options, and copy the executable to your target system.

  2. Find the correct sysroot directory and dynamic linker for your selected multilib. Refer to the section called “Library Configurations”. In the following steps, sysroot is the absolute path to the sysroot directory on the target corresponding to your selected multilib. For the default multilib, the dynamic linker is lib/ld-linux.so.3. This is used in the example below.

  3. On the target system, invoke the dynamic linker with your executable as:

    > sysroot/lib/ld-linux.so.3 \
      --library-path sysroot/lib:sysroot/usr/lib \
      /path/to/your-executable

    where sysroot is the absolute path to the sysroot directory on the target corresponding to your selected multilib.

    Invoking the linker in this manner requires that you provide either an absolute pathname to your executable, or a relative pathname prefixed with ./. Specifying only the name of a file in the current directory does not work.

Using GDB Server for Debugging

The GDB server utility provided with Sourcery G++ Lite can be used to debug a GNU/Linux application. While Sourcery G++ runs on your host system, gdbserver and the target application run on your target system. Even though Sourcery G++ and your application run on different systems, the debugging experience when using gdbserver is very similar to debugging a native application.

Running GDB Server

The GDB server executables are included in the sysroot in ABI-specific subdirectories of sysroot/usr. Use the executable from the sysroot that matches your program. See the section called “Library Configurations” for details.

You must copy the sysroot to your target system as described in the section called “Installing the Sysroot”. You must also copy the executable you want to debug to your target system.

If you have installed the sysroot in the root directory of the filesystem on the target, you can invoke gdbserver as:

> gdbserver :10000 program arg1 arg2 ...

where program is the path to the program you want to debug and arg1 arg2 ... are the arguments you want to pass to it. The :10000 argument indicates that gdbserver should listen for connections from GDB on port 10000. You can use a different port, if you prefer.

If you have installed the sysroot in an alternate directory, invoking gdbserver becomes more complicated. You must build your application using the link-time options to specify the location of the sysroot, as described in the section called “Using Linker Options to Specify the Sysroot Location”. You must also invoke gdbserver itself using the dynamic linker provided in the Sourcery G++ sysroot, as described in the section called “Specifying the Sysroot Location at Runtime”. In other words, the command to invoke gdbserver in this case would be similar to:

> sysroot/lib/ld-linux.so.3 \
  --library-path sysroot/lib:sysroot/usr/lib \
  sysroot/usr/lib/bin/gdbserver :10000 program arg1 arg2 ...

Connecting to GDB Server from the Debugger

You can connect to GDB server by using the following command from within GDB:

(gdb) target remote target:10000

where target is the host name or IP address of your target system.

When your program exits, gdbserver exits too. If you want to debug the program again, you must restart gdbserver on the target. Then, in GDB, reissue the target command shown above.

Setting the Sysroot in the Debugger

If you have installed the sysroot in the root filesystem on the target, as described in the section called “Installing the Sysroot”, you can enable debugging of shared libraries and support for multi-threaded debugging by using the set sysroot GDB command:

(gdb) set sysroot pathname

The pathname is the pathname to a copy of the sysroot on the host, or the unstripped original sysroot files included with your Sourcery G++ Lite distribution if you have installed a stripped copy on the target.

The pathname is used as a prefix for all file names GDB reads from your target. If you installed the sysroot in an alternate location on the target, use set sysroot to point to the root of your target's filesystem. For instance, if the Sourcery G++ libraries are located in /opt/codesourcery on your target and /data/software/opt/codesourcery on your host, use set sysroot /data/software. If the Sourcery G++ libraries are located at the same path on both host and target, you do not need set sysroot.