【问题标题】:How to pip install a package from a read-only directory?如何 pip 从只读目录安装软件包?
【发布时间】:2026-01-18 18:50:01
【问题描述】:

我正在尝试安装位于已安装目录中的 Python(C 扩展名,如果有的话)包,出于安全原因,该目录是只读的。但是,默认情况下 pip 将在其自己的位置的名为 build 的子目录中构建包,我不能。

$ pip install /mnt/remote/pkgname
Processing /mnt/remote/pkgname
  Preparing metadata (setup.py) ... done
Using legacy 'setup.py install' for pkgname, since package 'wheel' is not installed.
Installing collected packages: pkgname
  Attempting uninstall: pkgname
    Found existing installation: pkgname 1.0.0
    Uninstalling pkgname-1.0.0:
      Successfully uninstalled pkgname-1.0.0
    Running setup.py install for pkgname ... error
    ERROR: Command errored out with exit status 1:
     command: /path/to/venv/bin/python3.8 -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/mnt/remote/pkgname/setup.py'"'"'; __file__='"'"'/mnt/remote/pkgname/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-84ofxq5a/install-record.txt --single-version-externally-managed --compile --install-headers /path/to/venv/include/site/python3.8/pkgname
         cwd: /mnt/remote/pkgname/
    Complete output (6 lines):
    running install
    running build
    running build_ext
    building '_pkgname' extension
    creating build
    error: could not create 'build': Read-only file system
    ----------------------------------------
  Rolling back uninstall of pkgname
  Moving to /path/to/venv/lib/python3.8/site-packages/_pkgname.cpython-38-x86_64-linux-gnu.so
   from /tmp/pip-uninstall-6pwxs8h_/_pkgname.cpython-38-x86_64-linux-gnu.so
  Moving to /path/to/venv/lib/python3.8/site-packages/pkgname-1.0.0.egg-info
   from /path/to/venv/lib/python3.8/site-packages/~lclib-1.0.0.egg-info
ERROR: Command errored out with exit status 1: /path/to/venv/bin/python3.8 -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/mnt/remote/pkgname/setup.py'"'"'; __file__='"'"'/mnt/remote/pkgname/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-84ofxq5a/install-record.txt --single-version-externally-managed --compile --install-headers /path/to/venv/include/site/python3.8/pkgname Check the logs for full command output.

我尝试使用标志 -e--target <dir>--src 的组合,但它们都没有改变输出。

有没有办法编译包而不必在本地复制文件夹?

编辑

我刚刚注意到https://github.com/pypa/pip/issues/10587 对此问题进行了长时间的讨论。

临时解决方案是使用已弃用的选项运行它:

$ pip install --use-deprecated=out-of-tree-build /mnt/remote/pkgname

但是这个标志在 22.1 版本中被设置为停止工作。我仍然需要一个长期的解决方案,而那个问题链接可能就是我们能得到它的地方。

【问题讨论】:

  • 这是值得怀疑的,因为大多数编译器和链接器都需要一个可写的文件存储。
  • 因为你可以安装在某个地方(可能是你的主目录),你可以创建一个临时的 tmp 目录(是的,两次临时)。例如,mkdir $HOME/tmp,然后设置 TMPDIR 并运行 pip installTMPDIR=$HOME/tmp pip install /mnt/remote/pkgname 可能会起作用。

标签: python pip python-c-api


【解决方案1】:

您可以使用 pip install -b customize_build_directory 指定另一个目录作为构建基目录,例如 /tmp。

【讨论】: