迁移到VS2019后出现奇怪的LNK2001错误
将代码从VS2017移至VS2019之后,我偶然发现了奇怪的链接器行为-似乎它引用了静态库中不应该包含的对象(反过来又引用了无法解析的符号).基本上,我会得到以下结果:
After moving my code from VS2017 to VS2019 I stumbled into strange linker behaviour -- it seems like it references objects from static library that it shouldn't have (which in turn refer to symbols that can't be resolved). Basically, I end up with this:
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
中的任何内容.
tools.lib
is my own static library and it contains a lot of code, with 99% of it not being used by project being compiled. In particular, nothing from object_storage_azure.obj
is being used for sure.
因此,使用/VERBOSE
运行链接器会产生以下结果:
So, running linker with /VERBOSE
produces this:
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引用已解析为我的静态库中的对象文件(否则为未引用的对象文件)(随后将这些文件拉进了无法解析的整个世界).
Basically, for some mysterious reason some STL references were resolved to (otherwise unreferenced) object files in my static lib (and those subsequently pulled in a whole world of stuff that can't be resolved).
不确定是否相关,但是正在编译的项目是/clr
dll;一切都使用v142工具集和10.0.17763.0 SDK.
Not sure if it is related, but project being compiled is a /clr
dll; everything uses v142 toolset and 10.0.17763.0 SDK.
解决此问题的正确方法是什么?
What is the proper way to address this issue?
之所以会发生这种情况,是因为链接程序会寻找通常会内联的某些符号(例如 std :: exception :: what
)(但不是在/clr
有效)并在用户静态库的随机目标文件中找到它们(拉入该目标文件具有的所有依赖项).切换到VS2019只会更改目标库中目标文件的顺序.在此处中查看详细信息.
The happens because linker looks for certain symbols (e.g. std::exception::what
) that normally get inlined (but not when /clr
is in effect) and finds them in random object file of user static library (pulling in all dependencies said object file has). Switching to VS2019 simply changes the order of object files in said library. See details here.