Liên kết tĩnh của chức năng thư viện chia sẻ trong gcc


137

Làm thế nào tôi có thể liên kết một chức năng thư viện chia sẻ tĩnh trong gcc?


13
Bạn có ý nghĩa gì bởi liên kết tĩnh? Bạn có muốn thực thi của bạn được phân phối mà không yêu cầu .so?
Emiliano

Câu trả lời:


108

Tham khảo:

http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-spl-lologists-696714/

http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2004-05/0436.html

Bạn cần phiên bản tĩnh của thư viện để liên kết nó.

Một thư viện chia sẻ thực sự là một tệp thực thi trong một định dạng đặc biệt với các điểm nhập được chỉ định (và một số vấn đề về địa chỉ dính kèm). Nó không có tất cả các thông tin cần thiết để liên kết tĩnh.

Bạn không thể liên kết tĩnh một thư viện dùng chung (hoặc tự động liên kết một thư viện tĩnh).

Cờ -staticsẽ buộc trình liên kết sử dụng các thư viện tĩnh (.a) thay vì các thư viện được chia sẻ (.so). Nhưng các thư viện tĩnh không phải lúc nào cũng được cài đặt theo mặc định, vì vậy bạn có thể phải tự cài đặt thư viện tĩnh.

Một cách tiếp cận khác có thể là sử dụng statifier hoặc Ermine . Cả hai công cụ đều lấy đầu vào là một thực thi được liên kết động và như đầu ra tạo ra một thực thi độc lập với tất cả các thư viện chia sẻ được nhúng.


11
Thư viện tĩnh có thông tin gì để có thể liên kết tĩnh mà thư viện động không có?
kbolino

75

Nếu bạn muốn liên kết, nói, libapplejuice tĩnh, nhưng không, nói, liborangejuice , bạn có thể liên kết như thế này:

gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary

Có một cảnh báo - nếu liborangejuicesử dụng libapplejuice, thì libapplejuicecũng sẽ được liên kết động.

Bạn sẽ phải liên kết liborangejuicetĩnh cùng với libapplejuiceđể có được libapplejuicetĩnh.

Và đừng quên giữ cho -Wl,-Bdynamicngười khác cuối cùng bạn sẽ liên kết mọi thứ tĩnh, bao gồm libc(đó không phải là điều nên làm).


2
Không có cách nào để nói với gcc trực tiếp những gì cần liên kết tĩnh, và không bỏ qua anh ta và nói chuyện với trình liên kết?
Elazar Leibovich

1
@ElazarLeibovich bạn không thể có được sự kết hợp giữa tĩnh và động theo cách đó.
Haozhun

@EugeneBujak: Thông báo trước không áp dụng trên hệ thống của tôi. Ví dụ: gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libB sử dụng libA , nó được liên kết và lddkhông hiển thị tham chiếu đến libA . Việc thực thi hoạt động tốt. Đã thử nghiệm với g ++ 4.7.3.
cơ số

Một sự phụ thuộc gián tiếp (lồng nhau), tĩnh, phụ thuộc của một sự phụ thuộc trực tiếp, năng động, không tự nó trở thành liên kết động.
Vinny

Hãy xem xét những điều sau: binA phụ thuộc vào libB.so, điều này phụ thuộc vào libC.a Như những người khác đã nêu, chính họ cũng có thể thực thi được, vì vậy khi một đối tượng chia sẻ được liên kết, mọi phụ thuộc thư viện tĩnh đều được xử lý bởi trình liên kết giống như khi một thực thi đã được liên kết: các biểu tượng duy nhất được kéo từ .a lib tĩnh là những biểu tượng được tham chiếu (và chưa được giải quyết) bởi .so. Điều này có nghĩa là nếu binA tham chiếu một biểu tượng trong libC.a, không được tham chiếu ở bất kỳ đâu trong libB.so, thì ngay cả khi binA liên kết với libB.so, biểu tượng đó sẽ không được xác định (trừ khi -Wl, - lưu trữ toàn bộ được sử dụng khi liên kết libB.so).
Vinny

18

Nếu bạn có tệp .a của thư viện dùng chung (.so), bạn có thể chỉ cần đưa nó vào đường dẫn đầy đủ của nó như thể đó là một tệp đối tượng, như thế này:

Điều này tạo ra main.o chỉ bằng cách biên dịch:

gcc -c main.c

Điều này liên kết tệp đối tượng với thư viện tĩnh tương ứng và tạo tệp thực thi (được đặt tên là "chính"):

gcc main.o mylibrary.a -o main

Hoặc trong một lệnh duy nhất:

gcc main.c mylibrary.a -o main

Nó cũng có thể là một con đường tuyệt đối hoặc tương đối:

gcc main.c /usr/local/mylibs/mylibrary.a -o main

12

Vâng, tôi biết đây là một câu hỏi 8 năm, nhưng tôi được cho biết rằng có thể liên kết tĩnh với thư viện đối tượng dùng chung và đây thực sự là mục tiêu hàng đầu khi tôi tìm kiếm thêm thông tin về nó.

Để thực sự chứng minh rằng không thể liên kết tĩnh thư viện đối tượng dùng chung với ld( gcctrình liên kết) - trái ngược với chỉ một nhóm người khăng khăng rằng không thể - sử dụng gcclệnh sau :

gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so

(Tất nhiên bạn sẽ phải biên dịch objectname.otừ sourcename.cvà có lẽ bạn cũng nên tạo thư viện đối tượng chia sẻ của riêng mình. Nếu bạn làm như vậy, hãy sử dụng -Wl,--library-path,.để ld có thể tìm thấy thư viện của bạn trong thư mục cục bộ.)

Lỗi thực tế bạn nhận được là:

/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status

Mong rằng sẽ giúp.


10

Hơi muộn một chút nhưng ... tôi đã tìm thấy một liên kết mà tôi đã lưu vài năm trước và tôi nghĩ nó có thể hữu ích cho các bạn:

CDE: Tự động tạo các ứng dụng Linux di động

http://www.pgbovine.net/cde.html

  • Chỉ cần tải chương trình
  • Thực hiện chuyển nhị phân dưới dạng đối số tên của nhị phân bạn muốn thực hiện, ví dụ: nmap

    ./cde_2011-08-15_64bit nmap

Chương trình sẽ đọc tất cả các lib được liên kết với nmap và các tệp phụ thuộc của nó và nó sẽ lưu tất cả chúng trong một thư mục có tên là cde-pack / (trong cùng thư mục mà bạn đang có).

  • Cuối cùng, bạn có thể nén thư mục và triển khai nhị phân di động trong bất kỳ hệ thống nào.

Hãy nhớ rằng, để khởi chạy chương trình di động, bạn phải thực hiện nhị phân nằm trong cde-pack / nmap.cde

Trân trọng


2
Trong khi không chính xác cung cấp câu trả lời cho câu hỏi - đó là một giải pháp đáng chú ý cho vấn đề.
razong

0

Trong gcc, điều này không được hỗ trợ. Trong thực tế, điều này không được hỗ trợ trong bất kỳ trình biên dịch / trình liên kết hiện có nào mà tôi biết.


4
Bạn có thể giải thích làm thế nào liên kết tĩnh không được hỗ trợ bởi bất kỳ trình biên dịch hiện có?
jww

5
@noloader, liên kết tĩnh của thư viện động?
nothrow
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.