2010-05-11 43 views
6

Tôi đã có một thư viện chia sẻ với một số chức năng tự chế, mà tôi biên dịch vào các chương trình khác của mình, nhưng tôi phải liên kết chương trình kết thúc với tất cả các thư viện mà tôi đã sử dụng để biên dịch thư viện tĩnh. Dưới đây là ví dụ:Biên dịch một thư viện chia sẻ tĩnh

Tôi có chức năng foo trong thư viện yêu cầu chức năng từ thư viện khác libbar.so.

Trong chương trình chính của tôi để sử dụng chức năng foo Tôi phải biên dịch nó với cờ -lbar. Có cách nào tôi có thể biên dịch thư viện tĩnh của tôi để nó bao gồm tất cả mã bắt buộc từ các thư viện khác và tôi có thể biên dịch chương trình kết thúc của mình mà không cần cờ -lbar không?

+0

Ông có thể nói rõ những nền tảng được sử dụng? Lý tưởng nhất, họ sẽ có trong các thẻ. –

+0

chạy trên linux –

+0

Ghi chú bên; không chỉ bạn sẽ không phải -bar, nhưng một khi bạn bắt đầu, linker của bạn sẽ thả tất cả các biểu tượng * mã * của bạn không tham chiếu (trực tiếp hoặc gián tiếp xuống qua chuỗi cuộc gọi của bạn). Điều này sẽ thu nhỏ tệp thực thi của bạn và giúp ứng dụng của bạn khởi động nhanh hơn! – Armentage

Trả lời

5

Các đối tượng được chia sẻ (.so) không phải là các thư viện, chúng là các đối tượng. Bạn không thể trích xuất một phần của chúng và chèn nó vào các thư viện khác.

Bạn có thể làm gì nếu xây dựng một đối tượng được chia sẻ tham chiếu đến đối tượng kia - nhưng đối tượng khác sẽ cần thiết vào thời gian chạy. Chỉ cần thêm các -bar khi liên kết libfoo.

Nếu bạn có thể xây dựng libbar, bạn rõ ràng có thể tạo một thư viện là sự kết hợp giữa libfoo và libbar. IIRC, bạn cũng có thể làm cho trình liên kết xây dựng một thư viện là libfoo và phần cần thiết của libbar bằng cách liên kết a .a với .o có nghĩa là đi trong libbar. Ví dụ:

gcc -fPIC -c lib1.c  # define foofn(), reference barfn1() 
gcc -fPIC -c lib2a.c # define barfn1(), reference barfn2() 
gcc -fPIC -c lib2b.c # define barfn2() 
gcc -fPIC -c lib2c.c # define barfn3() 
gcc -c main.c   # reference foofn() 
ar -cru libbar.a lib2*.o 
gcc -shared -o libfoo.so lib1.o -L. -lbar 
nm libfoo.so | grep barfn2() # ok, not here 
gcc -o prog main.o -L. -lfoo 
env LD_LIBRARY_PATH=. ./prog # works, so foofn(), barfn1() and barfn2() are found 
3

Bước 1 (Tạo tập tin đối tượng):

gcc -c your.c -o your.o 

Bước 2 (Tạo thư viện tĩnh):

ar rcs libyour.a your.o 

Bước 3 (Link chống lại thư viện tĩnh):

gcc -static main.c -L. -lyour -o statically_linked 
1

Về cơ bản, nếu bạn có liên kết tĩnh trong thư viện hệ thống mà thư viện tĩnh của bạn phụ thuộc, bạn có thể liên kết tĩnh với tất cả mã từ thư viện đó.

Tôi không chắc chắn lý do tại sao. * Việc xử lý các thư viện chia sẻ của nền tảng NIX là một công việc của thiên tài và cắt giảm nghiêm trọng kích thước chương trình đã biên dịch. Nếu bạn lo lắng về việc không thể chạy mã trên một máy tính khác do thiếu thư viện, thì bạn luôn có thể lấy đường dẫn của hầu hết các chương trình mã nguồn đóng được biên dịch cho thư viện Linux: chỉ biên dịch chúng với các tùy chọn -Wl,--rpath -Wl,. tới GCC và phân phối thư viện cùng với nhị phân.

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