How can I "register" my library libfoo.so to link it with `-lfoo`?

Question
  1. How can I "register" my library foo.c, compiled to libfoo.so, to link it with -lfoo? Is it by appending its path to LD_LIBRARY_PATH? Is it by running sudo ldconfig?

  2. For curiosity, who do I "register" it with? That is, which application "needs to know" what -lfoo means in order for gcc bar.c -lfoo to work? Is it the bash environment? Is it gcc? Is it the kernel?

  3. Is any of this different for static libraries (eg. libfoo.a)?


Show source
| C   | gcc   | linux   | bash   | dynamic-linking   2017-01-06 21:01 1 Answers

Answers ( 1 )

  1. 2017-01-06 21:01

    If your library is not in a "standard" library directory such as (eg. /usr/local/lib or /usr/lib) then you'll need to tell the compiler it's location -L when you link it -l:

    $ gcc -L/home/username/foo -Wall -o test main.c -lfoo
            |                                        |
            |__ location of libfoo.so or libfoo.a    |__ link libfoo.so or libfoo.a
    

    GCC assumes that all libraries start with ‘lib’ and end with .so or .a (.so is for shared object or shared libraries, and .a is for archive, or statically linked libraries).

    • -L is the location to search for libraries linked to your executable

    • -l links the library to the executable (-lfoo can be translated as "link library libfoo.so")

    When using shared libraries sometimes simply linking them is not enough (eg. if the library is not installed in a standard location such as the example shown above). This is where using LD_LIBRARY_PATH, rpath or ldcondig comes into play. Static library paths won't need to be set like shared libraries since they are compiled with the executable.

    LD_LIBRARY_PATH

    $ export LD_LIBRARY_PATH=/home/username/foo:$LD_LIBRARY_PATH
    

    Exporting this variable informs the run-time linker to look in the specified location for the libfoo.so library that's associated with the executable. LD_LIBRARY_PATH is more or less a temporary, or convenient way of setting a library's location.

    rpath

    $ gcc -L/home/username/foo -Wl,-rpath=/home/username/foo -Wall -o test main.c -lfoo
    

    rpath works similarly to LD_LIBRARY_PATH (as libraries can reside almost anywhere in userland), however, rpath is linked to the executable at compile time, and sets a "fixed" library location.

    ldconfig

    Ultimately what might be the best solution is to use ldconfig, which creates the necessary links and cache to the most recent shared libraries found in the standard library locations and ones you can specify. It does require elevated permissions (eg. sudo) to set paths up this way, and should be used with a certain degree of caution.

    $ sudo cp /home/username/foo/libfoo.so /usr/local/lib
    $ sudo chmod 0755 /usr/local/lib/libfoo.so
    

    This copies the library into /usr/local/lib with permissions set to be readable by everyone.

    $ sudo ldconfig
    $ ldconfig -p | grep foo
    libfoo.so (libc6) => /usr/local/lib/libfoo.so
    

    Then we update the loader cache, and verify the path is set correctly.

    $ gcc -Wall -o test main.c -lfoo
    

    By using ldconfig, the -L option, LD_LIBRARY_PATH or rpath now shouldn't be needed.


    Additional Information

    Shared Libraries With GCC on Linux

◀ Go back