GCC/G++選項 -Wl,--as-needed 原

    GCC/G++提供了 -Wl,--as-needed 和 -Wl,--no-as-needed 兩個選項,這兩個選項一個是開啓特性,一個是取消該特性。

    在生成可執行文件的時候,通過 -lxxx 選項指定需要鏈接的庫文件。以動態庫爲例,如果我們指定了一個需要鏈接的庫,則連接器會在可執行文件的文件頭中會記錄下該庫的信息。而後,在可執行文件運行的時候,動態加載器會讀取文件頭信息,並加載所有的鏈接庫。在這個過程中,如果用戶指定鏈接了一個毫不相關的庫,則這個庫在最終的可執行程序運行時也會被加載,如果類似這樣的不相關庫很多,會明顯拖慢程序啓動過程。

    這時,通過指定 -Wl,--as-needed 選項,鏈接過程中,鏈接器會檢查所有的依賴庫,沒有實際被引用的庫,不再寫入可執行文件頭。最終生成的可執行文件頭中包含的都是必要的鏈接庫信息。-Wl,--no-as-needed 選項不會做這樣的檢查,會把用戶指定的鏈接庫完全寫入可執行文件中。

    舉例如下:

    main.cc

#include <iostream>

int main() {
    std::cout << "Hello, World" << std::endl;
}

    1,使用 -Wl,--no-as-needed 選項,且編譯時指定加載不相關的 pthread庫。

            g++ -Wl,--no-as-needed -o main main.cc -lpthread

        (1)查看可執行文件main的文件頭中是否包含pthread庫:               

                    $ 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 選項指示在命令行中指定加載的所有庫都記錄到可執行文件頭中,並最終由動態加載器去加載。

                

   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章