2009-04-07 35 views

Trả lời

85

Tham khảo:

http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-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.

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

Bạn có thể không tĩnh liên kết thư viện chia sẻ (hoặc tự động liên kết tĩnh)

Cờ -static sẽ buộc mối liên kết để sử dụng thư viện tĩnh (.a) thay vì chia sẻ (.so) Nhưng. Thư viện tĩnh không luôn được cài đặt theo mặc định. Vì vậy, nếu bạn cần liên kết tĩnh, bạn phải cài đặt các 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ụ này lấy làm đầu vào liên kết động thực thi và khi đầu ra tạo ra tệp thực thi khép kín với tất cả các thư viện được chia sẻ được nhúng.

+6

Bí quyết tuyệt vời với statifier hoặc Ermine. – jww

+2

1+ cho '' Cờ -static sẽ buộc trình liên kết sử dụng thư viện tĩnh (.a) thay vì chia sẻ (.so) '' – tod

0

Trong gcc, tính năng 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 cách 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ó nào không? – jww

+3

@noloader, liên kết tĩnh của thư viện động? – nothrow

70

Nếu bạn muốn liên kết, chẳng hạn, libapplejuice tĩnh, nhưng không phải, 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 caveat - nếu liborangejuice sử dụng libapplejuice, sau đó libapplejuice cũng sẽ được liên kết động.

Bạn sẽ phải liên kết liborangejuice tĩnh cùng với libapplejuice để nhận libapplejuice tĩnh.

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

+2

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

+1

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

+0

@EugeneBujak: _caveat_ 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ó liên kết và 'ldd' khô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. – radix

18

Nếu bạn có file .a của thư viện chia sẻ của bạn (.so) bạn chỉ có thể bao gồm nó với đường dẫn đầy đủ của nó như thể nó là một tập tin đối tượng, như thế này:

này tạo chính.o bằng cách chỉ cần soạn:

gcc -c main.c 

này liên kết mà đối tượng tập tin với các thư viện tĩnh tương ứng và tạo ra thực thi (có 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à đường dẫn tuyệt đối hoặc tương đối:

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

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

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

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

  • Chỉ cần tải chương trình
  • Execute việc thông qua nhị phân như một đối số tên của nhị phân bạn muốn làm cho di động, ví dụ: nmap

    ./cde_2011-08-15_64bit nmap

Chương trình sẽ đọc tất cả các libs liên quan đến nmap và 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 CDE-gói/ (trong cùng một 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.

nhớ rằng, để khởi động chương trình portable bạn phải exec nhị phân nằm ở CDE-gói/nmap.cde

Trân trọng

+0

Mặc dù không cung cấp chính xác câu trả lời cho câu hỏi - một giải pháp đáng chú ý cho vấn đề này. – razong

2

Yeah, tôi biết đây là một 8 năm- câu hỏi cũ, nhưng tôi đã nói rằng nó có thể liên kết tĩnh với một thư viện đối tượng được chia sẻ và đây thực sự là hit 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 liên kết tĩnh một thư viện chia sẻ đối tượng là không thể với ld (linker gcc 's) - như trái ngược với chỉ một bó của những người khẳng định rằng nó không thể - sử dụng gcc lệnh sau:

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

(Tất nhiên bạn sẽ cần phải biên dịch objectname.o từ sourcename.c, và có lẽ bạn nên tạo nên thư viện chia sẻ đối tượng của riêng bạn là tốt. Nếu bạn làm, 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ộ.)

Các 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 

Hy vọng rằng sẽ giúp.

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