9

I try to use the gsl library in one project, but I can't get the example program from the gsl website run properly. The source code and all commands are taken from the website: https://www.gnu.org/software/gsl/manual/html_node/Using-the-library.html#Using-the-library

The program is the following (test.cpp):

#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>

int main (void) {
  double x = 5.0;
  double y = gsl_sf_bessel_J0 (x);
  printf ("J0(%g) = %.18e\n", x, y); 
  return 0;
}

Then I first compile without errors. But the linking fails:

$ g++ -Wall -I/usr/include/ -c test.cpp
$ g++ -L/usr/lib/ -lgsl -lgslcblas -lm test.o
test.o: In function `main':
test.cpp:(.text+0x1c): undefined reference to `gsl_sf_bessel_J0'
collect2: ld returned 1 exit status

But the libraries are available:

$ ll /usr/lib/libgsl*
lrwxrwxrwx 1 root root   16 Mar  2  2012 /usr/lib/libgsl.so.0 -> libgsl.so.0.16.0
lrwxrwxrwx 1 root root   16 Mar  2  2012 /usr/lib/libgsl.so -> libgsl.so.0.16.0
lrwxrwxrwx 1 root root   20 Mar  2  2012 /usr/lib/libgslcblas.so.0 -> libgslcblas.so.0.0.0
lrwxrwxrwx 1 root root   20 Mar  2  2012 /usr/lib/libgslcblas.so -> libgslcblas.so.0.0.0
-rw-r--r-- 1 root root 2.3M Mar  2  2012 /usr/lib/libgsl.so.0.16.0
-rw-r--r-- 1 root root 274K Mar  2  2012 /usr/lib/libgslcblas.so.0.0.0
-rw-r--r-- 1 root root 503K Mar  2  2012 /usr/lib/libgslcblas.a
-rw-r--r-- 1 root root 4.3M Mar  2  2012 /usr/lib/libgsl.a

As well as the header files:

$ whereis gsl
gsl: /usr/include/gsl /usr/share/man/man3/gsl.3.gz

I also tried downloading and installing the lib manually but there is no difference (this one is the Ubuntu package for 12.04 LTS).

/edit2:

Using nm it does not give any further hints:

$ nm /usr/lib/libgsl.a
[...]
bessel_J0.o:
00000000000004c0 T gsl_sf_bessel_J0
0000000000000000 T gsl_sf_bessel_J0_e
                 U gsl_sf_bessel_cos_pi4_e
[...]
Oliver
  • 257
  • 3
  • 9
  • 1
    Have you tracked down which of the files actually provides the symbol `gsl_sf_bessel_J0` ? – PlasmaHH Sep 03 '13 at 09:35
  • I have the source code from the tgz archive and this function is defined in specfunc/bessel_J0.c. How can I find out to which lib* it compiles? /edit: If I apply 'strings' to the lib files the term `gsl_sf_bessel_J0` occurs in `libgsl.a` and `libgsl.so` – Oliver Sep 03 '13 at 10:50
  • use tools like `nm` or `objdump` – PlasmaHH Sep 03 '13 at 11:24
  • Thanks for the hints! I used now nm, but the functions do not refer to anything: `$ nm test.o`: `U gsl_sf_bessel_J0` `0000000000000000 T main` `U printf` – Oliver Sep 03 '13 at 11:40
  • Ok, I tried also `nm /usr/lib/libgsl.a` and there it refers to the file `bessel_J0.o` – Oliver Sep 03 '13 at 13:05
  • When you are linking .a archives, make sure your linker lists them in the correct order. – PlasmaHH Sep 03 '13 at 15:13
  • Ok. I played around a bit with the order, but it didn't change anything. Additionally, the given order is the same as in the tutorial. – Oliver Sep 03 '13 at 15:21
  • I could reproduce the problem. Caused by "inverting" linking flags. First you write the .o file, then the linking flags – Vivian Miranda Sep 03 '13 at 20:59

3 Answers3

11

Easy fix:

You must link as follows

 g++ -L/usr/local/lib/ test.o -lgsl -lgslcblas -lm

You inverted the order while linking (first .o files, then the -l flags)

PS: I could reproduce your problem using your original

 g++ -L/usr/local/lib/ -lgsl -lgslcblas -lm test.o 

and I use gsl all the time without linking problem. I fixed by inverting the order as I said before.

PS2: enter image description hereSee picture

Vivian Miranda
  • 2,276
  • 1
  • 13
  • 26
  • Yes, and that is essentially the same advise as in my earlier answer. – Dirk Eddelbuettel Sep 03 '13 at 21:15
  • @DirkEddelbuettel I am so sorry if you already answer it. But I just read your answer again I still could not see that this is your final advice. It was not my intention to duplicate your answer. – Vivian Miranda Sep 03 '13 at 21:37
  • Just look at my link arguments. – Dirk Eddelbuettel Sep 03 '13 at 21:37
  • They are correct, but it was not clear to me that you showed him that this was the mistake. Sorry. I should have cited something like "look Dirk answer and you will see that he has the correct link order" – Vivian Miranda Sep 03 '13 at 21:38
  • 1
    Don't worry about it -- you high-lighted something correct: Oliver was simply using his tools the wrong way. He has not bothered to upvote or accept anything, so , let's not waste more time here. – Dirk Eddelbuettel Sep 03 '13 at 21:40
  • 1
    I thought by linking flags you mean the order of the -l*. I didn't pay much attention to the position of the *.o. Both solutions work, thanks for the efforts. – Oliver Sep 04 '13 at 06:45
  • Sorry about the confusion. I fixed that sentence to make the meaning more clear. – Vivian Miranda Sep 04 '13 at 07:09
3

This works without a hitch on Ubuntu 13.04:

edd@max:~/src/progs/C$ cat gsl_bessel.c
// cf http://stackoverflow.com/questions/18588607/g-unable-to-link-libgsl

#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>

int main (void) {
    double x = 5.0;
    double y = gsl_sf_bessel_J0 (x);
    printf ("J0(%g) = %.18e\n", x, y); 
    return 0;
}
edd@max:~/src/progs/C$ gcc -Wall -o gsl_bessel gsl_bessel.c -lgsl -lgslcblas -lm
edd@max:~/src/progs/C$ ./gsl_bessel 
J0(5) = -1.775967713143382642e-01
edd@max:~/src/progs/C$ 

Maybe reinstall / check the packages? They have not changed in a long while.

(Disclaimer: I happen to be the Debian maintainer behind these packages.)

Edit: Oh, re-reading your title and tags, your mistake is the use of g++ instead of gcc. This is a C library, and you wrote a C program. It works with C++ but you need extern "C" (which is a different topic).

Edit 2: Never mind. Works fine with g++ as well here as the headers are C++ ready:

edd@max:~/src/progs/C$ rm ./gsl_bessel
edd@max:~/src/progs/C$ g++ -Wall -o gsl_bessel gsl_bessel.c -lgsl -lgslcblas -lm
edd@max:~/src/progs/C$ ./gsl_bessel 
J0(5) = -1.775967713143382642e-01
edd@max:~/src/progs/C$ 
Dirk Eddelbuettel
  • 331,520
  • 51
  • 596
  • 675
  • Thanks, Dirk. It doesn't make any difference whether I use `g++` or `gcc`. I reinstalled the packages now many times but no change at all. – Oliver Sep 03 '13 at 13:37
  • I do not have access to an old 12.04 Ubuntu instance, but I have no reason to believe it was broken there either. Something else is going on which I cannot decipher giving the information you provided. You don't have a second (local) copy of GSL somewhere, do you? – Dirk Eddelbuettel Sep 03 '13 at 13:39
  • Oh, I do, but it I receive the same error message. I downloaded the latest release from their website (version 1.16 from July 2013, [link](ftp://ftp.gnu.org/gnu/gsl/gsl-1.16.tar.gz)) and did a `./configure --prefix= && make && make install`. – Oliver Sep 03 '13 at 13:46
  • Try `ldd gsl_bessel` ie call ldd on the executable you built, check the libraries it linked against. – Dirk Eddelbuettel Sep 03 '13 at 13:47
  • Actually there are only `libgsl.*` and `libgslcblas.*` in the lib folder. Which one do you refer to exactly? `ldd libgsl.so` gives me `linux-vdso.so.1 => (0x00007fff0c13c000)`, `libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4a3ac5b000)`, `libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4a3a89c000)`, `/lib64/ld-linux-x86-64.so.2 (0x00007f4a3b39d000)` – Oliver Sep 03 '13 at 14:00
  • Thanks for all the help. I tested it on another system (Debian) and it works well. So I don't know why my system is broken. Anyone has the same experience with Ubuntu 12.04? – Oliver Sep 03 '13 at 14:33
  • I think the problem is much simpler to solver. I could reproduce his problem and I fixed by inverting the order of linking arguments. – Vivian Miranda Sep 03 '13 at 21:03
1

GSL linking on Windows:

gcc -c test.c -Wall -I"C:\Program Files\GnuWin32\include"  -o test.o -L"C:\Program Files\GnuWin32\lib" -lgslcblas -lgsl -lm

gcc -o test.exe test.o -L"C:\Program Files\GnuWin32\lib" -lgslcblas -lgsl -lm

where C:\Program Files\GnuWin32\include" is location of include directory in GSL and "C:\Program Files\GnuWin32\lib" is location of lib directory.