2010-02-03 13 views
9

tiêu đề của câu hỏi này là exact dupe, nhưng câu trả lời trong câu hỏi đó không giúp tôi.Chuyển đổi Thư viện tĩnh thành Thư viện được chia sẻ (tạo libsome.so từ libsome.a): biểu tượng của tôi ở đâu?

tôi có một loạt các file đối tượng đóng gói trong một thư viện tĩnh:

% g++ -std=c++98 -fpic -g -O1 -c -o foo.o foo.cpp 
% g++ -std=c++98 -fpic -g -O1 -c -o bar.o bar.cpp 
% ar -rc libsome.a foo.o bar.o 

Tôi muốn tạo libsome.so từ libsome.a thay vì các tập tin đối tượng, nhưng thư viện là thực sự barebones:

% g++ -std=c++98 -fpic -g -O1 -shared -o libsome.so libsome.a 
% nm -DC libsome.so 
0000xxxx A _DYNAMIC 
0000xxxx A _GLOBAL_OFFSET_TABLE_ 
     w _Jv_RegisterClasses 
0000xxxx A __bss_start 
     w __cxa_finalize 
0000xxxx A _edata 
0000xxxx A _end 
0000xxxx T _fini 
0000xxxx T _init 

thư viện tĩnh là ok, hoặc ít nhất tôi hoàn toàn có thể liên kết nó với tệp thực thi và chạy chức năng chứa. Ngoài ra, mọi thứ đều ổn nếu tôi tạo libsome.so từ foo.o và bar.o.

Trả lời

22

Giả sử bạn đang sử dụng trình liên kết GNU, bạn cần chỉ định tùy chọn --whole-archive để bạn nhận được tất cả nội dung của tệp lưu trữ tĩnh. Kể từ đó là một lựa chọn mối liên kết, bạn sẽ cần -Wl nói với gcc để vượt qua nó thông qua các mối liên kết:

g++ -std=c++98 -fpic -g -O1 -shared -o libsome.so -Wl,--whole-archive libsome.a 

Nếu bạn đang làm một cái gì đó phức tạp hơn nơi bạn muốn tất cả các thư viện số nhưng chỉ có một phần của thư viện hỗ trợ cần thiết cho libsome, bạn sẽ muốn tắt toàn bộ kho lưu trữ sau khi bạn đã sử dụng nó trên libsome:

... -Wl,--whole-archive libsome.a -Wl,--no-whole-archive libsupport.a 

Nếu bạn không sử dụng các mối liên kết GNU, bạn sẽ cần phải xem nếu mối liên kết của bạn hỗ trợ nó và nó được gọi là gì. Trên trình liên kết Sun, nó được gọi là -z allextract-z defaultextract.

+0

+1 Có bạn đi. Tôi đã thử "người đàn ông ld" và bỏ lỡ điều đó. –

+0

cảm ơn, đây là nó! Tôi đã tìm kiếm manpage ld lên và xuống, nhưng bằng cách nào đó đã bỏ lỡ tùy chọn này. –

+0

Bây giờ nếu chỉ có câu trả lời tuyệt vời này là cũng chỉ ra cách thiết lập điều này với một dự án CMake! Cảm ơn –

1

Tệp của bạn không bị kéo vào tệp .a vì không có gì đề cập đến chúng. Tại sao bạn tạo tệp .a trước? Bạn sẽ có may mắn hơn khi tạo một tệp .o bằng cách liên kết chúng với tùy chọn -r.

+0

khi tôi xây dựng libsome.so từ foo.o và bar.o, không có gì là tham chiếu đến các biểu tượng, nhưng chúng sẽ kết thúc trong thư viện. và vì tệp '.a' chỉ là hai tệp' .o' chính xác được tát cùng nhau, nên * nên * là một cách đơn giản để sử dụng nó thay cho các tệp đối tượng chứa, không? –

+0

Vì tệp đối tượng được lấy ra khỏi tệp .a chỉ khi một biểu tượng trong chúng được tham chiếu. Tệp .o luôn được liên kết trong, được tham chiếu hay không. –

+0

ok, bỏ qua các chi tiết cụ thể về tình huống của tôi: có hoặc không có cách nào để chuyển đổi một thư viện tĩnh sang một thư viện chia sẻ * như thể * các tệp '.o' đã được sử dụng? (chiết khấu 'ar -x') –