Search code examples
cross-compilingadagnat

GNAT GPL Ada fails will linkage error when cross-compiling for the Raspberry pi


I am trying to build a simple "hello_there" Ada app to run on a Raspberry Pi 2/Raspbian machine but have come across a linkage issue.

So far, I've done the following and had the following issues:

  1. Downloaded the "Raspberry Pi 2 Linux" GNAT GPL Ada toolchain for cross compiling (linux-on-linux) on the host machine (Ubuntu 16.04)

  2. Ran "doinstall" on the host machine successfully.

  3. Created a simple "hello_there.adb" file which just prints a message to the console.

  4. Ran {INSTALL_ROOT}/gnat-gpl-2016-raspberrypi-linux-linux-bin/bin/arm-linux-gnueabihf-gnatmake -v hello_there.adb to build this small app.

  5. That complained that the crt1.o | crti.o | crtn.o files cannot be found and since I couldn't use the ones under /usr/lib/x86_64-linux-gnu/ on the host machine (as I assume, these can only be used for a x86 target) the only solution I could find was to copy these files from the target machine which are located under /usr/lib/arm-linux-gnueabihf to the gnatmake command dir. That stopped the linker complaining about these.

  6. Ran again {INSTALL_ROOT}/gnat-gpl-2016-raspberrypi-linux-linux-bin/bin/arm-linux-gnueabihf-gnatmake -v hello_there.adb but now the linker is complaining with the following error:

    {INSTALL_ROOT}/gnat-gpl-2016-raspberrypi-linux-linux-bin/bin/../libexec/gcc/arm-linux-gnueabihf/4.9.4/ld: cannot find -lc

    It looks like compilation and binding complete fine but but linking fails. The full output is the following:

    GNATMAKE GPL 2016 (20160515-49)
    Copyright (C) 1992-2016, Free Software Foundation, Inc.
      "hello_there.ali" being checked ...
      -> "hello_there.ali" missing.
    arm-linux-gnueabihf-gcc -c hello_there.adb
    End of compilation
    arm-linux-gnueabihf-gnatbind -x hello_there.ali
    arm-linux-gnueabihf-gnatlink hello_there.ali
    /home/savvas/opt/GNAT/gnat-gpl-2016-raspberrypi-linux-linux-bin/bin/../libexec/gcc/arm-linux-gnueabihf/4.9.4/ld: cannot find -lc
    collect2: error: ld returned 1 exit status
    arm-linux-gnueabihf-gnatlink: error when calling /home/savvas/opt/GNAT/gnat-gpl-2016-raspberrypi-linux-linux-bin/bin/arm-linux-gnueabihf-gcc
    arm-linux-gnueabihf-gnatmake: *** link failed.
    

Is the linker looking for a clib (or some other filename?) file somewhere in the library path or is there something else going on? I'm new to gcc compilation/linking and am trying to make sense of this.

Any pointers, much appreciated.

Thanks


Solution

  • Before using this particular version of the GNAT (cross-)compiler, you need to copy some additional files from your RPi 2 to the host first. The exact steps are explained in the README file that accompanies the particular GNAT release. I copied the relevant section to the end of this answer for convenience.

    That said, also consider developing your program on Ubuntu first using a more recent version of GNAT (Community Edition or an FSF version), then copy the source code the Raspberry Pi, and recompile it on the Pi itself. The GNAT FSF compiler (and related tools) that is available from the Debian repositories is also available on Raspberry Pi OS:

    $ sudo apt install gnat gprbuild
    

    Finally, you could also consider to use Alire (at least on the host). Alire has no official support for Raspberry Pi yet, but an experimental release is already available here.


    Excerpt from the README file:

    Raspberrypi 2 (hosted on Linux)

    • The GNAT GPL compiler for raspberrypi is a cross compiler, hosted on linux-x86 (or linux-x86_64). You need to copy from the boards some library files. The following script achieves that. It should be executed from <GNAT GPL>/arm-linux-gnueabihf (the RPI variable is login@target):

      #!/bin/sh
      
      RPI=pi@myboard
      
      mkdir sysroot sysroot/lib sysroot/lib/arm-linux-gnueabihf
      cd sysroot/lib
      rsync -a $RPI:/lib/arm-linux-gnueabihf/{ld-*,lib?.*,lib?-*,libpthread*,librt*} arm-linux-gnueabihf
      ln -s arm-linux-gnueabihf/lib?.* .
      cd ../..
      mkdir sysroot/usr sysroot/usr/lib sysroot/usr/lib/arm-linux-gnueabihf
      cd sysroot/usr/lib/arm-linux-gnueabihf
      rsync -a $RPI:/usr/lib/arm-linux-gnueabihf {crt*,libc.*,libc_no*,libpthread*} .
      ln -s ../../../lib/arm-linux-gnueabihf/libm.so.* libm.so
      ln -s ../../../lib/arm-linux-gnueabihf/librt.so.* librt.so
      cd ..
      ln -s arm-linux-gnueabihf/* .
      

      Before running a GNAT GPL tool, set ENV_PREFIX variable like this:

      export ENV_PREFIX=<GNAT GPL>/arm-linux-gnueabihf/sysroot