2014-10-02 227 views
7

最近我創建一個可加載模塊,並發現這兩種GCC和LD鏈接有什麼區別?

gcc -fPIC --shared -o foo.so.1 foo.c 

gcc -fPIC --shared -c foo.c 
ld --shared -o foo.so.2 foo.o 

可以達到同樣的效果。

我還發現,foo.so.1是大約3KB比foo.so.2大,

gcc -### -fPIC --shared -o foo.so.1 foo.c 

透露,GCC比添加其他的foo.c東西到foo.so.1(例如,crtendS.o和crtn.o):

/usr/lib/gcc/x86_64-linux-gnu/4.7/collect2 "--sysroot=/" --build-id --no-add-needed --eh-frame-hdr -m elf_x86_64 "--hash-style=both" -shared -o foo.so.1 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/4.7 -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../.. /tmp/cc3JBdCJ.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crtn.o 

由於兩個foo.so.1和foo.so.2可以通過dlopen的加載,我想知道:

  1. 有什麼區別betwe這兩個鏈接方法?
  2. crtendS.o和crtn.o是否對創建的庫中的函數有所不同?

回答

6

原則上沒有區別。當你「通過gcc鏈接」時,它實際上調用ld。如果在「通過gcc鏈接」鏈接階段收到消息,您會立即發現它實際上來自ld。如果您想將某些特定於ld的命令行選項傳遞給ld,gcc的命令行界面具有專門用於此目的的功能(-Xlinker-Wl選項)。

至於額外的對象文件......它們可能包含由編譯器隱式添加的全局加載時間庫初始化/解除初始化代碼。 (請求標準庫?)您可以在這裏找到一些有關它的信息:https://gcc.gnu.org/onlinedocs/gccint/Initialization.html

+0

如果「gcc鏈接」結果與直接ld調用不同,那麼gcc必須通過將附加參數(options,libs)傳遞給ld來實現該目的。 – 2014-10-02 01:30:46