Ann*_*wal 3 c++ linux linker g++ static-linking
我想静态链接库说libcurl。由于静态库和共享库都在同一文件夹中,因此我使用-Wl,-Bstatic来使链接程序知道使用静态库。
g++ -o prog prog.o -Wl,-Bstatic -lcurl.
Run Code Online (Sandbox Code Playgroud)
但是上面的命令给出了错误:
/usr/bin/ld: cannot find -lgcc_s
Run Code Online (Sandbox Code Playgroud)
如果我排除-Wl,-Bstatic,它可以正常工作,但是它将使用我不想要的共享库。
怎么了?
使用g++前端执行链接时,例如:
g++ -o prog prog.o -Wl,-Bstatic -lcurl
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
特别注意您的-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
Run Code Online (Sandbox Code Playgroud)
其中包括您的-lcurl以及默认的系统库:
-lcurl -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
Run Code Online (Sandbox Code Playgroud)
然后,查看链接器选项的文档-Bstatic:
-静态
...
不要链接共享库。这仅在支持共享库的平台上才有意义。此选项的不同变体是为了与各种系统兼容。您可以在命令行上多次使用此选项:它会影响库搜索其后的-l选项。 此选项还意味着--unresolved-symbols = report-all。此选项可与-shared一起使用。这样做意味着正在创建共享库,但是必须通过从静态库中提取条目来解析库的所有外部引用。
[我的重点]
因此,您的-Bstatic选项将链接器定向为链接以下静态版本:
-lcurl -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
Run Code Online (Sandbox Code Playgroud)
它会找到libcurl.a您已安装的静态文件。它找不到静态库,-lgcc_s因为libgcc_s.a您的系统上没有安装任何静态库。您只有此版本和其他基本系统库的动态版本,这很正常。
如果你想链接器链接静态库只为-l选项你
指定,那么你必须打开-Bstatic你之前-l的选择,并在他们之后将其关闭,-Bdynamic即使这使得-Bdynamic你的命令行的最后一件事。因为g++(或任何其他GCC前端gcc,,gfortran...)将在-l
后台向命令行添加选项。链接类似:
g++ -o prog prog.o -Wl,-Bstatic -lcurl -Wl,-Bdynamic
Run Code Online (Sandbox Code Playgroud)
解决此特定的链接错误。
| 归档时间: |
|
| 查看次数: |
3139 次 |
| 最近记录: |