2013-04-27 25 views
5

Tôi đang cố gắng liên kết chương trình của tôi tĩnh với glibc, vì phiên bản glibc trên máy đích là khá khó lường. Tôi đã sử dụng cờ linker -static-libgcc và -static-libstdC++ và nó hoạt động tốt. Việc thực thi là lớn, nhưng tôi có thể sống với nó. Thật không may, khi tôi chạy thực thi của tôi trên máy mục tiêu (nó được đặt tên là 'mytest' trong ví dụ dưới đây) tôi nhận được lỗi sau:Chương trình không thể tìm thấy phiên bản chính xác của glibc/libstdC++, mặc dù nó đã được liên kết tĩnh

./mytest: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by libboost_log.so.1.53.0) 
./mytest: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by libboost_log.so.1.53.0) 
./mytest: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by libboost_log.so.1.53.0) 
./mytest: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by libboost_date_time.so.1.53.0) 
./mytest: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by libboost_thread.so.1.53.0) 

Nếu tôi làm 'chuỗi' trên mytest, nó mang lại cho tôi

$ strings mytest | grep GLIBC 
GLIBC_2.9 
GLIBC_2.7 
GLIBC_2.8 
GLIBC_2.3.2 
GLIBC_2.2.5 
GLIBCXX_3.4.15 
GLIBCXX_3.4.11 
GLIBCXX_3.4.14 
GLIBCXX_3.4.9 
GLIBCXX_3.4 

Điều gì có nghĩa là, tôi nghĩ rằng liên kết tĩnh đang hoạt động tốt. Tại sao bộ nạp vẫn cố gắng tìm các hàm của tôi trong glibc và libstdC++ được chia sẻ? Tôi đang làm gì sai?

Cảm ơn!

Trả lời

5

I am trying to link my program statically with glibc, because version of the glibc on the target machine is pretty much unpredictable. I used linker flags -static-libgcc and -static-libstdc++ and it worked fine.

Đó không ảnh hưởng đến phiên bản của glibc (libc), đó là khác nhau từ libgcclibstdc++. Với những cờ này, bạn vẫn tạo ra tệp thi hành được liên kết động, được mong đợi để không hoạt động trên một bản phân phối cũ hơn.

Bạn có thể liên kết tệp thi hành của mình với cờ -static và điều đó sẽ cung cấp cho bạn hoàn toàn thực thi tĩnh.

Cập nhật:

Sau khi đọc câu hỏi của bạn; vấn đề của bạn là không phải với glibc. Vấn đề của bạn là bạn đang liên kết với libboost_log.so, chính nó phụ thuộc vào libstdc++.so.6.

Câu trả lời là liên kết với libboost*.a thay vì libboost*.so. Bạn có thể cố gắng để đạt được điều đó theo cách này:

g++ $(OBJS) -static-libgcc -static-libstdc++ -Wl,-Bstatic -lboost_log ... \ 
    -Wl,-Bdynamic 

(Đó là rất quan trọng để có trailing -Wl,-Bdynamic.)

+0

Rất cám ơn. Thật không may, tôi không thể liên kết tất cả mọi thứ tĩnh, bởi vì sau đó thư viện pthread của tôi không hoạt động. Vì lý do gì, nó chỉ hoạt động nếu nó được liên kết động. – svetlana

+0

@svetlana 'libpthread' là một phần của glibc.Nếu bạn không thể liên kết nó tĩnh, thì bạn không thể có một tệp thực thi hoàn toàn tĩnh và điều đó ngụ ý rằng tệp thực thi của bạn sẽ * không bao giờ * hoạt động trên một hệ thống cũ hơn (điều đó không được hỗ trợ). Liên kết tĩnh * không * làm việc cho các chương trình đa luồng nói chung, vì vậy bạn cần phải tìm ra lý do tại sao nó không hoạt động cho trường hợp cụ thể của bạn, hoặc từ bỏ toàn bộ ý tưởng. –

+0

@svetlana Đã cập nhật câu trả lời. –

1

Liên kết với -static-libgcc-static-libstdc++ sẽ chỉ hoạt động đối với những thư viện đó. Dường như bạn cũng đang liên kết với các thư viện tăng (có khả năng động) mà sau đó liên kết với libgcc và libstdC++.

Thử chạy như sau:

ldd mytest 

Nó sẽ hiển thị "không phải là một động thực thi". Nếu nó cho thấy bất cứ điều gì khác, nó có nghĩa là nó được liên kết động với các thư viện khác. Nó không phải lúc nào cũng hoạt động dễ dàng như vậy, nhưng hãy thử thêm -static vào dòng biên dịch để quản lý các thư viện còn lại.

+0

Alec, nó cho thấy 'không phải là một động thực thi'. Tôi cảm thấy tràn ngập và tràn ngập ... – svetlana

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