2009-07-29 23 views
22

Trong ví dụ sau, chương trình sẽ in "foo được gọi là":Tại sao không __attribute __ ((constructor)) làm việc trong một thư viện tĩnh?

// foo.c 
#include <stdio.h> 

__attribute__((constructor)) void foo() 
{ 
    printf("foo called\n"); 
} 

// main.c 
int main() 
{ 
    return 0; 
} 

Nếu chương trình được biên dịch như thế này, nó hoạt động:

gcc -o test main.c foo.c 

Tuy nhiên, nếu foo.c được biên dịch vào một thư viện tĩnh, chương trình sẽ không in được gì cả.

gcc -c main.c 
gcc -c foo.c 
as rcs foo.a foo.o 
gcc -o test foo.a main.o 

Tại sao điều này xảy ra?

+0

Tại sao các downvotes? Có gì không chính xác? –

+0

Không chắc chắn (không phải tôi!) Nhưng có lẽ ai đó đã ngoại lệ để bạn trả lời câu hỏi của riêng bạn quá nhanh? – DaveR

+1

Hmm, tôi chỉ muốn thêm một tham chiếu hữu ích vào trang web cho một vấn đề không rõ ràng. Câu hỏi thường gặp cho thấy trả lời câu hỏi của chính mình là một điều tốt (đó là trong phần đầu tiên thực sự). –

Trả lời

13

Trình liên kết không bao gồm mã trong foo.a trong chương trình cuối cùng vì không có gì trong main.o tham chiếu đến nó. Nếu main.c được viết lại như sau, chương trình sẽ làm việc:

//main.c 

void foo(); 

int main() 
{ 
    void (*f)() = foo; 
    return 0; 
} 

Ngoài ra, khi biên soạn với một thư viện tĩnh, thứ tự của các đối số cho gcc (hoặc mối liên kết) rất có ý nghĩa: thư viện phải đến sau các đối tượng tham khảo nó.

gcc -o test main.o foo.a 
2

Như đã nêu, các ký hiệu không được tham chiếu từ lưu trữ không được đưa vào nhị phân đầu ra, vì trình liên kết loại bỏ chúng theo mặc định.

Để ghi đè hành vi này khi liên kết với thư viện tĩnh, --whole-archive/--no-whole-archive tùy chọn cho mối liên kết có thể được sử dụng, như thế này:

gcc -c main.c 
gcc -c foo.c 
ar rcs foo.a foo.o 
gcc -o test -Wl,--whole-archive foo.a -Wl,--no-whole-archive main.o 

Điều này có thể dẫn đến nhị phân cồng kềnh, bởi vì tất cả những biểu tượng từ foo.a sẽ được bao gồm bởi trình liên kết đến đầu ra, nhưng đôi khi nó được hợp lý hóa.

Các vấn đề liên quan