7

I've been having a harrowing time lately just trying to get several C programs compiled because I can't find where the libraries are located and pkg-config seems to be out of order.

I installed GNU GSL like this:

wget ftp://ftp.gnu.org/gnu/gsl/gsl-1.15.tar.gz
tar xvzf gsl-*gz
cd gsl-1.15
./configure
make
sudo make install

Apparently it installed in /usr/local/lib which is a non-standard place? (1) What is a standard place? (2) How would I get it to install there?

And I can't manage to compile a simple program that uses this library:

$ gcc gsl_erf.c -o gsl -I/usr/local/lib -L/usr/local/lib
/tmp/cc3WD9Zq.o: In function `main':
gsl_erf.c:(.text+0x24): undefined reference to `gsl_cdf_gaussian_P'
collect2: error: ld returned 1 exit status

Now, with pkg-config :

pkg-config --libs --cflags gslPackage gsl was not found in the pkg-config search path.
Perhaps you should add the directory containing `gsl.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gsl' found

So I did add the directory:

PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

But no luck yet! :( pkg-config still gives me the same message as above. (Perhaps you sh ...)

This is a more general problem I face regularly when I have to compile some C program. I would love a general solution for:

  1. Where and how do I install my C libs? (Perhaps the same place yum installs them?)
  2. How do I correct/configure and use pkg-config

Update : I tried one of the answer's suggestions below and running the compiled program gives me this : ./gsl_app: error while loading shared libraries: libgsl.so.0: cannot open shared object

gideon
  • 353
  • 3
  • 6
  • 17
  • Just curious ... Why isn't 'yum install gsl' sufficient? – rickhg12hs Jan 26 '14 at 17:34
  • 2
    @rickhg12hs I was reading `21st Century C` and this was one of the exercises. But I want to get this to work this way because I've run into this problem a few times now when trying to get some c library from github that's not in the yum repository. – gideon Jan 26 '14 at 18:00
  • Makes sense. There is a learning curve. Good luck! – rickhg12hs Jan 26 '14 at 21:23

2 Answers2

10

Apparently it installed in /usr/local/lib which is a non-standard place?

It's a standard place, but sometimes systems are configured presuming that you are not going to build-install anything, and so it is left out of the linker cache path.

Where and how do I install my C libs? (Perhaps the same place yum installs them?)

That is generally a bad idea, esp. if there are potentially distro packages -- now, or down the line -- that conflict. Stick with /usr/local.

Check to see if /usr/local/lib is in ld.so.cache by running ldconfig -v 2>&1 | grep /usr/local. If you don't get any output, create a file /etc/ld.so.conf.d/local.conf with one line:

/usr/local/lib

Run that ldconfig line again and this time you should see it. You need to run ldconfig every time you build and install a library from source.

I can't manage to compile a simple program that uses this library

Because you have to pass the pkg-config parameters to the compiler. First, you need to find the actual gsl.pc.

find /usr/local -name gsl.pc

I think it is more likely in /usr/local/lib/pkgconfig, and not /usr/local/pkgconfig as you say. Try pkg-config --list-all | grep gsl and see if it's found. If not export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH (or whatever the directory with gsl.pc is) and try again. When you get that right, you may want to add it somewhere in, e.g., /etc/profile.d.

Now, to actually compile:

gcc gsl_erf.c -o gsl `pkg-config --libs --cflags gsl`

You don't need to include -I and -L yourself; that's what pkg-config is for, although all you were likely missing before was -lgsl.

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
goldilocks
  • 86,451
  • 30
  • 200
  • 258
  • Thanks very much goldilocks! Your assumptions were correct. **however** while pkg-config spits the correct output I get this: `$ gcc gsl_erf.c -o gsl_app \`pkg-config --libs --cflags gsl\` $./gsl_app ./gsl_app: error while loading shared libraries: libgsl.so.0: cannot open shared object file: No such file or directory` – gideon Jan 26 '14 at 05:51
  • Any clues or ideas? – gideon Jan 26 '14 at 05:53
  • I notice you do need to use `export PKG_CONFIG_PATH=usr/local/lib/pkgconfig`; `pkg-config` must fork because without the **`export`** it won't find anything in the alternate path. You need to do that in the same shell you are compiling from, unless you put it in a `.profile` *and log out and in again completely*. – goldilocks Jan 27 '14 at 15:01
  • @gideon what's the output of `pkg-config --libs --cflags gsl`? do you have a `libgsl.so.0`? – umläute Jan 27 '14 at 16:42
  • @umläute ok, so only if I do the `export` line then it works. This is my output : `$ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH $ pkg-config --libs --cflags gsl OUTPUT: -I/usr/local/include -L/usr/local/lib -lgsl -lgslcblas -lm` – gideon Jan 27 '14 at 17:14
  • @umläute I do have a `libgsl.so.0` under `/usr/local/lib`. OK! I just tried compiling my program again and it worked. So yes I need to be in the same shell. However, I need to understand what is going on here? What is `ldconfig` and why can't pkg-config know where my gsl lib is? – gideon Jan 27 '14 at 17:17
  • 1
    See `man ldconfig`; ld.so is the linux [dynamic linker](http://en.wikipedia.org/wiki/Dynamic_linker). `pkg-config` is a little obtuse and AFAIK *the only* way to configure its search path is via `$PKG_CONFIG_PATH` (or during the building of pkg-config itself, I guess). Which is not so confusing since the shell is the same WRT `$PATH`. The reason `export` is required is that environment variables won't be *inherited* by subshells otherwise.... – goldilocks Jan 27 '14 at 18:56
  • ...And there is NO means of making a change to an env variable instantaneously system wide; currently running shells are not affected if you change a shell config file, and only the *future* children subshells of a running shell are affected by `export`. **This is on purpose** (which is probably why pkg-config uses such a system -- maybe not so obtuse!) and *environment* and environment variables are an important thing to understand, but that's a separate set of questions ;] – goldilocks Jan 27 '14 at 19:00
  • @goldilocks Unfortunately this sort of issue has been haunting me ever so often, here it is again : could you take a look at it pretty please! http://chat.stackexchange.com/transcript/message/13440911#13440911 – gideon Jan 28 '14 at 15:28
1

I'm working thru the same book, 21st Century C, and have the same problem. I found the solution that would let me compile this program in the GNU Docs at http://www.gnu.org/software/gsl/manual/gsl-ref.html.

2.3 Shared Libraries

To run a program linked with the shared version of the library the operating system must be able to locate the corresponding .so file at runtime. If the library cannot be found, the following error will occur:

$ ./a.out  ./a.out: error while loading shared libraries: 
libgsl.so.0: cannot open shared object file: No such  file or
directory 

To avoid this error, either modify the system dynamic linker configuration or define the shell variable LD_LIBRARY_PATH to include the directory where the library is installed.

For example, in the Bourne shell (/bin/sh or /bin/bash), the library search path can be set with the following commands:

$ LD_LIBRARY_PATH=/usr/local/lib $ export LD_LIBRARY_PATH $ ./example
Minix
  • 5,735
  • 8
  • 28
  • 45
  • The problem is usually face is `where is the sodded library installed!` Maybe I can search, sure, but usually where does it get installed? – gideon Jun 28 '15 at 14:07