Hãy xem xét kịch bản sau đây:Liên kết với thư viện năng động với phụ thuộc
- Shared Library libA.so, không phụ thuộc.
- Thư viện được chia sẻ libB.so, với libA.so là sự phụ thuộc của nó.
Tôi muốn biên dịch tệp nhị phân có liên kết với libB. Tôi có nên liên kết nhị phân với libB chỉ hoặc với libA không?
Có cách nào để liên kết chỉ với các phụ thuộc trực tiếp, cho phép giải quyết các biểu tượng chưa được giải quyết khỏi các phụ thuộc trong thời gian chạy không?
Tôi lo lắng về việc thực thi thư viện libB có thể thay đổi trong tương lai, giới thiệu các phụ thuộc khác (ví dụ: libC, libD, libE). Tôi sẽ có vấn đề với điều đó?
Nói cách khác:
- Liba file: a.cpp ah
- file libB: b.cpp bh
- file chương trình chính: main.cpp
Tất nhiên, b.cpp bao gồm ah và main.cpp bao gồm bh
lệnh Compilation:
g++ -fPIC a.cpp -c
g++ -shared -o libA.so a.o
g++ -fPIC b.cpp -c -I.
g++ -shared -o libB.so b.o -L. -lA
nào trong các tùy chọn dưới đây tôi nên sử dụng?
g++ main.cpp -o main -I. -L. -lB
hoặc
g++ main.cpp -o main -I. -L. -lB -lA
tôi không thể sử dụng tùy chọn đầu tiên. Trình liên kết phàn nàn về các ký hiệu chưa được giải quyết từ thư viện libA. Nhưng nó hơi lạ với tôi.
Cảm ơn rất nhiều.
- bình luận Cập nhật:
Khi tôi liên kết nhị phân, các mối liên kết sẽ cố gắng giải quyết tất cả các biểu tượng từ chính và libB. Tuy nhiên, libB có các ký hiệu không xác định từ libA. Đó là lý do tại sao người liên kết phàn nàn về điều đó.
Đó là lý do tại sao tôi cũng cần phải liên kết với libA. Tuy nhiên tôi tìm thấy một cách để bỏ qua các biểu tượng chưa được giải quyết từ các thư viện được chia sẻ. Hình như tôi nên sử dụng dòng lệnh sau đây để làm điều đó:
g++ main.cpp -o main -I. -L. -lB -Wl,-unresolved-symbols=ignore-in-shared-libs
Hình như nó vẫn còn có thể sử dụng tùy chọn -rpath
. Tuy nhiên tôi cần phải hiểu nó tốt hơn một chút.
Có ai biết bất kỳ cạm bẫy nào có thể xảy ra khi sử dụng tùy chọn -Wl,-unresolved-symbols=ignore-in-shared-libs
không?
- bình luận Cập nhật 2:
-rpath
không nên được sử dụng cho mục đích này. Nó rất hữu ích để buộc một thư viện được tìm thấy trong một thư mục nhất định. Cách tiếp cận -unresolved-symbol
trông đẹp hơn nhiều.
Xin cảm ơn một lần nữa.
Tôi biết đã lâu rồi, tôi quên đánh dấu nó là đã được giải quyết. Cảm ơn rất nhiều câu trả lời của bạn.] – Marcus
Cảm ơn các bạn vì câu hỏi tuyệt vời và câu trả lời hợp lý! Tôi đã gần như chính xác cùng một kịch bản. Tôi đang cố gắng để bọc các đối tượng chia sẻ openCV trong một đối tượng được chia sẻ tùy chỉnh. cho phép nói C.so là tùy chỉnh của tôi như vậy, và CV.so là một số openCV như vậy. Tôi đã liên kết thành công C.so chống lại CV.so, và tôi muốn liên kết một main.cpp (bạn nhận được nó!) Chống lại C.so, nhưng điều này ngoài việc sử dụng các đối tượng từ C.so, main.cpp sử dụng một đối tượng 'cv :: Mat' được định nghĩa trong CV.so .. Trong trường hợp này cho main.cpp để chạy, tôi có cần phải liên kết với cả C.so và CV.so ?? Tôi rất thích nó nếu ai đó làm sáng tỏ điều này. Cảm ơn bạn! :) –
Tại sao trình liên kết không giải quyết tất cả các ký hiệu libA.so bắt buộc khi tạo libB.so? Ứng dụng chính không được liên kết đến libA vì nó phải trong suốt, ví dụ: gián tiếp bảo vệ bởi libB? – Wilson