更新到 Visual Studio 17.4.0 会产生与 TLS 相关的链接器错误

Updating to Visual Studio 17.4.0 Yields linker errors related to TLS

提问人:Joe 提问时间:11/9/2022 最后编辑:Joe 更新时间:12/29/2022 访问量:3311

问:

编辑:只是为了关闭,这个问题原来是由于链接器中的错误造成的。Microsoft 在版本 17.4.3 中修复了它

我刚刚将我的 Visual Studio 实例从 17.3.6 更新到 17.4.0。然后我尝试了我的解决方案的干净构建。突然,我的一个项目给了我链接器错误

8>pch.obj : error LNK2001: unresolved external symbol __imp___tls_index_?init@?1??lazy_init_num_threads@internal@at@@YAXXZ@4_NA
8>pch.obj : error LNK2001: unresolved external symbol __imp___tls_offset_?init@?1??lazy_init_num_threads@internal@at@@YAXXZ@4_NA
8>C:\Users\jmole\Documents\Dev\Main\Solutions\..\Mobile\x64\Debug\net6.0-windows\mld_v143.dll : fatal error LNK1120: 2 unresolved externals

这完全让我感到困惑。当我打开详细链接时,我看到它在 MSVCRTD.lib 中找到各种相似的符号。例如。

2>      Found _tls_index
2>      Found __dyn_tls_init

还有其他人遇到过这种情况吗?

C 链接器错误 Visual-Studio-2022

评论

0赞 273K 11/9/2022
__imp___tls_index_莫。您的项目似乎错误地在使用动态或静态 C 运行时之间切换,并且应该在这些错误之前在日志中引发相应的警告。_tls_index
0赞 Joe 11/9/2022
这就是这个名字的意思吗?它试图使用静态函数?因为这与使用 17.3.6 构建的代码完全相同。自从我需要追踪一个不明显的链接错误或破译被破坏的名字以来,已经有十年了,所以我很难分辨
0赞 Joe 11/9/2022
顺便说一句,似乎没有任何关于静态与动态的警告。我们在构建设置中将警告设置为错误
0赞 273K 11/9/2022
这是一个链接器警告,它不受编译器设置的影响。
1赞 273K 11/9/2022
他们似乎切换到较新格式的项目设置数据库。更新后,我的许多设置重置为默认值。因此,您无法确定项目设置是否与 17.3.6 中的相同。幸运的是,我使用 cmake,只需要重新生成项目。

答:

-4赞 Jigme Dechen 11/11/2022 #1

更新到 17.4 后,请在平台工具集中切换到 LLVM for Visual Studio 2022,以避免链接时出现此类错误。

附言: 适用于 Visual Studio 2017、2019 和 2022 的 LLVM:Visual-Studio-llvm-utils

评论

1赞 MSalters 11/11/2022
这不是你应该一时兴起做的事情。
0赞 Joe 11/12/2022
...当然,我不会做一些事情来修复一个简单的链接错误。
1赞 MSalters 11/11/2022 #2

名称 mangling 似乎指向 ,这是一个 PyTorch 函数(有点奇怪,但它很可能使用线程本地存储)。您可能需要使用相同的工具链重新构建 PyTorchat::internal::lazy_init_num_threads

评论

0赞 Joe 11/12/2022
谢谢。这正是我所猜测的,但你证实了这一点。我希望能够构建 PyTorch。我们使用非 GPU 优化版本,您可以下载该版本。这就是给我链接错误的原因。我希望能够在打开 GPU 优化的情况下正确构建它。不幸的是,我这样做的尝试并不顺利。(这就是为什么我不得不回到 17.3.6)我什至无法让 CMake 为我生成合适的 VS 解决方案。安装了 CUDA 等等。但我想如果我自己想不通,这是另一篇文章的主题。
7赞 Armen Poghosov 11/15/2022 #3

转到 python 环境中的文件,并通过删除仅保留声明的内联实现来编辑它。这将强制生成使用非内联导入。 问题很可能出在 VS C++ 处理具有静态变量的内联导出的方式上 - 在本例中为一个。\Lib\site-packages\torch\include\ATen\Parallel.hat::internal::lazy_init_num_threads()thread_local

当然,完美的解决方案是与您的扩展一起重建 pytorch(就像任何 C++ DLL“导出”类一样,而没有真正关心以安全的 ABI 兼容方式进行),但修补包含文件在这里也是可以的,它只会阻止编译器内联 API 并创建对稍后链接失败的局部静态变量的引用。然后,编译器将使用 pytorch DLL 中的非内联变体,链接器错误将被消除。thread_local

评论

0赞 Joe 11/15/2022
我们现在使用的 PyTorch 版本只是从官方版本下载的已经构建的版本。如果我要编辑该头文件,但没有构建或下载任何新内容,您认为仅更改此头文件即可工作且安全吗?在尝试之前,我先问这个问题,因为为了实际验证这一点,我需要再次更新到13.4版本。然后,如果它引起问题,我将需要恢复。
0赞 Joe 11/15/2022
(表示版本 17.4)
0赞 kilasuelika 11/25/2022
我对pytorch C++版本有同样的问题,它解决了我的问题。
0赞 Joe 12/8/2022
由于即将发布的软件,直到今天我才真正进行此更改。但是我做到了,并且可以确认它解决了问题。我仍然想按照@MSalters首先的建议来构建它。但这确实解决了眼前的问题
0赞 Michael Innes 12/13/2022
我正在使用 Anaconda,所以在我的情况下,文件位于 .然后我只用这个替换了从下到下的所有东西:它起作用了。C:\Users\<username>\AppData\Roaming\Python\Python39\site-packages\torch\include\ATen\Parallel.hinline TORCH_API void lazy_init_num_threads() {}TORCH_API void lazy_init_num_threads();