4
votes

Is it possible to pass multiple objects to the linker via an environment variable in GNAT? I have a situation where I have an environment variable (let's call it LINKLIBS) that I have included a space-separated list of extra libraries to be brought into the executable at link-time. In GNU Make, we just define our link line as "$(LD) -o output_file main.o obj1.o obj2.o $(LINKLIBS)", and the linker will bring in everything in LINKLIBS into the object, subject to the usual rules.

LINKLIBS may look like this: "/usr/lib/libsource-highlight.a /usr/lib/x86_64-linux-gnu/libGLU.a /usr/lib/x86_64-linux-gnu/libmenu.a"

When I have a couple of objects explicitly specified in the GPR Linker package as follows, it works fine:

package Linker is
  for Default_Switches ("Ada")
    use (
      "--for-linker=-Map",
      "--for-linker=../myprog.map",
      "--for-linker=--start-group",
      external("LIB_PATH") & "/libabc.a",
      external("LIB_PATH") & "/lib123.a",
      "--for-linker=--end-group");
end Linker;

However, if I include an environment variable that has a space-separated list of archive files, I instead receive an error:

package Linker is
  for Default_Switches ("Ada")
    use (
      "--for-linker=-Map",
      "--for-linker=../myprog.map",
      "--for-linker=--start-group",
      external("LIB_PATH") & "/libabc.a",
      external("LIB_PATH") & "/lib123.a",
      external("LINKLIBS"),
      "--for-linker=--end-group");
end Linker;
gcc: error: /usr/lib/libsource-highlight.a /usr/lib/x86_64-linux-gnu/libGLU.a /usr/lib/x86_64-linux-gnu/libmenu.a: No such file or directory

So, it appears as though it's interpreting the single argument in the Linker package as a single file that includes spaces. I presume the items need to be comma-separated or something, but how can I do this in a way that would use the same variable for my GCC-created programs and my GNAT-created programs?

1

1 Answers

7
votes

You need external_as_list:

...
external_as_list("LINKLIBS", " "),
...

but note that this is a list, so you’ll have to use it as such:

package Linker is
  for Default_Switches ("Ada")
    use (
      "--for-linker=-Map",
      "--for-linker=../myprog.map",
      "--for-linker=--start-group",
      external("LIB_PATH") & "/libabc.a",
      external("LIB_PATH") & "/lib123.a")
      & external_as_list("LINKLIBS", " ")
      & ("--for-linker=--end-group");
end Linker;