I want to statically link a library say libcurl. As both static and shared libraries are in same folder, I am using -Wl,-Bstatic to let the linker know to use static library.
g++ -o prog prog.o -Wl,-Bstatic -lcurl.
But above command is giving error:
/usr/bin/ld: cannot find -lgcc_s
If I exclude -Wl,-Bstatic, it works fine, but It will use shared library which I dont want.
What is going wrong?
When you use the g++
front-end to perform your linkage, like:
g++ -o prog prog.o -Wl,-Bstatic -lcurl
g++
invokes the linker passing it your linkage options and also silently
adding to the linker commandline a large number of boiler-plate options that
are invariant for C++ linkage.
For example, your C++ program very probably will need to link the standard C++ library,
libstdc++
, but your g++
command doesn't mention it. It certainly also needs the standard C library,
but it isn't mentioned either. g++
automatically adds linkage options to link these and
other libraries.
You can see all the boilerplate that g++
adds to your linkage by running it in
verbose mode. You will see the like of:
$ g++ -v -o prog prog.o -Wl,-Bstatic -lcurl
...
...
COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so \
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper \
-plugin-opt=-fresolution=/tmp/cckwrJp6.res -plugin-opt=-pass-through=-lgcc_s \
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc \
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc \
--sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu \
--as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro \
-o prog /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o \
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o \
/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o \
-L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu \
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu \
-L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib \
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. prog.o \
-Bstatic -lcurl -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc \
/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o \
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
/usr/bin/x86_64-linux-gnu-ld: cannot find -lgcc_s
/usr/bin/x86_64-linux-gnu-ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
Note in particular your -Bstatic
option and the following linkage options:
-Bstatic -lcurl -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc \
/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o \
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
which include your -lcurl
and also the default system libraries:
-lcurl -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
Then see the documentation of the -Bstatic
linker option:
-Bstatic
...
Do not link against shared libraries. This is only meaningful on platforms for which shared libraries are supported. The different variants of this option are for compatibility with various systems. You may use this option multiple times on the command line: it affects library searching for -l options which follow it. This option also implies --unresolved-symbols=report-all. This option can be used with -shared. Doing so means that a shared library is being created but that all of the library’s external references must be resolved by pulling in entries from static libraries.
[my emphasis]
So, your -Bstatic
option directs the linker to link static versions of:
-lcurl -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
It finds the static libcurl.a
that you have installed. It fails to find a
static library for -lgcc_s
because there isn't any libgcc_s.a
installed on
your system. You just have dynamic versions of this and other basic system libraries,
which is pretty normal.
If you want the linker to link static libraries only for the -l
options that you
specify, then you must turn on -Bstatic
before your -l
options and turn it off
after them, -Bdynamic
, even if this makes -Bdynamic
the last thing on your commandline.
Because g++
(or any other GCC front-end, gcc
, gfortran
...) is going to add -l
options to your commandline behind the scenes. Link like:
g++ -o prog prog.o -Wl,-Bstatic -lcurl -Wl,-Bdynamic
to fix this particular linkage error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With