静态链接库时,出现链接器错误:找不到-lgcc_s

时间:2018-08-24 06:48:18

标签: c++ linux linker g++ static-linking

我想静态链接一个库,例如libcurl。由于静态库和共享库都在同一文件夹中,因此我使用-Wl,-Bstatic来使链接程序知道使用静态库。

g++ -o prog prog.o -Wl,-Bstatic -lcurl. 

但是上面的命令给出了错误:

/usr/bin/ld: cannot find -lgcc_s

如果我排除-Wl,-Bstatic,它可以正常工作,但是它将使用我不想要的共享库。

出了什么问题?

1 个答案:

答案 0 :(得分:4)

使用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

  

-静态

     

...

     

不链接共享库。这仅在支持共享库的平台上才有意义。   此选项的不同变体是为了与各种系统兼容。   您可以在命令行上多次使用此选项:它会影响库搜索其后的-l选项。   此选项还意味着--unresolved-symbols = report-all。此选项可与-shared一起使用。   这样做意味着正在创建共享库,但是所有库的外部   引用必须通过从静态库中提取条目来解决。

[我的重点]

因此,您的-Bstatic选项将链接器定向为链接以下的静态版本:

-lcurl -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc

它将找到您已安装的静态libcurl.a。找不到 -lgcc_s的静态库,因为未安装任何libgcc_s.a 你的系统。您只有该版本和其他基本系统库的动态版本, 这很正常。

如果您希望链接程序仅链接静态库 ,以获取-l选项 指定,则必须在-Bstatic选项之前打开-l并将其关闭 在它们之后-Bdynamic,即使这使-Bdynamic成为您命令行中的最后一件事。 由于g++(或任何其他GCC前端,gccgfortran ...)将添加-l 后台命令行选项。链接类似:

g++ -o prog prog.o -Wl,-Bstatic -lcurl -Wl,-Bdynamic

修复此特定的链接错误。