迁移到VS2019后出现奇怪的LNK2001错误



在将代码从VS2017移动到VS2019后,我偶然发现了奇怪的链接器行为——它似乎引用了静态库中不应该引用的对象(这些对象反过来引用了无法解析的符号(。基本上,我最终得到的是:

1>tools.lib(object_storage_azure.obj) : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __cdecl azure::storage::operation_context::operation_context(void)" (__imp_??0operation_context@storage@azure@@QEAA@XZ)
1>tools.lib(object_storage_azure.obj) : error LNK2001: unresolved external symbol "__declspec(dllimport) private: class Concurrency::task<void> __cdecl azure::storage::cloud_block_blob::upload_block_list_async_impl(class std::vector<class azure::storage::block_list_item,class std::allocator<class azure::storage::block_list_item> > const &,class azure::storage::access_condition const &,class azure::storage::blob_request_options const &,class azure::storage::operation_context,class Concurrency::cancellation_token const &,bool,class std::shared_ptr<class azure::storage::core::timer_handler>)" (__imp_?upload_block_list_async_impl@cloud_block_blob@storage@azure@@AEAA?AV?$task@X@Concurrency@@AEBV?$vector@Vblock_list_item@storage@azure@@V?$allocator@Vblock_list_item@storage@azure@@@std@@@std@@AEBVaccess_condition@23@AEBVblob_request_options@23@Voperation_context@23@AEBVcancellation_token@5@_NV?$shared_ptr@Vtimer_handler@core@storage@azure@@@7@@Z)
1>tools.lib(object_storage_azure.obj) : error LNK2001: unresolved external symbol "__declspec(dllimport) public: class Concurrency::task<void> __cdecl azure::storage::cloud_block_blob::upload_from_stream_async(class Concurrency::streams::basic_istream<unsigned char>,unsigned __int64,class azure::storage::access_condition const &,class azure::storage::blob_request_options const &,class azure::storage::operation_context,class Concurrency::cancellation_token const &)" (__imp_?upload_from_stream_async@cloud_block_blob@storage@azure@@QEAA?AV?$task@X@Concurrency@@V?$basic_istream@E@streams@5@_KAEBVaccess_condition@23@AEBVblob_request_options@23@Voperation_context@23@AEBVcancellation_token@5@@Z)
... // and so forth

tools.lib是我自己的静态库,它包含了很多代码,其中99%没有被正在编译的项目使用。特别是,object_storage_azure.obj中的任何内容都没有被确定使用。

因此,使用/VERBOSE运行链接器会产生以下结果:

1>Starting pass 1
1>Processed /DEFAULTLIB:uuid.lib
1>Processed /DEFAULTLIB:msvcprt
1>Processed /DEFAULTLIB:atls.lib
1>Processed /DEFAULTLIB:kernel32.lib
1>Processed /DEFAULTLIB:user32.lib
1>Processed /DEFAULTLIB:advapi32.lib
1>Processed /DEFAULTLIB:ole32.lib
1>Processed /DEFAULTLIB:shell32.lib
1>Processed /DEFAULTLIB:oleaut32.lib
1>Processed /DEFAULTLIB:shlwapi.lib
1>Processed /DEFAULTLIB:comsuppw.lib
1>Processed /DEFAULTLIB:MSVCRT
1>Processed /DEFAULTLIB:OLDNAMES
1>Processed /DEFAULTLIB:MSVCMRT.LIB
1>Processed /DEFAULTLIB:MSCOREE
1>
1>Searching libraries
1>    Searching C:Program Files (x86)Windows Kits10lib10.0.17763.0umx64winhttp.lib:
1>    Searching C:Program Files (x86)Windows Kits10lib10.0.17763.0umx64ws2_32.lib:
...
1>    Searching C:Program Files (x86)Windows Kits10lib10.0.17763.0umx64kernel32.lib:
1>    Searching C:Program Files (x86)Windows Kits10lib10.0.17763.0umx64odbccp32.lib:
1>    Searching C:***my-path***tools.lib:
1>      Found "public: virtual char const * __cdecl std::exception::what(void)const " (?what@exception@std@@UEBAPEBDXZ)
1>        Referenced in stdafx.obj
1>        Loaded tools.lib(treescan_json.obj)            <--------- O_O
1>      Found "public: virtual char const * __cdecl std::bad_weak_ptr::what(void)const " (?what@bad_weak_ptr@std@@UEBAPEBDXZ)
1>        Referenced in stdafx.obj
1>        Loaded tools.lib(object_storage_azure.obj)     <--------- O_O
...

基本上,由于某种神秘的原因,一些STL引用被解析为我的静态库中的对象文件(否则是未引用的((以及那些随后被拉入的无法解析的东西(。

不确定是否相关,但正在编译的项目是/clrdll;一切都使用v142工具集和10.0.17763.0 SDK。

解决这个问题的正确方法是什么?

之所以会发生这种情况,是因为链接器会查找通常被内联的某些符号(例如std::exception::what((但在/clr有效时不会(,并在用户静态库的随机对象文件中找到它们(拉入所述对象文件具有的所有依赖项(。切换到VS2019只需更改所述库中对象文件的顺序。请在此处查看详细信息。

最新更新