2013-04-04 45 views
7

Có cách nào (trong Linux) để xác định thư viện nào tôi phải liên kết với chương trình C/C++ không? Tôi không muốn bỏ lỡ một thư viện, ngay cả trong các tình huống khi các ký hiệu không xác định sẽ không được phát hiện khi bắt đầu chương trình. Ngoài ra, tôi muốn tránh những phụ thuộc không cần thiết của khóa học.Làm cách nào để biết thư viện nào liên kết?

Tôi đã xây dựng câu hỏi này nói chung, nhưng đây là một ví dụ cụ thể, không đặc biệt: Cho đến gần đây, tôi nghĩ rằng tôi cần liên kết với libpython cho các mô-đun Python được phát triển với Boost.Python. Tuy nhiên, điều này không đúng: Viết một mô-đun với Boost.Python; nó thậm chí có thể sử dụng các hàm từ API C C, không chỉ Boost.Python. Liên kết với libboost_python là đủ! Điều này là không rõ ràng ở tất cả-tôi đã không tìm thấy nó tài liệu, ít nhất, và có Boost.Python mô-đun xung quanh mà không cần thiết liên kết với libpython. Ngoài ra, điều này khó phát hiện vì libboost_python.so không liệt kê libpython là phụ thuộc theo báo cáo của ldd. (Tôi tin rằng thư viện Python được nạp động trong trường hợp này.)

[Đã thêm sau: Điều này độc lập với Boost.Python. Ngoài ra, nếu sử dụng API C C cấp thấp, mô-đun Python có thể được biên dịch và không được liên kết với libpython và nó sẽ hoạt động. Tuy nhiên, hãy xem các nhận xét và câu trả lời bên dưới nói rằng bạn nên liên kết với libpython.]

Vì vậy, làm cách nào để tìm ra liên kết không cần thiết một cách có hệ thống thay vì dùng thử và lỗi? Thủ tục chung tốt, không chỉ cho ví dụ này là gì?

[Đã thêm sau: Đây là những gì tôi đã học được từ các nhận xét cho câu hỏi của mình. Các sự kiện dưới đây không rõ ràng với tôi khi tôi đăng câu hỏi này, vì vậy tôi đánh vần chúng ngay bây giờ, vì lợi ích của những người ghé thăm cuộc thảo luận này trong tương lai, và ngay cả khi những điều này là hiển nhiên đối với những người bình luận hữu ích. (Cảm ơn!)

Biểu tượng giải quyết hoạt động theo cách chuyển tiếp trong Linux (như được chỉ ra bởi người dùng MvG và millimoose). Giả sử chương trình A cần phải giải quyết các biểu tượng từ libBlibC. Giả sử thêm rằng A được liên kết với libBlibB được liên kết với libC. Sau đó, A có thể được tải và thực thi ngay cả khi nó không trực tiếp tham chiếu đến libC.

Tuy nhiên, thực tiễn không tốt là dựa vào sự chuyển đổi này, như các nhà bình luận đã chỉ ra. Trong trường hợp các mô-đun Python được viết bằng C/C++, điều này có nghĩa là một mô-đun nên liên kết với libpython. Đối với trường hợp chung, mục tiêu phải là không phải là là để xác định danh sách thư viện tối thiểu cần thiết để liên kết và thực hiện — như câu hỏi orignal của tôi bằng cách nào đó được nêu ra. đã giải quyết trực tiếp trực tiếp.

Tóm tắt câu trả lời của Salgar, thông tin này thường chỉ có thể thu được từ tài liệu của thư viện được sử dụng.Ngoài ra, cờ liên kết GCC -Wl,--as-needed rất hữu ích để xác định các thư viện thực sự không cần thiết.]

+0

Nếu không cần thiết, chi phí liên kết sẽ mất một thời gian để tìm ra điều đó, nhưng sau đó nó sẽ xóa nó khỏi danh sách phụ thuộc, giống như bạn đã không vượt qua nó. –

+0

@Ben: I don ' Tôi nghĩ vậy. Trong ví dụ của tôi, nếu tôi chuyển '-lpythonX.Y' làm cờ trình biên dịch, thì * libpythonX.Y.so * xuất hiện trong đầu ra' ldd', ngay cả khi module hoạt động tốt mà không có sự phụ thuộc * libpython *. – Daniel

+0

Ngoài ra, hãy thử một thư viện ngẫu nhiên (bất cứ thứ gì từ thư mục '/ usr/lib' của bạn). Nếu bạn liên kết với nó, nó sẽ hiển thị trong đầu ra 'ldd', ngay cả khi nó không được sử dụng. – Daniel

Trả lời

4

Không có cách nào để biết các thư viện cần bao gồm, giống như không có cách nào để biết được các tiêu đề cần đưa vào.

Có thể có 10 thư viện khác nhau, tất cả đều có chức năng có cùng tên, tất cả đều làm những việc hoàn toàn khác nhau. Tùy thuộc vào bạn quyết định cái nào bạn muốn sử dụng.

Nói chung không phải như vậy, nhưng nó phục vụ một điểm trình diễn.

Thông thường nếu bạn đang sử dụng thư viện tăng hoặc thư viện tương tự khác, tài liệu này sẽ cho bạn biết bạn cần liên kết với lib nào.

Là người đã nói ở trên, bạn có thể bao gồm quá mức và sử dụng cờ - rất cần thiết, nhưng nhiều người gặp sự cố, như thường khi bạn liên kết với thư viện, nó được kéo vào lúc khởi động và toàn cầu các biến từ thư viện đó được khởi tạo. Cho dù bạn cần những biến toàn cầu hay không có thể là một điều khó hiểu cho mối liên kết để làm việc ra ngoài.

Tóm lại, câu trả lời thường là đọc tài liệu. Hoặc để biên dịch mã và xem lỗi liên kết nào bạn nhận được, và sau đó làm việc từ đó để tìm ra thư viện nào bạn cần.

+0

các trình khởi tạo toàn cầu từ các thư viện tĩnh có thể bị loại bỏ, do đó việc xử lý cùng một vấn đề và thư viện động không nên khó thực hiện. –

0

Không có bất kỳ/tầm thường/cách nào, nhưng bạn có thể làm cho nó dễ dàng hơn rất nhiều trên chính mình bằng cách sử dụng một công cụ quản lý xây dựng như CMake hoặc AutoConf.

0

Khi bạn xây dựng Boost, bạn có tùy chọn xây dựng các phiên bản tĩnh hoặc động của các lib được biên dịch. Nó đã được một thời gian kể từ khi tôi đã xây dựng tăng, nhưng nếu tôi nhớ lại nó xây dựng cả hai hương vị nếu bạn chỉ cần làm việc xây dựng dễ dàng.

này được bao phủ trong:

Đối với những Boost.Python, tùy chọn giữa tĩnh hoặc động thư viện liên kết được ghi lại ở đây:

Thư viện năng động là sự lựa chọn an toàn nhất và nhiều nhất linh hoạt:

  • Một bản duy nhất của mã thư viện được sử dụng bởi tất cả các module mở rộng được xây dựng với một trao toolset.3 Thư viện chứa một loại chuyển đổi registry. Bởi vì một đăng ký được chia sẻ giữa tất cả các mô-đun mở rộng, trường hợp của một lớp tiếp xúc với Python trong một mô-đun mở rộng được nạp động có thể được chuyển đến các hàm được phơi bày trong mô-đun như vậy.

Có thể thích hợp để sử dụng Boost tĩnh.thư viện Python trong bất kỳ trong các trường hợp sau đây:

  • Bạn đang extending trăn và các loại tiếp xúc trong mô-đun mở rộng tự động tải của bạn không cần phải được sử dụng bởi bất kỳ module mở rộng Boost.Python khác, và bạn không quan tâm nếu thư viện lõi mã được sao chép trong số đó.

  • Bạn đang nhúng python trong ứng dụng của bạn và một trong hai:

    • Bạn đang nhắm mục tiêu một biến thể Unix hệ điều hành khác hơn hệ điều hành MacOS hoặc AIX, nơi các module mở rộng tự động nạp có thể “nhìn thấy” Boost. Python ký hiệu thư viện là một phần của tệp thực thi.

    • Hoặc, bạn đã liên kết tĩnh một số module mở rộng Boost.Python vào ứng dụng của bạn và bạn không quan tâm nếu có động nạp Boost.Python module mở rộng có thể sử dụng các loại tiếp xúc bởi statically- của bạn mô-đun mở rộng được liên kết (và ngược lại).

Vì vậy, cấp, điều này không giải thích làm thế nào bạn biết những gì để liên kết chống lại trong một cảm giác chung. Chỉ một tình huống cụ thể.

Tôi nghĩ sự nhầm lẫn về cách boost.python hoạt động và những trải nghiệm khác nhau mà mọi người đang nhận xét liên quan đến liên kết có thể có ý nghĩa hơn một chút khi bạn xem qua ống kính này ít nhất.

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