Cross Linux Topics

This appendix describes topics that are specific to the GNAT for Cross Linux.

Building a Cross Linux Application

This section is the starting point for building an Ada application targeting a Cross Linux system.

To be able to build a program for Cross Linux, the build toolchain will need to know where to find includes and libraries for this target. GCC provides the option --sysroot for that purpose. This option takes as a parameter the logical root directory for headers and libraries.

For example, if the compiler normally searches for headers in /usr/include and libraries in /lib and /usr/lib, --sysroot=dir instead searches dir/usr/include and dir/usr/lib. On 64-bit targets, this would also include dir/usr/lib64 and dir/lib64.

GNAT also provides an alternative way to set the path to sysroot which allows you to use the compiler without having to pass --sysroot each and every time. This is done by setting the ENV_PREFIX environment variable. Having ENV_PREFIX in the environment is equivalent to passing --sysroot=$ENV_PREFIX to the compiler.

These libraries in your sysroot should match exactly the ones that the target provides; this is why they cannot be provided in the GNAT package.

On Linux host only, depending on your host distribution, you may have a package for cross development that matches your target setup. An example of such a case is Ubuntu 16.10 providing a package for cross development on ppc64-linux, named lib32gcc-6-dev-ppc64-cross.

Such a package would provide the target libc. But not all distribution would have such packages, and certainly not for all target architectures, distributions, versions; in particular if the target does not run the same distribution as the host, you most certainly won’t have a package for it.

In such a case, a more general way to build a sysroot is to copy the target libraries on host. For instance, on an x86_64-linux host, if you are developing with a ppc64-linux target, you could do the following to build a sysroot directory:

$ mkdir ./sysroot
$ mkdir ./sysroot/usr
$ scp -rp my-ppc64-linux-target:/usr/include ./sysroot/usr/
$ scp -rp my-ppc64-linux-target:/usr/lib ./sysroot/usr/
$ scp -rp my-ppc64-linux-target:/usr/lib64 ./sysroot/usr/
$ scp -rp my-ppc64-linux-target:/lib ./sysroot/
$ scp -rp my-ppc64-linux-target:/lib64 ./sysroot/

To use that sysroot, you can then export ENV_PREFIX as follow.

$ export ENV_PREFIX=`pwd`/sysroot

As indicated earlier, this allows you to use GNAT without having to pass the sysroot on each command.

To build the basic Hello world example on ppc64-linux, you can then invoke gnatmake with the default options:

$ powerpc64-generic-linux-gnu-gnatmake hello
powerpc64-generic-linux-gnu-gcc -c hello.adb
powerpc64-generic-linux-gnu-gnatbind -x hello.ali
powerpc64-generic-linux-gnu-gnatlink hello.ali

WARNING: Some Linux systems provide linker scripts, e.g., that may point to other shared libraries using a full path that starts with a double-slash ‘//’. While this does not cause any problem on GNU/Linux hosts, on Windows hosts, such paths are interpreted as UNC path. This should not prevent sysroot to be expanded, however Windows users creating sysroots from a live target system may want to fix them to avoid the latency of a network search.

Debugging an Application on Cross Linux

This section describes the steps needed to run the Cross Linux debugger.

The debugging solution that GNAT provides on this target consists of three tools:

  • gdbserver: A debugging server on target, which provides a low-level interface to control the debugged program.
  • gdb: The debugger itself, run on the host, it connects to the gdbserver and allows the user to control the debugged program through a command-line interface.
  • gps: The GNAT Programming Studio, which provides a graphical front-end on the top of gdb.

To start a debugging session, you first need to run the program under control of the GDB server. For example, if the board has an internet connection to the development host, and the Internet hostname of the board is myboard, that your application is named myapp, and that the port on which the gdbserver will wait for requests is 2345, the command would be:

myboard> gdbserver myboard:2345 myapp

To be able to properly debug the program running on target, the debugger will need to know where to find a copy of the shared libraries that this program is executing. For that, the environment variable ENV_PREFIX should be set. See section Building a Cross Linux Application for more information about these environment variables.

You can now start the debugger. In GPS, on the Languages tab of the project properties page, you would specify the name of the debugger (e.g. powerpc64-generic-linux-gnu-gdb). You would then be able to start this debugger with the command: Debug => Initialize => <No Main Program>. Alternatively, you can run the debugger gdb from the command line.

You are now ready to connect the debugger to the GDB server:

(gdb) target remote myboard:2345

After the server has been started and attached from the host, the program is running on the target but has halted execution at the very beginning. You can then set breakpoints, resume the execution and use the usual debugger commands:

(gdb) break some_function
(gdb) continue
(gdb) next

For further information about the debugger or the GDB server, please refer to the GDB User’s Manual.