2
votes

I'm building a simple program for ARM. GPRbuild outputs the following:

gprbuild -p -P avocado_test.gpr (in directory: /home/rodeo/Projects/AvocadoTest)
Bind
   [gprbind]      run_avocado_test.bexch
   [Ada]          run_avocado_test.ali
Link
   [link]         run_avocado_test.adb
/opt/GNAT/arm-elf/bin/arm-eabi-ld: unrecognised emulation mode: cpu=cortex-m3
Supported emulations: armelf
gprbuild: link of run_avocado_test.adb failed
Compilation failed.

From what I could find online, ld has a switch -m which specifies an emulation mode. However, I am not using this switch in the linker of my project. I am using the -mcpu=cortex-m3 switch in the compiler, though, and it looks like somehow GPRbuild is passing this switch to the linker as well. Here is my .gpr file:

project Avocado_Test is

   for Source_Dirs use ("source");
   for Object_Dir  use "build";
   for Main use ("source/run_avocado_test.adb");

   for Target use "arm-eabi";
   for Runtime ("Ada") use "ravenscar-sfp-sam3x8e";

   package Builder is
      for Executable_Suffix use ".elf";
      for Switches ("Ada") use ("-j0");
   end Builder;

   package Compiler is
      for Driver ("Ada") use "arm-eabi-gcc";
      for Switches ("Ada") use (
        "-mthumb",
        "-mcpu=cortex-m3",
        "-O2");
   end Compiler;

   package Binder is
      for Driver ("Ada") use "arm-eabi-gnatbind";
   end Binder;

   package Linker is
      for Driver use "arm-eabi-ld";
   end Linker;

end Avocado_Test;

Why is the linker taking a switch from the compiler? How do I prevent this?

1
You don't show your whole GPR so it is hard to tell. I took a look at my bare metal projects. I never specify those parameters in the project GPR because the runtime.xml file for my runtime inserts them in the correct place. Have you tried not specifying them and seeing if the runtime adds them appropriately when you build?Jere
I've edited to include the full .gpr file. Commenting out the Linker'Driver attribute results in some different errors which are from a library I've built. Looks like I need to look at my runtime.xml file and perhaps rebuild the library as well, since the compiler and linker packages look similar in that project. Thanks for the idea.Rodeo
So, it turns out that in the runtime.xml file was appending compiler switches to the Linker'Required_Switches attribute. This file and runtime are generated from Adacore's bb-runtimes. It doesn't make any sense, why on earth would compiler switches be appended to the linker switches?Rodeo
I have no idea what GPRBuild is, but in general it is wrong to link any user-level program directly with ld -- one should always use the compiler driver (arm-eabi-gcc here) instead.Employed Russian
Oh, I wasn't aware that the compiler was able to select the correct linker like that.Rodeo

1 Answers

3
votes

I wouldn’t use Driver at all, in any of your GPR packages. Once gprbuild sees for Target use "arm-eabi"; it knows to prepend arm-eabi- to each tool.

There’s no reason to avoid passing compiler switches to the default linker driver, which is gcc (in this case arm-eabi-gcc), because it knows which of them to pass to the linker.

You might find these interesting from my cortex-gnat-rts project: runtime.xml (but note, details may differ from AdaCore’s runtimes), testbed.gpr.