2009-11-07 13 views
16

Tôi đã cố gắng liên kết tĩnh với thư viện C++ được gọi là Poco trên Windows bằng cách sử dụng các công cụ dòng lệnh của Visual Studio 2008.Cách liên kết tĩnh bằng cách sử dụng link.exe

tôi xây dựng chương trình của tôi với:

cl /I..\poco\lib /c myapp.cpp 
link /libpath:..\poco\lib myapp.obj PocoNet.lib 

Điều này dẫn đến một exe mà khi chạy đòi hỏi PocoNet.dll và PocoFoundation.dll.

Tôi đã dành một chút thời gian để đọc liên kết trong Windows và biết rằng liên kết tĩnh với thư viện chuẩn là cl /MT, trong khi cl /MD liên kết động.

Tôi đã cố gắng chỉ định /MT, nhưng điều đó dường như không thay đổi bất cứ điều gì; ứng dụng của tôi vẫn yêu cầu tệp Poco DLL. (Tôi cũng nghi ngờ rằng /MT là hành vi mặc định.)

Nhìn dưới ..\poco\lib, tôi tìm thấy ở đó cũng là một PocoNetmt.lib, nhưng chỉ định rằng thay vì PocoNet.lib dẫn đến một loạt các lỗi LNK2005 ("đã được xác định"):

msvcprt.lib(MSVCP90.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" ([email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]) already defined in exp.obj 

sau đó tôi đã cố gắng xếp chồng trên nhiều cờ:

Tôi cũng thử một số các kết hợp ở trên, tất cả đều không có kết quả.

Mọi manh mối sẽ được đánh giá cao. Nhưng cũng hữu ích như bất kỳ con trỏ nào đến các tài nguyên hữu ích để gỡ rối (hoặc tìm hiểu) các loại vấn đề này.

Trả lời

15

Bạn phải xác định POCO_STATIC trên dòng lệnh và liên kết với cả hai PocoFoundationmt và PocoNetmt.lib:

C: \ test> cl/MD/WX/nologo/EHsc/DPOCO_STATIC/DUNICODE/D_UNICODE/I. . \ poco \ Quỹ \ include/I .. \ poco \ Net \ include/c exp.cpp

exp.cpp

C: \ test> liên kết /libpath:..\poco\lib/WX/nologo exp.obj PocoNetmt.lib PocoFoundationmt.lib

[UPDATE] Nếu bạn biên dịch wi Th/DPOCO_STATIC, sau đó không cần thiết phải chỉ định các thư viện POCO trên dòng lệnh của trình liên kết. Các tệp tiêu đề chứa các câu lệnh #pragma comment (lib, "PocoXXXmt.lib") phải đảm bảo rằng tất cả các thư viện cần thiết sẽ được liên kết.

Nếu bạn không biên dịch với/DPOCO_STATIC, thì thư viện nhập DLL sẽ được tự động liên kết thay thế. [/ UPDATE]

+2

Cảm ơn. POCO_STATIC là chìa khóa. Tôi rất khuyên bạn làm cho câu chú giải tối nghĩa này nổi bật hơn ở đâu đó trong tài liệu cấp cao và README. Khi Googling cho POCO_STATIC, các tham chiếu duy nhất cho nó nằm trong các bài đăng trên blog. – Yang

5

Có vẻ như vấn đề là tệp PocoNet.lib là thư viện nhập cho poco.dll. Vì vậy, các externs nó giải quyết là DLL.

Bạn sẽ cần phải tìm hoặc xây dựng một thư viện tĩnh cho Poco (nếu có thể).

+0

Nhưng làm cách nào để xác minh điều này? Tôi đã đề cập rằng cuối cùng tôi đã tìm thấy và chuyển sang một 'PocoNetmt.lib'; đó là những gì bắt đầu cho tôi lỗi liên kết. (Hệ thống xây dựng Poco theo mặc định sẽ tạo ra cả các thư mục lib được chia sẻ và tĩnh.) – Yang

0

Bạn sẽ cần/MT trên mã của bạn và tất cả các phụ thuộc của nó để liên kết tĩnh với thời gian chạy MSVC (MSVCP90.dll/MSVCR90.dll).

Đó là vì PocoNetmt.lib có vẻ được xây dựng với/MT.

Nếu với/MT bạn vẫn nhận được msvcprt.lib, bật/tiết và tìm hiểu thư viện nào khác kéo nó. Sau đó biên dịch/tìm tĩnh xây dựng đó.

Một tùy chọn khác là tìm static PocoNet lib được xây dựng bằng/MD (để bạn liên kết tĩnh với nó, nhưng tự động chạy) và chuyển mọi thứ sang/MD.

EDIT: Khi Poco dll được liên kết với/MT không ảnh hưởng đến bạn. Nhưng vì bạn muốn loại bỏ nó, bạn (và tất cả các phụ thuộc khác của bạn) sẽ phải sử dụng cùng một cờ/MT.

+0

CAPCHA: analy worthier. Go figure ... – Eugene

+0

Tôi vừa nhận được một phản hồi từ danh sách gửi thư của Poco cho tôi biết rằng, trong khi PocoNetmt.lib thực sự là liên kết tĩnh, bản thân Poco libs đều được xây dựng với/MT, vì vậy tôi vẫn cần động liên kết với libs thời gian chạy chuẩn - điều này là tốt. Tôi chỉ không muốn kéo PocoNet.dll với tôi, và đó là những gì tôi không thể tìm ra cách để làm. – Yang

+0

/MT có nghĩa là bạn _don't_ liên kết đến dll thời gian chạy./MD có nghĩa là bạn làm. Và cờ này phải giống nhau trên tất cả các lib bạn liên kết đến. – Eugene