如何使用link.exe静态链接

时间:2009-11-07 00:20:19

标签: c++ static linker visual-c++ poco

我一直在尝试使用Visual Studio 2008命令行工具在Windows上静态链接一个名为Poco的C ++库。

我用以下代码构建我的程序:

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

这会导致exe在运行时需要PocoNet.dll和PocoFoundation.dll。

我花了一些时间阅读Windows中的链接,并了解到cl /MT静态链接标准库,而cl /MD动态链接。

我试图指定/MT,但这似乎没有改变任何东西;我的应用程序仍然需要Poco DLL。 (我还怀疑/MT是默认行为。)

..\poco\lib下查看,我发现还有一个PocoNetmt.lib,但指定而不是PocoNet.lib会导致一堆LNK2005错误(“已定义”):

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

然后我尝试堆叠更多标志:

  • /verbose:lib:有助于了解正在发生的事情

  • /Zl:与之前的结果相同

  • /nodefaultlib:libcmt.lib /nodefaultlib:msvcprt.lib:收到此错误:

    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
    
  • 完全放弃.libas suggested here:与上面相同的错误

我也试过上面的一些组合,但都无济于事。

任何线索都将不胜感激。但同样有用的是指向调试(或了解)这些类型问题的资源的任何指针。

4 个答案:

答案 0 :(得分:15)

您必须在命令行上定义POCO_STATIC并与PocoFoundationmt和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] 如果使用/DPOCO_STATIC进行编译,则无需在链接器命令行上指定POCO库。头文件包含#pragma comment(lib, "PocoXXXmt.lib")语句,应确保链接所有必需的库。

如果不使用/DPOCO_STATIC进行编译,则会自动链接DLL导入库。 [/ UPDATE]

答案 1 :(得分:5)

听起来问题是PocoNet.lib文件是poco.dll的导入库。因此它解析的外部是DLL。

您需要为Poco查找或构建静态库(如果可能)。

答案 2 :(得分:0)

您需要/ MT代码及其所有依赖项静态链接到MSVC运行时(MSVCP90.dll / MSVCR90.dll)。

这是因为PocoNetmt.lib似乎是用/ MT构建的。

如果使用/ MT你仍然得到msvcprt.lib,打开/ verbose并找出哪个其他库拖动它。然后重新编译/找到它的静态构建。

另一种选择是找到使用/ MD构建的静态PocoNet库(因此您可以静态链接到它,但动态地链接到运行时)并将所有内容切换到/ MD。

编辑: 当Poco dll与/ MT链接时不会影响您。但是既然你想要摆脱它,你(以及你所有的其他依赖项)都必须使用相同的/ MT标志。

答案 3 :(得分:0)

使用静态运行时

POCO&gt; = 1.4.0支持静态(并且动态运行时仍然是静态的)

https://raw.github.com/pocoproject/poco/poco-1.4.5/CHANGELOG (搜索“debug_static_mt”)

在包含poco标题时不要忘记定义 POCO_STATIC

相关问题