当您使用g++ 前端执行链接时,例如:
g++ -o prog prog.o -Wl,-Bstatic -lcurl
g++ 调用链接器,将您的链接选项传递给它,并且还默默地
向链接器命令行添加大量样板选项
对于 C++ 链接是不变的。
例如,您的 C++ 程序很可能需要链接标准 C++ 库,
libstdc++,但你的 g++ 命令没有提到它。它当然还需要标准 C 库,
但也没有提到。 g++ 自动添加链接选项来链接这些和
其他库。
您可以通过在其中运行 g++ 添加到您的链接的所有样板
详细模式。你会看到类似的:
$ 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
特别注意您的-Bstatic 选项和以下链接选项:
-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
其中包括您的 -lcurl 以及默认系统库:
-lcurl -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
那就看documentation of the -Bstatic linker option:
-B静态
...
不要链接到共享库。这仅在支持共享库的平台上才有意义。
此选项的不同变体是为了与各种系统兼容。
您可以在命令行上多次使用此选项:它会影响库搜索后面的 -l 选项。
此选项还暗示 --unresolved-symbols=report-all。此选项可与 -shared 一起使用。
这样做意味着正在创建一个共享库,但该库的所有外部
引用必须通过从静态库中拉入条目来解决。
[我的重点]
因此,您的 -Bstatic 选项会指示链接器链接 static 版本的:
-lcurl -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
它会找到您已安装的静态libcurl.a。它无法找到一个
-lgcc_s 的静态库,因为没有安装任何 libgcc_s.a
你的系统。你只有这个和其他基本系统库的动态版本,
这很正常。
如果您希望链接器仅为-l 选项链接静态库您
指定,那么您必须在 -l 选项之前打开 -Bstatic 并关闭它
在他们之后,-Bdynamic,即使这使-Bdynamic 成为命令行中的最后一件事。
因为g++(或任何其他GCC前端,gcc,gfortran...)将添加-l
后台命令行选项。链接如下:
g++ -o prog prog.o -Wl,-Bstatic -lcurl -Wl,-Bdynamic
修复这个特定的链接错误。