2013-04-06 61 views
22

Tôi muốn bắt đầu bằng cách sử dụng liên kết đơn giản để giải thích vấn đề của tôi. Giả sử rằng có một thư viện z có thể được biên dịch thành thư viện libz.dll (D: /libs/z/shared/libz.dll) hoặc vào thư viện tĩnh libz.a (D:/libs/z/static/libz .a).Liên kết tĩnh và động/chia sẻ với MinGW

Lết Tôi muốn liên kết chống lại nó, sau đó tôi làm điều này:

gcc -o main.exe main.o -LD:/libs/z/static -lz 

Theo this documentation, gcc sẽ tìm kiếm libz.a, đó là

tập tin lưu trữ mà các thành viên là đối tượng tệp

Tôi cũng có thể làm như sau:

gcc -o main.exe main.o -LD:/libs/z/shared -lz 

Nó không được đề cập trong tài liệu ở trên mà -l cờ sẽ tìm kiếm lib<name>.so.

Điều gì sẽ xảy ra nếu tôi libz.a và libz.dll nằm trong cùng một thư mục? Thư viện sẽ được liên kết với một chương trình như thế nào? Tại sao tôi cần các cờ -Wl,-Bstatic-Wl,-Bdynamic nếu -l tìm kiếm cả thư viện được chia sẻ và tĩnh?

Tại sao một số nhà phát triển cung cấp tệp .a có tệp .dll cho cùng một mô-đun, nếu tôi biên soạn một bản phân phối thư viện được chia sẻ?

Ví dụ: Qt cung cấp tệp .dll trong thư mục bin có tệp .a trong thư mục lib. Nó có phải là cùng một thư viện, nhưng được xây dựng giống như chia sẻ và tĩnh, tương ứng? Hoặc các tệp .a là một số loại thư viện giả cung cấp liên kết với các thư viện được chia sẻ, nơi có các cài đặt thư viện thực?

Ví dụ khác là thư viện OpenGL trên Windows. Tại sao mọi trình biên dịch phải cung cấp lib OpenGL tĩnh như libopengl32.a trong MingW?

Các tệp có phần mở rộng .dll.a và .la được sử dụng để làm gì?

P.S. Có rất nhiều câu hỏi ở đây, nhưng tôi nghĩ mỗi người phụ thuộc vào câu hỏi trước và không cần chia chúng thành nhiều câu hỏi.

+0

Hãy lấy ví dụ Cygwin: đó là sự hiểu biết của tôi, rằng các chương trình được biên dịch với Cygwin cần một dll nhất định để chạy. Các dll là ràng buộc với một giấy phép nhất định (một trong những cái miễn phí) và phải có mặt trên hệ thống máy chủ cho chương trình. Nếu bạn là một nhà phát triển quên gửi nó cùng với chương trình, chương trình sẽ không chạy. Một ví dụ khác là phiên bản DLL xung đột (tức là opengl). mọi hệ thống đều có các khả năng khác nhau và do đó các triển khai khác nhau của một số DLL nhất định. Vì vậy, đôi khi các nhà phát triển muốn sử dụng đúng phiên bản thư viện => liên kết tĩnh. – scones

Trả lời

23

Vui lòng xem ld and WIN32 (cygwin/mingw). Đặc biệt, các liên kết trực tiếp đến một phần dll để biết thêm thông tin về hành vi của -l cờ trên các cổng Windows của LD. Extract:

Ví dụ, khi ld được gọi với đối số -lxxx nó sẽ cố gắng tìm kiếm, trong thư mục đầu tiên của con đường tìm kiếm của mình,

libxxx.dll.a 
xxx.dll.a 
libxxx.a 
cygxxx.dll (*) 
libxxx.dll 
xxx.dll 

trước khi chuyển sang thư mục tiếp theo trong đường dẫn tìm kiếm.

(*) Thực tế, đây không phải là cygxxx.dll nhưng trên thực tế là <prefix>xxx.dll, trong đó <prefix> được đặt theo tùy chọn ld -dll-search-prefix=<prefix>. Trong trường hợp Cygwin, tệp đặc tả gcc chuẩn bao gồm -dll-search-prefix=cyg, do đó, chúng tôi thực sự tìm kiếm cygxxx.dll.

LƯU Ý: Nếu bạn đã từng xây dựng Boost với MinGW, bạn có thể nhớ lại rằng việc đặt tên của các thư viện Boost chính xác tuân theo mô hình được mô tả trong các liên kết ở trên.

Trước đây đã xảy ra sự cố trong MinGW với liên kết trực tiếp tới *.dll, do đó, nên tạo một thư viện tĩnh lib*.a với các ký hiệu đã xuất từ ​​*.dll và liên kết với nó thay thế. Liên kết đến trang wiki MinGW này hiện đã chết, vì vậy tôi cho rằng sẽ ổn khi liên kết trực tiếp với *.dll ngay bây giờ. Hơn nữa, tôi đã tự làm nhiều lần với bản phân phối MinGW-w64 mới nhất và chưa có vấn đề gì.

Bạn cần cờ liên kết -Wl,-Bstatic-Wl,-Bdynamic vì đôi khi bạn muốn để buộc liên kết tĩnh, ví dụ, khi thư viện năng động cùng tên cũng có mặt trong một đường dẫn tìm kiếm:

gcc object1.o object2.o -lMyLib2 -Wl,-Bstatic -lMyLib1 -Wl,-Bdynamic -o output 

Các đảm bảo đoạn trên rằng ưu tiên liên kết mặc định của cờ -l bị ghi đè cho MyLib1, tức là ngay cả khi MyLib1.dll có mặt trong đường dẫn tìm kiếm, LD sẽ chọn libMyLib1.a để liên kết ngược lại. Lưu ý rằng đối với MyLib2 LD sẽ lại thích phiên bản động.

LƯU Ý: Nếu MyLib2 phụ thuộc vào MyLib1, sau đó MyLib1 được liên kết động quá, bất kể -Wl,-Bstatic (tức là nó bị bỏ qua trong trường hợp này). Để ngăn chặn điều này, bạn sẽ phải liên kết MyLib2 tĩnh quá.

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