我曾经遇到了这个问题,当我想要安装pylisten(它有一个PyAudio的依赖项)。
这里有两个问题 - 首先,你的MSVC找不到portaudio.h,然后在构建时会有一个关于min
宏的问题。但首先要解决第一个问题。
获取portaudio
这是PyAudio的C依赖项,因此您需要包含文件,特别是像屏幕截图中所示的portaudio.h
。尽管可以获得Windows的二进制文件,但如果您使用Anaconda,则最简单的方法是使用conda
进行安装:
(base) C:\> conda search portaudio
Loading channels: done
# Name Version Build Channel
portaudio 19.6.0 h0c8e037_3 pkgs/main
portaudio 19.6.0 hfa6e2cd_3 pkgs/main
(base) C:\> conda install portaudio
(...)
接下来,我们希望了解 portaudio 库的文件实际上去了哪里。没有 conda package --list
命令...(参见这里: https://github.com/conda/conda/pull/7457 ),因此我们需要在 Stack Overflow 上找到其他地方的一些技巧:
(base) C:\>dir %CONDA_PREFIX%\conda-meta\portaudio*
(...)
26.01.2020 13:17 5 577 portaudio-19.6.0-hfa6e2cd_3.json
我们需要检查这个 JSON,并找到
files
属性:
"extracted_package_dir": "C:\\Users\\(...)\\Anaconda3\\pkgs\\portaudio-19.6.0-hfa6e2cd_3",
"features": "",
"files": [
"Library/bin/portaudio.dll",
"Library/include/pa_asio.h",
"Library/include/pa_jack.h",
"Library/include/pa_linux_alsa.h",
"Library/include/pa_mac_core.h",
"Library/include/pa_win_ds.h",
"Library/include/pa_win_wasapi.h",
"Library/include/pa_win_waveformat.h",
"Library/include/pa_win_wdmks.h",
"Library/include/pa_win_wmme.h",
"Library/include/portaudio.h",
"Library/lib/portaudio.lib",
"Library/lib/portaudio_static.lib",
".nonadmin"
],
extracted_package_dir
(上面删除了用户名)实际上相当于:
%CONDA_PREFIX%\pkgs\portaudio-19.6.0-hfa6e2cd_3
。
因此,针对这个特定的构建,必要的包含目录(-I
)如下:
%CONDA_PREFIX%\pkgs\portaudio-19.6.0-hfa6e2cd_3\Library\include
以及链接目录(-L
)如下:
%CONDA_PREFIX%\pkgs\portaudio-19.6.0-hfa6e2cd_3\Library\lib
这将在下文中很有用。
简单的方式,但不起作用
如果你的Conda环境具有MSVC 14.0来构建本地扩展,那么你应该使用:
(base) C:\> pip install --global-option=build_ext --global-option="-I%CONDA_PREFIX%\pkgs\portaudio-19.6.0-hfa6e2cd_3\Library\include" --global-option="-L%CONDA_PREFIX%\pkgs\portaudio-19.6.0-hfa6e2cd_3\Library\lib" pyaudio
现在,它将找到
portaudio.h
!但是不幸的是,写作时会导致编译错误。我仍然将其放在这里,因为也许与MSVC的不兼容性会得到修复。
艰难但成功的方式
我们需要修改PyAudio的源代码。可以像这样完成:
(base) C:\>pip download pyaudio
这将下载一个类似于
PyAudio-0.2.11.tar.gz
的文件(版本号可能在未来有所不同)。您需要使用
tar
解包它。我把它放在
C:\Windows\system32
- 可能是因为WSL的缘故。您也可以使用7-zip来解压缩它。无论如何:
(base) C:\>tar xf PyAudio-0.2.11.tar.gz
(... unpacked ...)
(base) C:\>cd PyAudio-0.2.11
(base) C:\PyAudio-0.2.11>
现在要想得到与以前相同的结果,您需要以不同于pip
的方式向setup.py
传递特殊参数:
(base) C:\PyAudio-0.2.11>python setup.py build_ext --include-dirs="%CONDA_PREFIX%\pkgs\portaudio-19.6.0-hfa6e2cd_3\Library\include" --library-dirs="%CONDA_PREFIX%\pkgs\portaudio-19.6.0-hfa6e2cd_3\Library\lib" install
(compile errors: min macro redefinition, __typeof__ undefined)
现在,请编辑文件src\_portaudiomodule.c
,并删除/注释掉这些行(就在顶部,第39行左右):
#define min(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; \
})
这个微不足道的宏定义是罪魁祸首。如果你想提交修复给Pham先生(
http://people.csail.mit.edu/hubert/pyaudio/),请不要删除它,而是使用类似于
#ifndef _MSC_VER
...
#endif
的内容。
保存文件并再次运行此程序:
(base) C:\PyAudio-0.2.11>python setup.py build_ext --include-dirs="%CONDA_PREFIX%\pkgs\portaudio-19.6.0-hfa6e2cd_3\Library\include" --library-dirs="%CONDA_PREFIX%\pkgs\portaudio-19.6.0-hfa6e2cd_3\Library\lib" install
现在应该一切都好了。
编辑: 简明扼要的方法
再次检查后,我在 https://repo.anaconda.com/pkgs/main/win-64
中看到了 pyaudio
。这意味着,如果您使用的是Anaconda,您只需执行以下操作:
conda install pyaudio
为了教育目的,我将留下本答案的其余部分。