2013-01-19 29 views
9

Hãy xem xét các chương trình hello world C:Làm cách nào để xác định tùy chọn dòng lệnh nào gcc chuyển sang ld theo mặc định?

hello.c:

#include "stdio.h" 

int main() 
{ 
     printf("Hello, World!\n"); 
} 

Nếu tôi gọi:

$ gcc -c hello.c -o hello.o 

Nó sẽ tạo ra một ELF relocatable file hello.o

Nếu sau đó tôi gọi:

$ gcc hello.o -o hello   [1] 

Nó sẽ liên kết với hello.o ld và tạo ra một ELF thực thi tập tin chào

Tuy nhiên nếu tôi gọi ld trực tiếp [2] thay vì [1]:

$ ld hello.o -o hello    [2] 

tôi nhận được các lỗi này:

/usr/bin/ld.bfd.real: warning: cannot find entry symbol _start 
test.c:(.text+0xa): undefined reference to `puts' 

gcc phải được đi qua các tùy chọn khác để ld (để liên kết thư viện C chẳng hạn).

Có cách nào để xác định chính xác những gì dòng lệnh gcc chuyển qua ld trong lệnh [1]?

Trả lời

15

Có, bạn có thể sử dụng gcc -v hello.o -o hello để nhận đường liên kết. Ví dụ của bạn trên máy ubuntu của tôi, tôi nhận được dòng liên kết này (chỉnh sửa để được Multiline cho dễ đọc):

/usr/lib/gcc/x86_64-linux-gnu/4.4.5/collect2 
--build-id 
--eh-frame-hdr 
-m elf_x86_64 
--hash-style=gnu 
-dynamic-linker 
/lib64/ld-linux-x86-64.so.2 
-o hello 
-z relro 
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o 
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crti.o 
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtbegin.o 
-L/usr/lib/gcc/x86_64-linux-gnu/4.4.5 
-L/usr/lib/gcc/x86_64-linux-gnu/4.4.5 
-L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib 
-L/lib/../lib 
-L/usr/lib/../lib 
-L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../.. -L/usr/lib/x86_64-linux-gnu 
hello.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.4.5/crtend.o 
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crtn.o 

Lưu ý rằng collect2 chỉ là một bí danh cho ld.

+1

Có vẻ như trên hộp Ubuntu 12,10 64 của tôi 'collect2' không phải là một bí danh đơn giản cho 'ld'. 'collect2' là một tập tin thực thi - trong khi' ld' là một liên kết sym tới 'ld.bfd', là một liên kết tượng trưng đến' hardened-ld', là một kịch bản perl. Không biết chuyện gì đang xảy ra ở đó. –

+1

Xin lỗi, tôi không có nghĩa là bí danh theo nghĩa đen. Bạn sẽ thấy rằng nếu bạn chạy lệnh tương tự với 'ld' thay vào đó nó sẽ hoạt động tương tự. Tài liệu: http://gcc.gnu.org/onlinedocs/gcc-4.3.5/gccint/Collect2.html –

+0

Sự khác nhau giữa 'collection2' và' ld' là gì? Không thể hiểu dễ dàng sau khi đọc gccint. –