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:
But I need more detail than that:
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?
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?
Why -lpthread
vs -pthread
? I've seen both before and don't understand the difference.
Are -l
includes linking to static .a
libraries, or to runtime .so
libraries? Where do these libraries exist in your filesystem?
How does this relate to the output of sudo ldconfig -v
which I see here?
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
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:
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.
Header files are also automatically searched for in /usr/include
and /usr/local/include
.
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
-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.
Regarding -lpthread
vs -pthread
, here are my own notes from my answer above:
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!
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
.
sudo ldconfig -v
shows dynamic libraries only, which are loaded and available for run-time linking now (I think).
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.