Ubuntu

為什麼我應該在編譯器命令行上將源文件名放在庫名之前?

  • March 17, 2018

作為 OpenSUSE 的使用者,我習慣於輸入:

gcc -lz myfile.c

我很驚訝在 Ubuntu 上這個命令會失敗,比如:

myfile.c:(.text+0x5): undefined reference to `zlibVersion'
collect2: error: ld returned 1 exit status

gcc -v我發現 Ubuntu 上的 GCC C 編譯器生成的命令在OpenSUSEcollect2上以 while 開頭,--as-needed這個選項不存在。即 Ubuntu 上的命令行如下所示:

/usr/lib/gcc/x86_64-linux-gnu/5/collect2 --build-id --eh-frame-hdr\
-m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker \
....[a lot of stuff removed].....\
-lz /tmp/cc7kz9Nz.o ....[yet more stuff removed].....\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o

在 OpenSUSE 上,它看起來非常相似,但--as-needed選項不同。

/usr/lib64/gcc/x86_64-suse-linux/4.8/collect2 --build-id --eh-frame-hdr\
-m elf_x86_64 -dynamic-linker \
....[a lot of stuff removed].....\
-lz /tmp/cccpZlmL.o ....[yet more stuff removed].....\
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../lib64/crtn.o

這種差異從何而來?有沒有在什麼地方討論過?我不應該將庫名放在源文件名之前嗎?

這記錄在 Ubuntu wiki 上。它預設設置為減少包中依賴項的數量,但正如您發現的那樣,這意味著庫的順序很重要:您需要確保對象(任何類型)出現在它們使用的庫之前。

您可以使用 禁用此功能--no-as-needed

引用自:https://unix.stackexchange.com/questions/430373