Search code examples
gccg++ld

Meaning of `-l` (lowercase "L") flags in gcc/g++


What is the meaning of -l (lowercase "L") flags passed to gcc/g++? And where can I find documentation or tutorials on it?


I've tried searching man gcc and man ld for -l, but that has thousands of matches.

Example of a -l flag:

in this:

gcc -Wall -Wextra -Werror -O3 -std=c17 hello_world_extra_basic.c -o bin/a -lm && bin/a

-lm says to include the math library (static .a or dynamic .so?--I don't know) so you can use functions like sin() from math.h.

See:

  1. https://en.cppreference.com/w/c/numeric/math
  2. https://stackoverflow.com/a/12165016/4561887

But I need more detail than that:

  1. What does calling -lgtest or -lm really do? I can clearly manually pass the -I include directories, and .a static prebuilt files myself, for instance, like this from my answer here:

    # to manually build "googletest/googletest/samples/sample1_unittest.cc"
    time ( \
        time g++ -Wall -Wextra -Werror -O3 -std=c++17 -pthread \
        -I"googletest/googletest/include" -I"googletest/googlemock/include" \
        googletest/googletest/samples/sample1_unittest.cc \
        googletest/googletest/samples/sample1.cc \
        bin/libgtest.a bin/libgtest_main.a \
        -o bin/a \
        && time bin/a \
    )
    

    What does -lgtest do instead, and what has to be in-place for this to work?

  2. Why -l? Is that part of what must be present in the name? Does "l" mean something like 'l'inker? Do these flags go to the compiler or the linker?

  3. Why -lpthread vs -pthread? I've seen both before and don't understand the difference.

  4. Are -l includes linking to static .a libraries, or to runtime .so libraries? Where do these libraries exist in your filesystem?

  5. How does this relate to the output of sudo ldconfig -v which I see here?

  6. Can you add your own -l flags? How?

Update: searching ld --help shows this, so l must stand for 'l'ibrary, but is that static or dynamic?:

-l LIBNAME, --library LIBNAME  
                            Search for library LIBNAME

Solution

  • I got it figured out well enough to feel comfortable posting an answer. I figured out almost all of the following through extensive trial and error as I wrote my answer here.

    For full details, see the "Going further" section at the end of my answer here: How to set up googleTest as a shared library on Linux: "Going further: general information about libraries; debugging; gcc/g++ compiler flags; etc."

    Here are some of the salient points:

    1. As I figured out in the bottom of my question, -l presumably means 'l'ibrary. These flags apparently get passed straight through gcc/g++ to the ld linker. See ld --help. The flag -lmylibraryname tells the linker to look for a file named libmylibraryname.a (if a static .a archive library), or a similar name prefixed with lib if a dynamic .so shared object libary. If such a library is found, generally in /usr/lib (usually for system libraries), or /usr/local/lib (usually for user-installed libraries), then the linking is successful.

    2. Header files are also automatically searched for in /usr/include and /usr/local/include.

    3. Based on the naming above, -lm means there must be a file named libm.a, for instance, probably in /usr/lib somewhere. Sure enough, find /usr/lib -path "*libm.*" finds the following:

      $ find /usr/lib -path "*libm.*"
      /usr/lib/x86_64-linux-gnu/libm.so
      /usr/lib/x86_64-linux-gnu/libm.a
      /usr/lib/x86_64-linux-gnu/libm.so.6
      /usr/lib/i386-linux-gnu/libm.so.6
      
    4. -lgtest works because a file named libgtest.a (following that same naming convention described above) exists at /usr/local/lib/libgtest.a, now that I've followed my own instructions at the link above.

    5. Regarding -lpthread vs -pthread, here are my own notes from my answer above:

      1. A google search for g++ "-lpthread" vs "-pthread" reveals this answer: Difference between -pthread and -lpthread while compiling, which says that the difference between -lpthread and -pthread is historical, so on today's gcc/g++ and clang compilers, you should always just use -pthread to bring in POSIX threads.

        The -lpthread library is now an empty binary apparently and doesn't do anything except satisfy ancient requirements where that library must still be included in some places. But, -pthread handles that all for you, so just use -pthread alone and be done!

    6. Are -l includes linking to static .a libraries, or to runtime .so libraries? Where do these libraries exist in your filesystem?

      Answer: either.

      They are usually found in /usr/lib (system-installed libraries) or /usr/local/lib (user-installed libraries), and their file names must begin with lib.

    7. sudo ldconfig -v shows dynamic libraries only, which are loaded and available for run-time linking now (I think).

    8. Can you add your own -l flags? How?

      Yes! First, build .c/.cpp files into .o files using gcc or g++, then use ar to convert the output .o files into archive .a static library files. Then, copy your .a files into /usr/local/lib via sudo cp -i -t=/usr/local/lib lib/libgtest.a lib/libgtest_main.a lib/libgmock.a lib/libgmock_main.a, or similar. For full details on building the .o and .a files manually, see my answer here: How do I build and use googletest (gtest) and googlemock (gmock) with gcc/g++ or clang?.

    I think that covers it.