2012-09-13 27 views
5

Trong một dự án, đồng nghiệp của tôi tạo một thư viện tĩnh, ví dụ: liba.a, được liên kết với ứng dụng.Làm thế nào tôi có thể liên kết libc.a vào thư viện dùng chung trong arm-linux arm-none-linux-gnueabi-gcc

Trong liba.a, anh ấy ghi đè libc malloc() lên phiên bản chủ sở hữu của anh ấy.

Tôi tạo thư viện được chia sẻ libs.so cũng được liên kết với ứng dụng.

Vấn đề là khi libs.so của tôi liên kết với ứng dụng, malloc() được sử dụng trong libs.so của tôi sẽ là một trong liba.a, không phải là một trong libc.so chuẩn, điều này gây ra vấn đề.

Sau đó, tôi muốn liên kết tĩnh libc.a với libs.so của tôi, tôi đã sử dụng cờ -static -shared -fPIC cho gcc.

Nhưng tôi luôn nhận được arm-2012.03/bin /../ lib/gcc/arm-none-linux-gnueabi/4.6.3 /../../../../ arm-none-linux -gnueabi/bin/ld: arm-2012.03/bin /../ arm-none-linux-gnueabi/libc/usr/lib/libc.a (dl-tsd.o) (. văn bản + 0x14): R_ARM_TLS_LE32 di chuyển không được phép trong đối tượng được chia sẻ.

Có ai có ý tưởng về nó không?

Xin cảm ơn về phía trước.

+0

Tôi nghĩ rằng -static -share không nên được trộn lẫn ... – Jeyaram

+0

Văn bản sau đây được sao chép từ ld.pdf từ bộ mã vạch: "-static Không liên kết với các thư viện được chia sẻ. Điều này chỉ có ý nghĩa trên nền tảng mà đã chia sẻ ** Tùy chọn này có thể được sử dụng với 'chia sẻ' **. Làm như vậy có nghĩa là một thư viện được chia sẻ là đang được tạo nhưng tất cả các tham chiếu bên ngoài của thư viện phải được giải quyết bằng cách kéo các mục từ thư viện tĩnh . " –

+0

@DavidChyi: Điều đó chỉ nói -static và -shared có thể được trộn lẫn, nhưng không phải đó là một ý tưởng hay. Các trình biên dịch nói chung có nhiều tùy chọn không phải là một ý tưởng tốt để sử dụng cho các ứng dụng bình thường. Chúng rất quan trọng đối với các trường hợp đặc biệt như biên dịch kernel, bootloader, mã vi điều khiển và như vậy. –

Trả lời

2

Bạn không thể, vì mã nằm trong thư viện được chia sẻ phải được biên dịch với -fPIC và mã trong thư viện tĩnh thì không. Nếu bạn quản lý để làm điều đó, kết quả thực thi sẽ kết thúc liên kết với libc nhiều lần, mà sẽ được thực sự mong manh anyway và có thể sụp đổ sớm hay muộn, vì vậy bạn không nên làm điều đó anyway. Do đó:

Không. Thư viện động phải liên kết với các thư viện hệ thống động và mọi tệp thực thi liên kết với bất kỳ thư viện động nào cũng phải liên kết động thư viện hệ thống.

Tôi cũng muốn nhắc bạn rằng việc liên kết GNU libc với ứng dụng không phải GPL là bất hợp pháp, vì LGPL chỉ chấp nhận mã được liên kết động. Đây là mục đích để cho phép sửa lỗi thư viện mà không biên dịch lại tệp thực thi mà nguồn có thể không có sẵn. Nó khá phổ biến trong Linux để nâng cấp các thư viện được chia sẻ với phiên bản lỗi mà không cần biên dịch lại các tệp thực thi phụ thuộc; các nhà phát triển libc biết cách làm điều đó.

+0

@Hudec: Cảm ơn bạn đã gửi lời nhắc nhở. Đồng nghiệp của tôi đã thay đổi thư viện của anh ấy để sử dụng tiêu chuẩn malloc() trong libc.so. Nhưng chỉ vì tò mò, Tại sao ví dụ sau làm việc trong PC gcc, nhưng thất bại trong ARM gcc: $ cat libtest.c '#include void foo() {printf ("% d \ n ", 42); } ' $ cat chính.c '#include extern void foo(); int main() {puts ("Câu trả lời là:"); foo(); } ' ' gcc -shared -fPIC libtest.c -o libtest.so -static-libgcc -Wl, -Bstatic -lc && gcc -c main.c -o main.o && gcc main.o -o kiểm tra. /libtest.so && LD_PRELOAD =./libtest.so./test' ====> 42, đã hoạt động. –

+0

@Hudec: Tôi có thể tìm thông tin này ở đâu? _Không. Thư viện động phải liên kết với thư viện hệ thống động và mọi tệp thực thi liên kết với bất kỳ thư viện động nào cũng phải liên kết thư viện hệ thống động._ Và libc.a được sử dụng để làm gì? –

+0

@DavidChyi: Nó phụ thuộc vào những gì libc.a trên hệ thống cụ thể mà bạn đang thử nó trên thực sự chứa. Nó có thể hoạt động trên một cài đặt cụ thể và không hoạt động trên một cài đặt khác. Nhiều cài đặt thậm chí không cài đặt libc tĩnh. –

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