Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to statically link using link.exe

I've been trying to statically link against a C++ library called Poco on Windows using the Visual Studio 2008 command line tools.

I build my program with:

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

This results in an exe that at runtime requires PocoNet.dll and PocoFoundation.dll.

I spent some time reading up on linking in Windows, and learned that cl /MT statically links against the standard library, while cl /MD links dynamically.

I tried to specify /MT, but that didn't seem to change anything; my app still requires the Poco DLLs. (I also suspect that /MT is the default behavior.)

Looking under ..\poco\lib, I found there was also a PocoNetmt.lib, but specifying that instead of PocoNet.lib resulted in a bunch of LNK2005 errors ("already defined"):

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)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in exp.obj

I then tried stacking on more flags:

  • /verbose:lib: useful for seeing what's happening

  • /Zl: same results as before

  • /nodefaultlib:libcmt.lib /nodefaultlib:msvcprt.lib: got this error:

    PocoFoundationmt.lib(Exception.obj) : warning LNK4217: locally defined symbol ??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ (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)) imported in function __ehhandler$??0Exception@Poco@@QAE@ABV01@@Z
    
  • dropping the .lib altogether, as suggested here: same error as above

I also tried some combinations of the above, all to no avail.

Any clues would be greatly appreciated. But just as useful would be any pointers to resources that are useful for debugging (or learning about) these types of issues.

like image 309
Yang Avatar asked Nov 07 '09 00:11

Yang


People also ask

Can you statically link a shared object?

You can't statically link a shared library (or dynamically link a static one).

What does it mean to statically link?

Static linking is the result of the linker copying all library routines used in the program into the executable image. This may require more disk space and memory than dynamic linking, but is both faster and more portable, since it does not require the presence of the library on the system where it is run.

How do you link Sfml statically?

How do I link SFML statically? In order to link SFML statically, you'll need to setup your build environment to link against the static libraries of SFML. Static libraries are the ones with a -s suffix, for example sfml-graphics-s .


2 Answers

You have to define POCO_STATIC on the command line and link with both PocoFoundationmt and PocoNetmt.lib:

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

exp.cpp

C:\test>link /libpath:..\poco\lib /WX /nologo exp.obj PocoNetmt.lib PocoFoundationmt.lib

[UPDATE] If you compile with /DPOCO_STATIC, then it isn't necessary to specify the POCO libraries on the linker command line. The header files contain #pragma comment(lib, "PocoXXXmt.lib") statements that should ensure that all the necessary libraries will be linked in.

If you don't compile with /DPOCO_STATIC, then the DLL import libraries will be automatically linked instead. [/UPDATE]

like image 70
Alex Avatar answered Sep 22 '22 06:09

Alex


It sounds like the problem is that the PocoNet.lib file is an import library for the poco.dll. So the externs it resolves are to the DLL.

You'll need to find or build a static library for Poco (if possible).

like image 22
Michael Burr Avatar answered Sep 20 '22 06:09

Michael Burr