【问题标题】:Weird LNK2001 errors after migration to VS2019迁移到 VS2019 后出现奇怪的 LNK2001 错误
【发布时间】:2020-11-23 19:09:43
【问题描述】:

在将我的代码从 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。

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

【问题讨论】:

  • 你是如何构建 tools.lib 的?为什么里面有STL函数?它是使用“静态 CRT 链接”构建的,还是包含 STL 库的副本?从运行 dumpbin /linkermember tools.lib 的 VS 开发人员命令提示符中尝试并确保其中没有 STL 副本。
  • @ChuckWalbourn 一切都使用/MD(动态链接CRT)和/Gy。我想它因为内联而包含 STL 函数,但在 VS2017 中这不是问题。事实上,VS2017 的/VERBOSE 输出显示了相同的图片,但由于某种原因,它不会导致未解析的符号(它们只是从未被提及)。感觉就像 /Gy 被 VS2019 忽略了——它试图解析 .obj 中提到的每个符号,这些符号被已解析的 STL 引用拉取
  • 你使用的VS 2019完整版是什么?您可能希望通过报告问题向developercommunity.visualstudio.com/spaces/8/index.html 发布错误报告。一般来说,由 VS 2017 构建的位应与 VS 2019 程序链接。
  • @ChuckWalbourn VS 16.6.5。我不敢相信没有人遇到这个问题,在谷歌也找不到任何东西。我想我会尝试使用一些简单的代码来重现它并提交给 MS... 链接器输出很奇怪 - 提到了一些从 &lt;symbol&gt;__t2m@&lt;symbol&gt; 的“搜索转换”...:\
  • @ChuckWalbourn Huh... 看起来 /clr 会影响 std::exception::what 的内联(将其关闭),因此 CLD dll 最终会在链接库中搜索此符号。它偶然发现了这样的出口/。问题是,当我切换工具集 (v141 -> v142) 时静态库中的 smth 更改(对象的顺序?)并且现在在不同的 .obj 文件中发现了所述符号,导致引入不同的依赖项集......

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


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多