是否可以更改 gcc 链接器的路径?

Is it possible to change the path to the linker for gcc?

我有一个在 Solaris 8 上编译的 gcc 二进制文件。为了实验,我将它带到了 NetBSD 8.2 虚拟机上,看看我是否可以让它在那个环境中工作。 gcc 的编译阶段似乎工作成功(即 gcc -c some_program.c),但如果涉及链接器,链接器似乎会生成分段违规。我怀疑这与 gcc 中的内置链接器路径有关。有没有办法在不完全重建二进制文件的情况下改变这个路径?

下面是 gcc -v -o small small.c 的输出,其中 small.c 只是 int main() { return 0; }:

Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/specs
gcc version 2.95.1 19990816 (release)
 /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/cpp -lang-c -v -D__GNUC__=2 -D__GNUC_MINOR__=95 -Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__sparc__ -D__sun__ -D__unix__ -D__svr4__ -D__SVR4 -D__sparc -D__sun -D__unix -Asystem(unix) -Asystem(svr4) -D__GCC_NEW_VARARGS__ -Acpu(sparc) -Amachine(sparc) small.c /var/tmp/ccibWaJl.i
GNU CPP version 2.95.1 19990816 (release) (sparc)
#include "..." search starts here:
#include <...> search starts here:
 .
 .
 .
 .
End of search list.
The following default directories have been omitted from the search path:
 /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/../../../../include/g++-3
End of omitted list.
 /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/cc1 /var/tmp/ccibWaJl.i -quiet -dumpbase small.c -version -o /var/tmp/ccCCiV6u.s
GNU C version 2.95.1 19990816 (release) (sparc-sun-solaris2.8) compiled by GNU C version 2.95.1 19990816 (release).
 /usr/ccs/bin/as -V -Qy -s -o /var/tmp/ccqr3F3G.o /var/tmp/ccCCiV6u.s
/usr/ccs/bin/as: Sun WorkShop 6 99/08/18
 /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/collect2 -V -Y P,/usr/ccs/lib:/usr/lib -Qy -o small /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/crt1.o /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/crti.o /usr/ccs/lib/values-Xa.o /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/crtbegin.o -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1 -L/usr/ccs/bin -L/usr/ccs/lib -L/usr/local/lib /var/tmp/ccqr3F3G.o -lgcc -lc -lgcc /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/crtend.o /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.1/crtn.o
collect2: ld terminated with signal 11 [Segmentation Fault]
ld: Software Generation Utilities - Solaris Link Editors: 5.8-1.281

更新: 为了比较,这里是在 NetBSD 上使用 gcc 二进制文件的相同编译字符串的输出:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/lto-wrapper
Target: sparc--netbsdelf
Configured with: /usr/src/tools/gcc/../../external/gpl3/gcc/dist/configure --target=sparc--netbsdelf --enable-long-long --enable-threads --with-bugurl=http://www.NetBSD.org/Misc/send-pr.html --with-pkgversion='NetBSD nb3 20180905' --with-system-zlib --disable-libstdcxx-dual-abi --enable-__cxa_atexit --enable-libstdcxx-time=rt --enable-libstdcxx-threads --with-diagnostics-color=auto-if-env --with-mpc-lib=/var/obj/mknative/sparc/usr/src/external/lgpl3/mpc/lib/libmpc --with-mpfr-lib=/var/obj/mknative/sparc/usr/src/external/lgpl3/mpfr/lib/libmpfr --with-gmp-lib=/var/obj/mknative/sparc/usr/src/external/lgpl3/gmp/lib/libgmp --with-mpc-include=/usr/src/external/lgpl3/mpc/dist/src --with-mpfr-include=/usr/src/external/lgpl3/mpfr/dist/src --with-gmp-include=/usr/src/external/lgpl3/gmp/lib/libgmp/arch/sparc --enable-tls --disable-multilib --disable-symvers --disable-libstdcxx-pch --disable-libstdcxx-dual-abi --build=sparc--netbsdelf --host=sparc--netbsdelf --with-sysroot=/var/obj/mknative/sparc/usr/src/destdir.sparc
Thread model: posix
gcc version 5.5.0 (nb3 20180905) 
COLLECT_GCC_OPTIONS='-v' '-o' 'small' '-mcpu=v7'
 /usr/libexec/cc1 -quiet -v small.c -quiet -dumpbase small.c -mcpu=v7 -auxbase small -version -o /tmp//ccZMD7zc.s
GNU C11 (nb3 20180905) version 5.5.0 (sparc--netbsdelf)
    compiled by GNU C version 5.5.0, GMP version 5.1.3, MPFR version 3.1.2, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=46 --param ggc-min-heapsize=30704
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/gcc-5
 /usr/include
End of search list.
GNU C11 (nb3 20180905) version 5.5.0 (sparc--netbsdelf)
    compiled by GNU C version 5.5.0, GMP version 5.1.3, MPFR version 3.1.2, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=46 --param ggc-min-heapsize=30704
Compiler executable checksum: 2df9f867f6d360c5052229962b633018
COLLECT_GCC_OPTIONS='-v' '-o' 'small' '-mcpu=v7'
 as -v -32 -relax -o /tmp//ccXtMemo.o /tmp//ccZMD7zc.s
GNU assembler version 2.27 (sparc--netbsdelf) using BFD version (NetBSD Binutils nb1) 2.27
COMPILER_PATH=/usr/libexec/
LIBRARY_PATH=/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'small' '-mcpu=v7'
 ld -plugin /usr/libexec/liblto_plugin.so -plugin-opt=/usr/libexec/lto-wrapper -plugin-opt=-fresolution=/tmp//ccyzsYKQ.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 -plugin-opt=-pass-through=-lc --eh-frame-hdr -m elf32_sparc -relax -dc -dp -e __start -dynamic-linker /usr/libexec/ld.elf_so -o small /usr/lib/crt0.o /usr/lib/crti.o /usr/lib/crtbegin.o /tmp//ccXtMemo.o --as-needed -lgcc_s --no-as-needed -lgcc -lc --as-needed -lgcc_s --no-as-needed -lgcc -lc /usr/lib/crtend.o /usr/lib/crtn.o

更新于 2022 年 4 月 20 日 5:46 下午美国东部时间: 我已经在我的 Solaris 8 虚拟机上安装了 gcc 版本 3.4.6 ,它似乎在那里工作。但是,无论何时 Solaris 8 gcc 二进制文件运行,将该二进制文件以及所有必要的库传输到 NetBSD 都会导致立即出现分段冲突。不过,来自 Solaris 8 VM 的其他一些动态链接的二进制文件似乎仍然有效。

我还尝试为原始 2.95.1 gcc 二进制文件指定 -B 标志,并传递包含 collect2 可执行文件的目录。这似乎对结果没有影响。也许我会尝试使用其他版本的 gcc...

根据 Eugene 在 OP 的第一条评论中的建议,单独调用链接器似乎奏效了。以下是我为获得可运行的可执行文件而采取的高级步骤:

  1. gcc -c编译小程序得到目标文件
  2. 运行 gcc-v 的所有阶段,以获取 gcc 尝试 运行.
  3. 的链接器命令
  4. 将该输出的链接器行复制到 shell 脚本,并替换链接器的相应路径以及包含正确路径的所有目标文件。
  5. -rpath 参数添加到命令以覆盖任何“*.so 找不到库”错误。
  6. 运行 shell 脚本。
  7. 运行 生成的程序。

也感谢所有对 OP 发表评论的人!