2

What I did so far on my Linux Mint system:

  1. Write a thin binding to the GSL library
  2. Write a thick binding based on the thin binding
  3. Write a test program for 1.
  4. Write a test program for 2.

When I create static libraries, everything works fine. When creating dynamic libraries however, compiling 4. with

gprbuild -P test_odeiv2_dyn

gets me undefined references:

Compile
   [Ada]          test_odeiv2.adb
   [Ada]          odeiv2_aux.adb
   [Ada]          integration.adb
   [Ada]          odeiv2.adb
Build Libraries
   [gprlib]       gsl.lexch
   [link library] libgsl.so
Bind
   [gprbind]      test_odeiv2.bexch
   [Ada]          test_odeiv2.ali
Link
   [link]         test_odeiv2.adb
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_driver_apply'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_rk4imp'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_msbdf'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_bsimp'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_rkf45'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_rk1imp'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_rk4'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_driver_free'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_strerror'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_rkck'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_msadams'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_driver_alloc_y_new'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_rk2imp'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_integration_qng'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_rk8pd'
/usr/bin/ld: /home/frank/Lib/Ada/Num/GSL/lib//libgsl.so: undefined reference to `gsl_odeiv2_step_rk2'
collect2: error: ld returned 1 exit status
gprbuild: link of test_odeiv2.adb failed
gprbuild: failed command was: /usr/bin/gnatgcc test_odeiv2.o b__test_odeiv2.o -L/home/frank/Lib/Ada/Num/GSL/lib/ -lgsl -L/home/frank/Lib/Ada/Num/GSL/Thin/lib/ -lgsl_thin_dyn -L/usr/lib/x86_64-linux-gnu -lgsl -lgslcblas -L/usr/lib/x86_64-linux-gnu -lgsl -lgslcblas -L/home/frank/Lib/Ada/Num/Tests/Test_GSL/obj_dyn/ -L/home/frank/Lib/Ada/Num/Tests/Test_GSL/obj_dyn/ -L/home/frank/Lib/Ada/Num/GSL/lib/ -L/home/frank/Lib/Ada/Num/GSL/Thin/lib/ -L/usr/lib/gcc/x86_64-linux-gnu/9/adalib/ -shared-libgcc -lgnarl-9 -lgnat-9 -lrt -lpthread -lrt -ldl -Wl,-rpath-link,/usr/lib/gcc/x86_64-linux-gnu/9//adalib -Wl,-z,origin,-rpath,$ORIGIN/../..//GSL/lib:$ORIGIN/../..//GSL/Thin/lib:/usr/lib/x86_64-linux-gnu:$ORIGIN//obj_dyn:/usr/lib/gcc/x86_64-linux-gnu/9/adalib:/usr/lib64:/usr/lib -o /home/frank/Lib/Ada/Num/Tests/Test_GSL//test_odeiv2_dyn

What am I missing?

My project files are:

1.

library project GSL_Thin_Dyn is

   version:= "1";

   for Source_Dirs use ("src", "src/matrix");
   for Library_Dir use "lib";
   for Object_Dir use "obj_rel";
   for Library_Name use "gsl_thin_dyn";
   for Library_Kind use "relocatable";
   for Library_Version use "libgsl_thin.so." & version;
   for Externally_Built use "false";

   package Linker is
      for Linker_Options use ("-L/usr/lib/x86_64-linux-gnu", "-lgsl", "-lgslcblas");
   end Linker;

end GSL_Thin_Dyn;
with "Thin/gsl_thin_dyn";

library project GSL_dyn is

   version:= "1";
   
   for Source_Dirs use (".");
   for Object_Dir use "obj_dyn";
   for Library_Dir use "lib";
   for Library_Name use "gsl";
   for Library_Kind use "relocatable";
   for Library_Version use "libgsl.so." & version;
   for Externally_Built use "false";

   package Linker is
      for Linker_Options use ("-L/usr/lib/x86_64-linux-gnu", "-lgsl", "-lgslcblas");
   end Linker;

end GSL_dyn;
with "../../../Gen/gen_shared";
with "../../GSL/Thin/gsl_thin_dyn";

project Test_Odeiv2_Thin_Dyn is

   for Source_Dirs use (".");
   case gen_shared.mode is
      when "debug"  => for Object_Dir use "obj_dyn";
      when "release"    => for Object_Dir use "obj_dyn/release";
      when others   => null;
   end case;
   for Exec_Dir use ".";
   for Main use ("test_odeiv2_thin.adb");

   package Builder is
      for Executable ("test_odeiv2_thin.adb") use "test_odeiv2_thin_dyn";
   end Builder;

end Test_Odeiv2_Thin_Dyn;
with "../../../Gen/gen_shared";
with "../../GSL/gsl_dyn";
        
project Test_Odeiv2_Dyn is
        
   for Source_Dirs use (".");
   case gen_shared.mode is
      when "debug"  => for Object_dir use "obj_dyn";
      when "release"    => for Object_Dir use "obj_dyn/release";
   end case;
   for Exec_Dir use ".";
   for Main use ("test_odeiv2.adb");
        
   package Linker is
      for Linker_Options use ("-L/usr/lib/x86_64-linux-gnu", "-lgsl", "-lgslcblas");
   end Linker;
    
   package Builder is
     for Executable ("test_odeiv2.adb") use "test_odeiv2_dyn";
   end Builder;
        
end Test_Odeiv2_Dyn;
hreba
  • 107
  • 1
  • 8
  • 1
    Not entirely sure whether that's the problem, but you shouldn't name your thick wrapper `gsl` when the library you're wrapping is named `gsl`. Also the `Linker_Options` propagate, don't repeat them in every library that indirectly depends on them. – flyx Jan 18 '22 at 16:54
  • Repetition of Linker_Options was just an act of desesperation. I changed the library name to gsl_ada, and this is not only cleaner, besites that IT WORKS! Thanks a lot! – hreba Jan 19 '22 at 11:01
  • If you repeat your comment as answer, I could mark the question as resolved (according to my understanding of the procedures here). If I'd do that, I would win your laurels. – hreba Jan 19 '22 at 11:08
  • Are you going to publish this thick binding to GSL? There's always useful to have these bindings available. – Gneuromante Jan 20 '22 at 23:11
  • Actually, I'm working on a physics simulation framework, which will serve as a test for my GSL binding (ODEIV2 - Orinary Differential Equation Integration). At the end (in 2 months maybe), I might publish both results. I've never done any publishing before. What would you recommend? SourceForge? – hreba Jan 21 '22 at 08:39
  • @hreba Ideally you'd publish your library to [Alire](https://alire.ada.dev). Where you host your code is up to you, nowadays most people seem to use GitHub or GitLab as these make it easier for other devs to contribute than SourceForge does. – flyx Feb 01 '22 at 13:07

1 Answers1

4

You named your thick wrapper library gsl. The library you're wrapping is also named gsl. Internally, this will cause the linker to get -lgsl two times, and both will be resolved to your thick wrapper. This is why it's missing the symbols from the original library.

Change the Library_Name of your thick wrapper to resolve this.

flyx
  • 35,506
  • 7
  • 89
  • 126