GCC/G++提供了 -Wl,--as-needed 和 -Wl,--no-as-needed 兩個選項,這兩個選項一個是開啓特性,一個是取消該特性。linux
在生成可執行文件的時候,經過 -lxxx 選項指定須要連接的庫文件。以動態庫爲例,若是咱們指定了一個須要連接的庫,則鏈接器會在可執行文件的文件頭中會記錄下該庫的信息。然後,在可執行文件運行的時候,動態加載器會讀取文件頭信息,並加載全部的連接庫。在這個過程當中,若是用戶指定連接了一個絕不相關的庫,則這個庫在最終的可執行程序運行時也會被加載,若是相似這樣的不相關庫不少,會明顯拖慢程序啓動過程。ios
這時,經過指定 -Wl,--as-needed 選項,連接過程當中,連接器會檢查全部的依賴庫,沒有實際被引用的庫,再也不寫入可執行文件頭。最終生成的可執行文件頭中包含的都是必要的連接庫信息。-Wl,--no-as-needed 選項不會作這樣的檢查,會把用戶指定的連接庫徹底寫入可執行文件中。c++
舉例以下:spa
main.cc命令行
#include <iostream>io
int main() {
std::cout << "Hello, World" << std::endl;
}編譯
1,使用 -Wl,--no-as-needed 選項,且編譯時指定加載不相關的 pthread庫。thread
g++ -Wl,--no-as-needed -o main main.cc -lpthreadstream
(1)查看可執行文件main的文件頭中是否包含pthread庫: gcc
$ ldd main
linux-vdso.so.1 => (0x00007fff0fbb0000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe9452d4000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fe944f52000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe944c49000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe944a33000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe944669000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe9454f1000)
可見可執行文件main中包含了不相關的pthread庫。
(2)查看運行時是否加載pthread庫。
$ strace ./main
...
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
...
可見,在程序運行時也加載了pthread庫。
2,使用 -Wl,--as-needed 選項,且編譯時指定加載不相關的 pthread庫。
g++ -Wl,--as-needed -o main main.cc -lpthread
(1)查看可執行文件main的文件頭中是否包含pthread庫:
$ ldd main
linux-vdso.so.1 => (0x00007ffecb5b6000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff99f7ca000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff99f400000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff99f0f7000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff99fb4c000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff99eee1000)
可見即便在命令行中指定了 -lpthread,一旦指定了 -Wl,--as-needed 選項,因爲pthread庫不是必須的,因此不會在可執行文件中記錄 pthread 庫。
(2)經過執行 strace ./main 命令,運行結果顯示也不會去加載pthread庫。
總結:-Wl,--as-needed 選項指示最終的可執行文件中只包含必要的連接庫信息,-Wl,--no-as-needed 選項指示在命令行中指定加載的全部庫都記錄到可執行文件頭中,並最終由動態加載器去加載。