【C++随记】collect2: error: ld returned 1 exit status错误分析与解决

avatar
作者
筋斗云
阅读量:3

目录

1、问题背景

2、解决方法

2.1 深入编译过程

1)查看error发生点

2)复现error

2.2 缩小case

2.3 确定问题

2.4 静态编译和动态编译的效果

参考文献:


1、问题背景

        在项目工程代码编译过程中,出现以下报警

/usr/bin/ld: cannot find -lstdc++ collect2: error: ld returned 1 exit status make[2]: *** [runtime/CMakeFiles/testrt_shared.dir/build.make:209: runtime/libtestrt_shared.so] Error 1 make[1]: *** [CMakeFiles/Makefile2:1611: runtime/CMakeFiles/testrt_shared.dir/all] Error 2 make[1]: *** Waiting for unfinished jobs....

2、解决方法

2.1 深入编译过程

1)查看error发生点

通过以上log,进入过程文件路径 build.make下,发现有生成一个link.txt的log日志。ld的错误,就是链接过程中出现了错误。

打开link.txt,里面内容如下

/usr/bin/c++ -fPIC  -std=c++11 -fPIC -fvisibility=hidden -Wall -pthread -fno-strict-aliasing -ftemplate-depth=2014 -O3 -DNDEBUG -static-libgcc -static-libstdc++ -Wl,--version-script=/home/admin1/guan/s2_runtime_20240511/s2_runtime/runtime/version-script-testrt.map -shared -Wl,-soname,libtestrt_shared.so -o libtestrt_shared.so CMakeFiles/testrt_shared.dir/test_rt/ta.cpp.o CMakeFiles/testrt_shared.dir/test_rt/fatbin_registry.cpp.o CMakeFiles/testrt_shared.dir/test_error.cpp.o CMakeFiles/testrt_shared.dir/test_runtime.cpp.o CMakeFiles/testrt_shared.dir/test_command.cpp.o CMakeFiles/testrt_shared.dir/test_compiler_api.cpp.o CMakeFiles/testrt_shared.dir/test_internal.cpp.o CMakeFiles/testrt_shared.dir/fp16.c.o  -ldl

2)复现error

在build路径下,重新执行link.txt中的指令。发现可以复现现象。在复现的指令后面,增加参数 -v,可以得到更具体的过程log。

/usr/bin/c++ -fPIC  -std=c++11 -fPIC -fvisibility=hidden -Wall -pthread -fno-strict-aliasing -ftemplate-depth=2014 -g -static-libgcc -static-libstdc++ -Wl,--version-script=/home/admin1/guan/s2_runtime_20240511/s2_runtime/runtime/version-script-testrt.map -shared -Wl,-soname,libtestrt_sharedd.so -o libtestrt_sharedd.so CMakeFiles/testrt_shared.dir/test_rt/ta.cpp.o CMakeFiles/testrt_shared.dir/test_rt/fatbin_registry.cpp.o CMakeFiles/testrt_shared.dir/test_error.cpp.o CMakeFiles/testrt_shared.dir/test_runtime.cpp.o CMakeFiles/testrt_shared.dir/test_command.cpp.o CMakeFiles/testrt_shared.dir/test_compiler_api.cpp.o CMakeFiles/testrt_shared.dir/test_internal.cpp.o CMakeFiles/testrt_shared.dir/fp16.c.o  -ldl -v
Using built-in specs.
COLLECT_GCC=/usr/bin/c++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/11/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-host-pie --enable-host-bind-now --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.rockylinux.org/ --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-plugin --enable-initfini-array --without-isl --enable-multilib --with-linker-hash-style=gnu --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_64=x86-64-v2 --with-arch_32=x86-64 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.4.1 20231218 (Red Hat 11.4.1-3) (GCC)
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/11/:/usr/libexec/gcc/x86_64-redhat-linux/11/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/11/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/11/:/usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/11/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-std=c++11' '-fPIC' '-fvisibility=hidden' '-Wall' '-pthread' '-fno-strict-aliasing' '-ftemplate-depth=2014' '-g' '-static-libgcc' '-shared' '-o' 'libtestrt_sharedd.so' '-v' '-mtune=generic' '-march=x86-64-v2' '-dumpdir' 'libtestrt_sharedd.so.'
 /usr/libexec/gcc/x86_64-redhat-linux/11/collect2 -plugin /usr/libexec/gcc/x86_64-redhat-linux/11/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/11/lto-wrapper -plugin-opt=-fresolution=/tmp/ccDybwv6.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -shared -o libtestrt_sharedd.so /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/11/crtbeginS.o -L/usr/lib/gcc/x86_64-redhat-linux/11 -L/usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/11/../../.. --version-script=/home/admin1/guan/s2_runtime_20240511/s2_runtime/runtime/version-script-testrt.map -soname libtestrt_sharedd.so CMakeFiles/testrt_shared.dir/test_rt/ta.cpp.o CMakeFiles/testrt_shared.dir/test_rt/fatbin_registry.cpp.o CMakeFiles/testrt_shared.dir/test_error.cpp.o CMakeFiles/testrt_shared.dir/test_runtime.cpp.o CMakeFiles/testrt_shared.dir/test_command.cpp.o CMakeFiles/testrt_shared.dir/test_compiler_api.cpp.o CMakeFiles/testrt_shared.dir/test_internal.cpp.o CMakeFiles/testrt_shared.dir/fp16.c.o -ldl -Bstatic -lstdc++ -Bdynamic -lm -lgcc -lgcc_eh -lpthread -lc -lgcc -lgcc_eh /usr/lib/gcc/x86_64-redhat-linux/11/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crtn.o
/usr/bin/ld: cannot find -lstdc++
collect2: error: ld returned 1 exit status

然后再单独执行collect2这条红色的语句,可以复现。并且发现,报错点事 找不到stdc++库。

针对collect2指令,增加-debug参数,以获取更多的log。

/usr/libexec/gcc/x86_64-redhat-linux/11/collect2 -plugin /usr/libexec/gcc/x86_64-redhat-linux/11/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/11/lto-wrapper -plugin-opt=-fresolution=/tmp/ccINdTEJ.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -shared -o libtestrt_sharedd.so /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/11/crtbeginS.o -L/usr/lib/gcc/x86_64-redhat-linux/11 -L/usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/11/../../.. --version-script=/home/admin1/guan/s2_runtime_20240511/s2_runtime/runtime/version-script-testrt.map -soname libtestrt_sharedd.so CMakeFiles/testrt_shared.dir/test_rt/ta.cpp.o CMakeFiles/testrt_shared.dir/test_rt/fatbin_registry.cpp.o CMakeFiles/testrt_shared.dir/test_error.cpp.o CMakeFiles/testrt_shared.dir/test_runtime.cpp.o CMakeFiles/testrt_shared.dir/test_command.cpp.o CMakeFiles/testrt_shared.dir/test_compiler_api.cpp.o CMakeFiles/testrt_shared.dir/test_internal.cpp.o CMakeFiles/testrt_shared.dir/fp16.c.o -ldl -Bstatic -lstdc++ -Bdynamic -lm -lgcc -lgcc_eh -lpthread -lc -lgcc -lgcc_eh /usr/lib/gcc/x86_64-redhat-linux/11/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crtn.o -debug
Convert string '/home/admin1/.local/bin:/home/admin1/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin' into prefixes, separator = ':'
  - add prefix: /home/admin1/.local/bin/
  - add prefix: /home/admin1/bin/
  - add prefix: /usr/local/bin/
  - add prefix: /usr/bin/
  - add prefix: /usr/local/sbin/
  - add prefix: /usr/sbin/

Looking for 'real-ld'
  - failed: no entries in prefix list
Looking for 'collect-ld'
  - failed: no entries in prefix list
Looking for 'ld'
  - failed: no entries in prefix list
Looking for 'ld'
Looking for 'gnm'
  - failed: no entries in prefix list
Looking for 'gnm'
Looking for 'nm'
  - failed: no entries in prefix list
Looking for 'nm'
Looking for 'gstrip'
  - failed: no entries in prefix list
Looking for 'gstrip'
Looking for 'strip'
  - failed: no entries in prefix list
Looking for 'strip'
Looking for 'gcc'
  - failed: no entries in prefix list
Looking for 'gcc'
collect2 version 11.4.1 20231218 (Red Hat 11.4.1-3)
ld_file_name        = /usr/bin/ld
c_file_name         = /usr/bin/gcc
nm_file_name        = /usr/bin/nm
strip_file_name     = /usr/bin/strip
c_file              = libtestrt_sharedd.so.cdtor.c
o_file              = libtestrt_sharedd.so.cdtor.o

/usr/bin/ld -plugin /usr/libexec/gcc/x86_64-redhat-linux/11/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/11/lto-wrapper -plugin-opt=-fresolution=/tmp/ccINdTEJ.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -shared -o libtestrt_sharedd.so /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/11/crtbeginS.o -L/usr/lib/gcc/x86_64-redhat-linux/11 -L/usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/11/../../.. --version-script=/home/admin1/guan/s2_runtime_20240511/s2_runtime/runtime/version-script-testrt.map -soname libtestrt_sharedd.so CMakeFiles/testrt_shared.dir/test_rt/ta.cpp.o CMakeFiles/testrt_shared.dir/test_rt/fatbin_registry.cpp.o CMakeFiles/testrt_shared.dir/test_error.cpp.o CMakeFiles/testrt_shared.dir/test_runtime.cpp.o CMakeFiles/testrt_shared.dir/test_command.cpp.o CMakeFiles/testrt_shared.dir/test_compiler_api.cpp.o CMakeFiles/testrt_shared.dir/test_internal.cpp.o CMakeFiles/testrt_shared.dir/fp16.c.o -ldl -Bstatic -lstdc++ -Bdynamic -lm -lgcc -lgcc_eh -lpthread -lc -lgcc -lgcc_eh /usr/lib/gcc/x86_64-redhat-linux/11/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crtn.o
/usr/bin/ld: cannot find -lstdc++
collect2: error: ld returned 1 exit status

怀疑1:系统中是不是不存在libstdc++.so的库。

怀疑2:还是ld执行的时候,给与的查找路径中没有包含libstdc++.so的库。

2.2 缩小case

为了跟踪问题方便,于是引用了参考文献1中的testcase,用最小case复现问题。

#include <iostream>  using namespace std;  int main() {     cout << "Hello World!" << endl;     return 0; } 

用最小case复现时,执行以下指令,编译可以成功

/usr/bin/cc helloworld.cpp -lstdc++ -o hello

但是,用以下指令执行的时候,就复现了问题。

/usr/bin/c++ helloworld.cpp -static-libstdc++ -o hello -v
Using built-in specs.
COLLECT_GCC=/usr/bin/c++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/11/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-host-pie --enable-host-bind-now --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.rockylinux.org/ --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-plugin --enable-initfini-array --without-isl --enable-multilib --with-linker-hash-style=gnu --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_64=x86-64-v2 --with-arch_32=x86-64 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.4.1 20231218 (Red Hat 11.4.1-3) (GCC)
COLLECT_GCC_OPTIONS='-o' 'hello' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64-v2' '-dumpdir' 'hello-'
 /usr/libexec/gcc/x86_64-redhat-linux/11/cc1plus -quiet -v -D_GNU_SOURCE helloworld.cpp -quiet -dumpdir hello- -dumpbase helloworld.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64-v2 -version -o /tmp/ccWZZR6d.s
GNU C++17 (GCC) version 11.4.1 20231218 (Red Hat 11.4.1-3) (x86_64-redhat-linux)
        compiled by GNU C version 11.4.1 20231218 (Red Hat 11.4.1-3), GMP version 6.2.0, MPFR version 4.1.0-p9, MPC version 1.2.1, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/11/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11
 /usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/x86_64-redhat-linux
 /usr/lib/gcc/x86_64-redhat-linux/11/../../../../include/c++/11/backward
 /usr/lib/gcc/x86_64-redhat-linux/11/include
 /usr/local/include
 /usr/include
End of search list.
GNU C++17 (GCC) version 11.4.1 20231218 (Red Hat 11.4.1-3) (x86_64-redhat-linux)
        compiled by GNU C version 11.4.1 20231218 (Red Hat 11.4.1-3), GMP version 6.2.0, MPFR version 4.1.0-p9, MPC version 1.2.1, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 9405b6ffeb72113ec6541eb381112dcb
COLLECT_GCC_OPTIONS='-o' 'hello' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64-v2' '-dumpdir' 'hello-'
 as -v --64 -o /tmp/cc5PDA9p.o /tmp/ccWZZR6d.s
GNU assembler version 2.35.2 (x86_64-redhat-linux) using BFD version version 2.35.2-37.el9
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/11/:/usr/libexec/gcc/x86_64-redhat-linux/11/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/11/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/11/:/usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/11/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-o' 'hello' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64-v2' '-dumpdir' 'hello.'
 /usr/libexec/gcc/x86_64-redhat-linux/11/collect2 -plugin /usr/libexec/gcc/x86_64-redhat-linux/11/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/11/lto-wrapper -plugin-opt=-fresolution=/tmp/ccHq0SBv.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 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/11/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/11 -L/usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/11/../../.. /tmp/cc5PDA9p.o -Bstatic -lstdc++ -Bdynamic -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/11/crtend.o /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crtn.o
/usr/bin/ld: cannot find -lstdc++
collect2: error: ld returned 1 exit status
 

现在才关注到这个c++的编译参数,-static-libstdc++。所以特别搜了一下,这个参数的作用。具体可以见参考文献2。

所以,既然是静态链接的方式去做编译。那么,我们的系统中有libstdc++.a的静态库么?

2.3 确定问题

通过以下指令,查看当前系统安装的stdc的库。

最后,可在以下页面进行libstdc++-static的安装。

Libstdc++-static Download for Linux (rpm)

https://pkgs.org/download/libstdc++-static

由于我的是rocky系统,最终采用以下指令,完成了安装。

sudo dnf --enablerepo=devel install libstdc++-static

安装完成的效果。

验证一下效果。

2.4 静态编译和动态编译的效果

通过下面指令编译以后,通过ldd查看,效果如下。可见,可执行文件是一种动态链接的方式。

/usr/bin/cc helloworld.cpp -lstdc++ -o hello

[admin1@localhost work]$ ldd hello         linux-vdso.so.1 (0x00007fff4098a000)         libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f7fbe800000)         libc.so.6 => /lib64/libc.so.6 (0x00007f7fbe400000)         libm.so.6 => /lib64/libm.so.6 (0x00007f7fbe725000)         /lib64/ld-linux-x86-64.so.2 (0x00007f7fbea80000)         libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f7fbea59000) [admin1@localhost work]$  -rwxr-xr-x.  1 admin1 admin1  25K May 16 17:21 hello

而通过静态参数去编译的效果如下:

/usr/bin/c++ helloworld.cpp -static-libstdc++ -o hello

[admin1@localhost work]$ ldd hello         linux-vdso.so.1 (0x00007ffd0952c000)         libm.so.6 => /lib64/libm.so.6 (0x00007fd64faf8000)         libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fd64fadd000)         libc.so.6 => /lib64/libc.so.6 (0x00007fd64f800000)         /lib64/ld-linux-x86-64.so.2 (0x00007fd64fbdf000) [admin1@localhost work]$   -rwxr-xr-x.  1 admin1 admin1 1.3M May 16 17:20 hello 

编译出来的hello大小,也发生了很大的变化。
 

以下是解决过程中的参考文献。如有侵权请告知,会及时删除。谢谢

参考文献:

1. 采用了以下中的c++ testcase

【C++随记】collect2: error: ld returned 1 exit status错误分析与解决

2. -static-libstdc++的作用

gcc 链接选项-static -static-libstdc++ -static-libgcc使用分析
 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!