【问题标题】:MSVC error LNK2001: unresolved external symbolMSVC 错误 LNK2001:未解析的外部符号
【发布时间】:2020-08-21 07:12:22
【问题描述】:

我正在尝试将包含 cython 绑定的 Python 库编译到用 C 编写的 FFTW 库中。我在 Windows 机器上,并已更新到最新的 MSVC 构建工具。我安装了 Build Tools 2017 (v15.9.22) 和 Build Tools 2019 (v16.5.4)。

我使用conda create --name tsne python=3.7.4 创建了一个名为tsne 的单独conda 环境,并使用conda install -c conda-forge fftw 使用conda 安装了FFTW。我的setup.py 定义了适当的扩展名和目录来编译模块。例如,C 头文件的包含目录正确包含在miniconda3\envs\tsne\Library\include 中,以及带有miniconda3\envs\tsne\Library\lib 的库目录。

当我尝试编译依赖于 FFTW 的扩展时,我收到以下错误

C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.25.28610\bin\HostX86\x64\cl.exe
  /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\Users\pavli\miniconda3\envs\tsne\include
  -IC:\Users\pavli\miniconda3\envs\tsne\Library\include
  -IC:\Users\pavli\miniconda3\envs\tsne\lib\site-packages\numpy\core\include
  -IC:\Users\pavli\miniconda3\envs\tsne\include
  -IC:\Users\pavli\miniconda3\envs\tsne\include
  "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.25.28610\include"
  "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt"
  "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared"
  "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um"
  "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt"
  "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\cppwinrt"
  /TcopenTSNE/_matrix_mul/matrix_mul_fftw3.c
  /Fobuild\temp.win-amd64-3.7\Release\openTSNE/_matrix_mul/matrix_mul_fftw3.obj  
  /Ox  /openmp
  matrix_mul_fftw3.c

C:\Users\pavli\miniconda3\envs\tsne\lib\site-packages\numpy\core\include\numpy\npy_1_7_deprecated_api.h(14) : Warning Msg: Using deprecated NumPy API, disable it with #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
openTSNE/_matrix_mul/matrix_mul_fftw3.c(2704): warning C4244: 'function': conversion from 'Py_ssize_t' to 'int', possible loss of data
openTSNE/_matrix_mul/matrix_mul_fftw3.c(2741): warning C4244: 'function': conversion from 'Py_ssize_t' to 'int', possible loss of data
openTSNE/_matrix_mul/matrix_mul_fftw3.c(2760): warning C4244: 'function': conversion from 'Py_ssize_t' to 'int', possible loss of data
openTSNE/_matrix_mul/matrix_mul_fftw3.c(3199): warning C4244: 'function': conversion from 'Py_ssize_t' to 'int', possible loss of data
openTSNE/_matrix_mul/matrix_mul_fftw3.c(3199): warning C4244: 'function': conversion from 'Py_ssize_t' to 'int', possible loss of data
openTSNE/_matrix_mul/matrix_mul_fftw3.c(3237): warning C4244: 'function': conversion from 'Py_ssize_t' to 'int', possible loss of data
openTSNE/_matrix_mul/matrix_mul_fftw3.c(3237): warning C4244: 'function': conversion from 'Py_ssize_t' to 'int', possible loss of data
openTSNE/_matrix_mul/matrix_mul_fftw3.c(3257): warning C4244: 'function': conversion from 'Py_ssize_t' to 'int', possible loss of data
openTSNE/_matrix_mul/matrix_mul_fftw3.c(3257): warning C4244: 'function': conversion from 'Py_ssize_t' to 'int', possible loss of data

C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.25.28610\bin\HostX86\x64\link.exe
  /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO 
  /LIBPATH:C:\Users\pavli\miniconda3\envs\tsne\lib 
  /LIBPATH:C:\Users\pavli\miniconda3\envs\tsne\Library\lib 
  /LIBPATH:C:\Users\pavli\miniconda3\envs\tsne\libs 
  /LIBPATH:C:\Users\pavli\miniconda3\envs\tsne\PCbuild\amd64
  "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.25.28610\lib\x64"
  "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\ucrt\x64" 
  "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\um\x64" 
  /EXPORT:PyInit_matrix_mul build\temp.win-amd64-3.7\Release\openTSNE/_matrix_mul/matrix_mul_fftw3.obj 
  /OUT:C:\Users\pavli\Desktop\openTSNE\openTSNE\_matrix_mul\matrix_mul.cp37-win_amd64.pyd 
  /IMPLIB:build\temp.win-amd64-3.7\Release\openTSNE/_matrix_mul\matrix_mul.cp37-win_amd64.lib 
  /Ox  /openmp

LINK : warning LNK4044: unrecognized option '/Ox'; ignored
LINK : warning LNK4044: unrecognized option '/openmp'; ignored
   Creating library build\temp.win-amd64-3.7\Release\openTSNE/_matrix_mul\matrix_mul.cp37-win_amd64.lib and object build\temp.win-amd64-3.7\Release\openTSNE/_matrix_mul\matrix_mul.cp37-win_amd64.exp
matrix_mul_fftw3.obj : error LNK2001: unresolved external symbol fftw_destroy_plan
matrix_mul_fftw3.obj : error LNK2001: unresolved external symbol fftw_plan_dft_r2c_1d
matrix_mul_fftw3.obj : error LNK2001: unresolved external symbol fftw_execute
matrix_mul_fftw3.obj : error LNK2001: unresolved external symbol fftw_plan_dft_c2r_2d
matrix_mul_fftw3.obj : error LNK2001: unresolved external symbol fftw_plan_dft_r2c_2d
matrix_mul_fftw3.obj : error LNK2001: unresolved external symbol fftw_plan_dft_c2r_1d
C:\Users\pavli\Desktop\openTSNE\openTSNE\_matrix_mul\matrix_mul.cp37-win_amd64.pyd : fatal error LNK1120: 6 unresolved externals
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.25.28610\\bin\\HostX86\\x64\\link.exe' failed with exit status 1120

错误表示找不到编译的库(我猜?我不是那么熟悉......)。但是,我可以验证该库是否存在。所以miniconda3\envs\tsne\Library\lib\fftw3.lib 确实存在。然后我认为 fftw3.lib 文件可能有问题,所以我使用 dumpbin.exe 转储了这些符号。链接器说缺少的所有符号实际上都在那里,例如fftw_execute的对应转储块

  Version      : 0
  Machine      : 8664 (x64)
  TimeDateStamp: 5DC30B59 Wed Nov  6 19:05:13 2019
  SizeOfData   : 00000017
  DLL name     : fftw3.dll
  Symbol name  : fftw_execute
  Type         : code
  Name type    : name
  Hint         : 60
  Name         : fftw_execute

所以,如果我理解正确的话,lib 文件没问题。在 Unix 系统上,我可以通过指定 -lfftw 标志来告诉链接器去哪里,但显然,这在 MSVC 上不存在。我很困惑,因为链接器标志 /LIBPATH:C:\Users\pavli\miniconda3\envs\tsne\Library\lib 已通过,但显然它没有找到 fftw3.lib 文件?任何帮助将不胜感激。

【问题讨论】:

  • “在 Unix 系统上,我可以通过指定 -lfftw 来告诉链接器去哪里” - 那不是这样做的;告诉链接的 what 链接。 “在哪里找到要链接的东西”(即在哪里寻找“什么”)是一个不同的链接器选项,类似的场景也出现在 MS 的工具链中。您必须提供两件事:在哪里查找链接库,以及要在其中使用哪些库。
  • Unix 上的 C 编译器(至少我知道的那个)使用 -l 命名要链接的库,并使用 -L 提供搜索库的路径。这与 MSVC 类似,尽管搜索路径的参数是 /LIBPATH,而库作为输入文件给出。 .Lib Files as Linker Input
  • 是的,我应该更准确一点,在 Unix 系统上,我使用 -L 添加库路径,并告诉 -l 使用哪些库。哦,谢谢,指定fftw3.lib 的完整路径就可以了。那么,如果我必须输入完整路径,那么指定 /LIBPATH 的目的是什么?有没有办法做到这一点而不必指定/LIBPATH:C:\Users\pavli\miniconda3\envs\tsne\Library\lib\fftw3.lib 作为参数?
  • 您没有在命令行中列出 fftw3.lib 文件。你给出了路径,但你从未说过你想要 fftw3.lib。链接器不会搜索路径中的每个库。设置 LIBPATH 意味着您可以说“fftw3.lib”,链接器将在所有 LIBPATH 中查找它。 (如果没有 LIBPATH,您必须提供 fftw3.lib 的完整路径。)就像在 C 中一样:您可以将目录添加到您的 INCLUDES 路径,但您仍然必须 #include 它。默认情况下,编译器不仅仅包含目录中的所有内容。
  • 谢谢,这很有帮助。如果你把它打包成一个简短的答案,我会结束这个问题。

标签: c windows visual-studio visual-c++


【解决方案1】:

根据 cmets,我没有在 link.exe 的参数中指定 fftw3.lib/LIBPATH 的行为类似于 unix 编译器上的 -L 标志,并且 -l 标志没有等效项。相反,我们必须传递完整的 lib 路径或只传递 lib 文件名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-03
    • 2014-09-27
    • 2018-08-14
    • 2018-08-24
    • 2016-09-04
    • 2013-08-19
    相关资源
    最近更新 更多