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

时间:2020-08-03 17:23:53

标签: c++ visual-studio visual-c++ linker visual-studio-2019

将代码从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 Kits\10\lib\10.0.17763.0\um\x64\winhttp.lib:
1>    Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x64\ws2_32.lib:
...
1>    Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x64\kernel32.lib:
1>    Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x64\odbccp32.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引用已解析为我的静态库中的对象文件(否则为未引用的对象文件)(随后将这些文件拉进了无法解析的整个世界)。

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

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

1 个答案:

答案 0 :(得分:0)

之所以会这样,是因为链接器会寻找通常会内联的某些符号(例如std::exception::what)(但在/clr生效时则不会在内)并在用户静态库的随机对象文件中找到它们(将其拉入)表示目标文件具有的所有依赖性)。切换到VS2019只会更改目标库中目标文件的顺序。查看详细信息here