【发布时间】: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++