如何修复 Python 安装软件包时出现的 No such file or directory
编译器错误
作者 Alex Garnett
导言
在安装 Python 模块时,你可能会收到一个常见的错误:No such file or directory
,意为“无此文件或目录”。这句话可能会误导你,因为你试图安装的包中通常并没有丢失文件或目录。其实,这个错误是由于 Python 在安装模块时试图调用你的系统编译器导致的。因为通向系统编译器的路径通常硬编码在 Python 中,而它没有找到它所需要的编译器文件。本教程将提供一个这种错误的例子,以及如何在不同的平台上修复它。
缺少编译器的错误
Python 包通常是使用 pip
软件包管理器的 pip install
命令来安装的。pip 会打印出你选择的包额外需要的依赖项列表,以及一长串的安装过程。但有时,安装程序会以一个错误退出,输出的末尾包含类似下面的文字:
Output
x86_64-linux-gnu-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/python3.10 -I/usr/local/lib/python3.10/dist-packages/numpy/core/include -I/usr/include/python3.10 -c radiomics/src/_cmatrices.c -o build/temp.linux-x86_64-3.10/radiomics/src/_cmatrices.o
error: command 'x86_64-linux-gnu-gcc' failed: No such file or directory
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure
× Encountered error while trying to install package.
╰─> pyradiomics
note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.
这个错误是试图用 pip install pd-dwi
安装 pd-dwi
的结果,pd-dwi
是一个用于化疗研究的 Python 库。
某些 Python 库,特别是那些用于科学计算的库,在安装后需要在你的机器本地编译额外的代码。Python 是一种高级的解释性语言,只有 Python 解释器存在时才能运行。Python 库偶尔会为了高性能处理而包含像 C 或 Rust 这样的低级语言,它们需要进行编译和优化才可执行。因此,如果你的系统上没有编译器,Python 安装就会失败。
在大多数现代平台上,当你安装 Python 的软件包管理器 pip
时,它会建立一个编译器环境,安装相关的软件包。然而,有几种原因可能导致它不会这样做。例如,编译器有可能被意外地卸载了,或者一开始就没有安装。而且与 Linux 不同,Python 包通常不由 Mac 或 Windows 上的系统包管理器安装,这就更有可能造成麻烦。
本教程的后续几步将提供在 Ubuntu/Debian Linux、Red Hat/Rocky Linux、Windows 和 macOS 上安装和验证兼容的 Python 的编译器的说明。
Ubuntu 和 Debian 的编译器包
在 Ubuntu 上,你可以安装一个名为 build-essential
的软件包,它可以为一个现代的、支持良好的编译器环境提供所需的所有软件包。build-essential
就是所谓的 元软件包。它并不指任何一个软件包,而是将一些常见的编译器工具作为依赖项拉进来。
你也可以安装 libpython3-dev
。这是一个存在已久的 Ubuntu/Debian 生态系统包,它本质上是将编译器与 Python “连接”起来,并提供所有需要的后台配置,以便从 Python 或 pip
中自动调用你的编译器。通常它与 pip
一起自动安装,但如果不使用软件包管理器安装 pip
,可能会漏掉它。
用 apt
安装这些包:
$ sudo apt install build-essential libpython3-dev
以上也会安装一些依赖项。之后,你可以检查系统中是否存在 make
命令来验证编译器是否可用。要检查这个,请使用 which
命令:
$ which make
Output
/usr/bin/make
make
是 gcc
(最流行的开源编译器)用来解析 Makefile
的命令,每个软件包使用 Makefile
的形式提供编译指令。如果你现在已经在你的路径上安装了某个版本的 make
,再试试用 pip
安装你的 Python 模块。
用于 Red Hat 和 Rocky Linux 的编译器包
在 Red Hat 和 Rocky Linux 上,你可以使用 dnf
软件包管理器的 group
功能来安装一组软件包,其中包括一个支持良好的编译器环境。这组软件包被称为 "Development Tools"
。
使用两个 dnf
命令来安装该软件包组。
$ sudo dnf groups mark install "Development Tools"
$ sudo dnf groupinstall "Development Tools"
以上代码也会安装一些依赖项。接下来,你可以安装 python3-devel
,一个存在已久的 Red Hat 生态系统软件包,它本质上是将编译器与 Python “连接”起来。 python3-devel
提供了所有需要的后台配置,以便从 Python 或 pip
中自动调用编译器。
$ sudo dnf install python3-devel
之后,你可以检查系统中是否存在 make
命令来验证编译器是否可用。要检查这个,请使用 which
命令:
$ which make
Output
/usr/bin/make
make
是 gcc
(最流行的开源编译器)用来解析 Makefile
的命令,每个软件包使用 Makefile
的形式提供编译指令。如果你现在已经在你的路径上安装了某个版本的 make
,再试试用 pip
安装你的 Python 模块。
Windows 编译器环境
Windows 的编译器问题可能更棘手,因为有许多不同的安装 Python 的方法,而每一种方法都需要不同的编译器:
- 如果您使用带有 WSL2 的 Python,就像在 Linux 下运行 Python 一样,所以您可以按照您的发行版(默认为 Ubuntu)的故障排除说明进行操作。
- 如果你在 Anaconda 上使用 Python,它将在 conda 环境中提供自己的编译器包,这样通常就能避免这些错误。
- 如果你在 Windows 本机上使用 Python,情况会有所不同。默认情况下,Windows 上的 Python 会尝试使用 Microsoft Visual Studio Build Tools。这是一个非常大规模的安装,并且增加了许多云端工作不常用的 Windows 生态系统包,它们在安装后应该会自动工作,就像在 Linux 上安装
make
一样。 - 如果你已经在你的 Windows 环境中使用 MinGW 或 Chocolatey 安装了可用的开源
gcc
和make
构建工具,你可以让 Python 在 Windows 上使用这个编译器,方法是在 Python 安装路径的Lib/distutils/distutils.cfg
创建一个文件并添加以下内容: Lib/distutils/distutils.cfg
[build]
compiler=mingw32
[build_ext]
compiler=mingw32
如果你在 Windows 上安装编译器遇到困难,可以尝试为你要安装的库安装一个预编译的 wheel 包来代替,但这不如从 pip
上安装方便,而且通常只在特定情况下可用。
macOS 编译器环境
macOS 将其编译器工具链捆绑在苹果的开发套件 XCode 中。像 Windows 上的 Visual Studio 一样,XCode 是一个完整的开发环境,有自己的界面,但是你实际上不需要使用 XCode 来编译 Python 包。相反,你只需要确保 XCode 包本身已经安装即可。你可以通过运行 xcode-select -install
来做到这一点。
$ xcode-select --install
你会收到开始安装的提示,然后再次被提示接受软件许可。然后这些工具将自动下载和安装。
结语
Python 生态系统非常强大,对新手和专家级的开发者都敞开怀抱,但在使用时遇到的困难可能会让人困惑。在本教程中,你学会了如何修复由于缺少编译器包而可能出现的错误,以及当 Python 在模块安装时需要编译低级代码时的错误。