2008-11-08 34 views
19

Dường như có 3 cách để nói với GCC để mắt xích yếu một biểu tượng:Làm thế nào để làm việc liên kết yếu với GCC?

  • __attribute__((weak_import))
  • __attribute__((weak))
  • #pragma weak symbol_name

Không ai trong số những công việc cho tôi:

#pragma weak asdf 
extern void asdf(void) __attribute__((weak_import, weak)); 
... 
{ 
    if(asdf != NULL) asdf(); 
} 

Tôi luôn gặp phải lỗi liên kết như thế này:

Undefined symbols: 
    "_asdf", referenced from: 
     _asdf$non_lazy_ptr in ccFA05kN.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status

Tôi đang sử dụng GCC 4.0.1 trên OS X 10.5.5. Tôi đang làm gì sai?

+0

'int __attribute __ ((yếu)) main() {...}' hoạt động tốt đối với tôi với gcc/Mac OS X, nhưng không biên dịch được với gcc/MinGW. :( – mcandre

+0

điều này có thể là vấn đề: http://stackoverflow.com/questions/13089166/how-to-make-gcc-link-strong-symbol-in-static-library-to-overwittren-weak-symbol –

Trả lời

0

Từ doc thủ gcc:

yếu

The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions which can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker.

có nghĩa là một đối tượng được hợp thức hóa để ghi đè lên một biểu tượng yếu (được định nghĩa trong một đối tượng/thư viện) mà không bị lỗi lúc liên kết . Điều không rõ là liệu bạn có đang liên kết thư viện với biểu tượng yếu hay không. Có vẻ như cả hai bạn đã không xác định biểu tượng và thư viện không được liên kết đúng cách.

+0

Có có vẻ là hai cách sử dụng liên kết yếu: http://gcc.gnu.org/ml/gcc/1999-02n/msg01219.html Tôi đang cố liên kết với phiên bản cũ của thư viện. Phiên bản hiện tại xác định các hàm –

+1

Trích dẫn đó không áp dụng ở đây: "Thiết kế liên kết yếu của Mac OS X [xuất phát từ Trình quản lý phân đoạn mã Mac OS cổ điển ] Nếu bạn quen thuộc với [ELF], bạn có thể được sử dụng với một ý nghĩa khác cho các cụm từ * biểu tượng yếu * hoặc * liên kết yếu, * trong đó một biểu tượng yếu có thể bị ghi đè bởi một biểu tượng không yếu. là * định nghĩa yếu * —xem [[Phạm vi và điều trị các định nghĩa biểu tượng ”] (http://developer.apple.com/libra ry/mac/# documentation/DeveloperTools/Khái niệm/MachOTopics/1-Các bài viết/executing_files.html # // apple_ref/doc/uid/TP40001829-98432-TPXREF120) để biết thêm thông tin. " –

4

Bạn cần đặt biến MACOSX_DEPLOYMENT_TARGET thành 10.2 trở lên. Xem Apple's documentationtechnote của họ khi liên kết yếu.

+0

Tôi đã nhìn thấy nó, và nó là đặt theo cách đó. Đó không phải là lỗi tôi nhận được. –

6

Thêm -Wl,-flat_namespace,-undefined,dynamic_lookup vào dòng trình biên dịch gcc mà bạn sử dụng để thực hiện liên kết cuối cùng.

+1

Khi tôi sử dụng gcc/MinGW, nó nói 'cc1.exe: lỗi: tùy chọn dòng lệnh không được công nhận "-flat_namespace, -undefined, dynamic_lookup" '. – mcandre

28

Tôi chỉ xem xét điều này và nghĩ rằng một số người khác có thể quan tâm đến những phát hiện của tôi.

Kết nối yếu với weak_import thực sự chỉ hoạt động tốt với thư viện động. Bạn có thể làm cho nó hoạt động với liên kết tĩnh (bằng cách xác định dynamic_lookup -undefined như đã đề xuất ở trên) nhưng đây không phải là một ý tưởng nóng. Nó có nghĩa là không có ký hiệu không xác định sẽ được phát hiện cho đến khi chạy. Đây là điều tôi sẽ tránh trong mã sản xuất, cá nhân.

Đây là một phiên Mac OS X Terminal cho thấy làm thế nào để làm cho nó hoạt:

Dưới đây là fc

int f(int n) 
{ 
    return n * 7; 
} 

Đây là whatnof.c

#include <stdio.h> 
#include <stdlib.h> 

extern int f (int) __attribute__((weak_import)); 

int main() { 
    if(f == NULL) 
     printf("what, no f?\n"); 
    else 
     printf("f(8) is %d\n", f(8)); 
    exit(0); 
} 

Thực hiện một thư viện động từ fc:

$ cc -dynamiclib -o f.dylib f.c 

Biên dịch và liên kết với lib động, liệt kê các lib động.

$ cc -o whatnof whatnof.c f.dylib 
$ otool -L whatnof 
whatnof: 
     f.dylib (compatibility version 0.0.0, current version 0.0.0) 
     /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0) 

Run whatnof để xem những gì sẽ xảy ra:

$ whatnof 
f(8) is 56 

Bây giờ thay thế f.dylib với một thư viện rỗng (không có kí tự):

$ mv f.dylib f.dylib.real 
$ touch null.c 
$ cc -dynamiclib -o f.dylib null.c 

Run cùng whatnof để xem những gì sẽ xảy ra:

$ whatnof 
what, no f? 

Ý tưởng cơ bản (hoặc "trường hợp sử dụng") cho weak_import là nó cho phép bạn liên kết chống lại một tập hợp các thư viện động (được chia sẻ), nhưng sau đó chạy cùng một mã với các phiên bản trước đó của cùng một thư viện. Bạn có thể kiểm tra các hàm so với NULL để xem chúng có được hỗ trợ trong thư viện động cụ thể mà mã hiện đang chạy không. Điều này có vẻ là một phần của mô hình phát triển cơ bản được hỗ trợ bởi Xcode. Tôi hy vọng ví dụ này hữu ích; nó đã giúp tâm trí tôi thoải mái về phần này của thiết kế Xcode.