我需要傳遞一些對象[some assembler |另一個編譯器|一個檔案]直接鏈接到鏈接器。如何在任意系統上找到並測試編譯器正在使用的*實際鏈接器?
但似乎在路徑上找到的ld
是[broken |缺少|鏈接錯誤的ABI]。
有時,我根本找不到ld
。
無論C編譯器是什麼,我如何才能找到正在使用的實際鏈接器,
[在Mac上|在Linux上在BSD |上從配置腳本]?
我需要傳遞一些對象[some assembler |另一個編譯器|一個檔案]直接鏈接到鏈接器。如何在任意系統上找到並測試編譯器正在使用的*實際鏈接器?
但似乎在路徑上找到的ld
是[broken |缺少|鏈接錯誤的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)"
所以,你可能剛纔所說的,
來吧傢伙,沒辦法這是必要的!就像,
which 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
堆棧溢出告訴我,我需要接受一個答案或開始賞金。所以雖然我要在這裏接受我自己的答案,它不是:請參閱[對問題的最後評論](http://stackoverflow.com/questions/21605720/how-can-i-find-and-test-the-actual-linker-a-compiler-is-using -on-AN-任意#comment32666361_21605720)。 –
gcc和鐺用'-print-PROG-NAME = ld' - 我不知道ICC 。您始終可以調用編譯器來鏈接對象(無源代碼)。 –
@BrettHale其實,我提出的問題和答案恰恰是因爲 '-print-prog-name = ld'並沒有真正做到這一點(儘管我可能應該說一些這樣的效果)。例如,'gcc -print-prog-name = ld'只是簡單地將'ld'回傳給我的系統,因爲它實際上調用'collect2'包裝器,而不是'ld'。 –
Re:'你總是可以調用編譯器來代替' - 這是真的嗎?如果這樣做會很好,但有幾個選項我一直無法弄清楚如何做到這一點。 例如,一個'ld -r',如何通過編譯器前端合併對象? –