Gcc 如何在任意系统上查找和测试编译器正在使用的*实际链接器*?

Gcc 如何在任意系统上查找和测试编译器正在使用的*实际链接器*?,gcc,linker,clang,ld,icc,Gcc,Linker,Clang,Ld,Icc,我需要将一些对象从[某个汇编器|另一个编译器|一个存档]直接传递到链接器 但是在路径上找到的ld似乎[断开了|缺少|链接到错误的ABI]。 有时,我甚至找不到ld 我怎样才能找到C编译器所使用的实际链接器, [在Mac上|在Linux上|在BSD上|从一个配置脚本]?我必须弄清楚这一点。 这有点难,所以我想和大家分享一下 试一试: #!/usr/bin/env sh # 'main;' is the shortest C program possible (I think.). # So it

我需要将一些对象从[某个汇编器|另一个编译器|一个存档]直接传递到链接器

但是在路径上找到的
ld
似乎[断开了|缺少|链接到错误的ABI]。
有时,我甚至找不到
ld

我怎样才能找到C编译器所使用的实际链接器,

[在Mac上|在Linux上|在BSD上|从一个配置脚本]?

我必须弄清楚这一点。
这有点难,所以我想和大家分享一下

试一试:

#!/usr/bin/env sh

# 'main;' is the shortest C program possible (I think.).
# So it is compiled, linked, and written to /dev/null.
# So if the linker can't link, this should return 1.

for link in collect2 ld; do # Order matters, because of GCC.
 echo 'main;' | $CC -v -x c - -o /dev/null -\#\#\# 2>&1 | grep -q $link &&
 echo 'main;' | $CC -v -x c - -o /dev/null -\#\#\# 2>&1 | grep    $link |
 sed -e "s|\(.*$link\).*|\1|" -e 's/ //g' -e 's|"||' && break
done

# That should work on just about anything, and returns an absolute path,
# except with ICC. If we want to try to get an absolute path there too,
# we have to:

# If 'which' is missing, and it might not have an -s flag.
which="$(which which >/dev/null 2>&1)" || which=echo

$which "$(for link in collect2 ld; do
 echo 'main;' | $CC -v -x c - -o /dev/null -\#\#\# 2>&1 | grep -q $link &&
 echo 'main;' | $CC -v -x c - -o /dev/null -\#\#\# 2>&1 | grep    $link |
 sed -e "s|\(.*$link\).*|\1|" -e 's/ //g' -e 's|"||' && break
done)"
所以你可能会说

来吧,伙计,没必要这么做!就像,
哪个ld

老实说,这在我的大部分时间里都不起作用。
这在今天并不少见,因为
ld
通常是一个包装器

让我们测试一下,看看会出现什么情况:

#!/usr/bin/env sh

# On my Mac, nothing too special, I swear.
# Just a MacBook, Xcode, GCC from Homebrew, and one commercial compiler.


echo; $which ld; echo "...Not necessarily."; echo

for CC in cc gcc clang icc; do echo $c:
  for link in collect2 ld; do
    echo 'main;' | $CC -v -x c - -o /dev/null -\#\#\# 2>&1 | grep -q $link &&
    echo 'main;' | $CC -v -x c - -o /dev/null -\#\#\# 2>&1 | grep    $link |
       sed -e "s|\(.*$link\).*|\1|" -e 's/ //g' -e 's|"||' && break
   done

  which="$(which which 2>/dev/null 1>&1)" || which=echo
  $which "$(for link in collect2 ld; do
    echo 'main;' | $CC -v -x c - -o /dev/null -\#\#\# 2>&1 | grep -q $link &&
    echo 'main;' | $CC -v -x c - -o /dev/null -\#\#\# 2>&1 | grep    $link |
   sed -e "s|\(.*$link\).*|\1|" -e 's/ //g' -e 's|"||' && break
  done)"
  echo
done
返回:

/usr/bin/ld
...Not necessarily.

cc:
/Applications/Xcode51-Beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
/Applications/Xcode51-Beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld

gcc:
/Users/Shared/usr/local/Cellar/gcc49/4.9-20140119/libexec/gcc/x86_64-apple-darwin13.1.0/4.9.0/collect2
/Users/Shared/usr/local/Cellar/gcc49/4.9-20140119/libexec/gcc/x86_64-apple-darwin13.1.0/4.9.0/collect2

clang:
/Applications/Xcode51-Beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
/Applications/Xcode51-Beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld

icc:
ld
/usr/bin/ld

gcc和clang与
-print prog name=ld
-我不知道icc。您可以随时调用编译器来链接对象(无源)。@BrettHale事实上,我提出问题并给出答案正是因为
-print prog name=ld
并没有真正做到这一点(尽管我可能应该说一些这样的话)。例如,
gcc-print prog name=ld
只是在我的系统上吐回'ld',因为它实际上调用的是
collect2
包装,而不是'ld'。Re:'您可以随时调用编译器来代替'-这是真的吗?如果是这样的话,那就太好了,但是有几个选项我还没有弄清楚如何做到这一点。例如,一个
ld-r
如何通过编译器前端合并对象?对linker.Ha的每个参数使用
-Wl,
!我从来没有完全理解
-Wl
可以接受任何任意的参数-我想我认为它只能与链接器选项或其他东西一起使用。但你是100%正确的:
cc-Wl,-r,-Wl,foo.o,-Wl,bar.o,-Wl,-o,-Wl,foobar.o
工作正常。谢谢如果这不是一条评论,我会将其标记为“正确答案”。Stack Overflow告诉我需要接受答案或开始悬赏。所以当我在这里接受我自己的答案时;它不是:看。