Description
Description
For packages that contain extension modules, they may need to use build tools such as cmake
/ ninja
. There are PyPI packages that ship those tools with console scripts. E.g., pip3 install cmake
will create an executable ${PROJECT}/venv/bin/cmake
.
#!${PROJECT}/venv/bin/python3.13
# -*- coding: utf-8 -*-
import re
import sys
from cmake import cmake
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(cmake())
When installing a user package from the source, pip
will create an isolated build environment (venv
(B)). During installing the user package, the setup script may invoke the cmake
executable in the PATH
mentioned above (installed in venv
(A)). However, in the build environment (venv
(B)), the cmake
script (interpreted by Python in venv
(A)) failed to find the cmake
module installed in venv
(A).
See issue scikit-build/cmake-python-distributions#586 for more information.
I think this issue is caused by the suspicious sitecustomize.py
in the build environment:
pip/src/pip/_internal/build_env.py
Lines 96 to 134 in 93d43c9
Expected behavior
The console script (e.g., cmake
) should always be runnable if invoked in a subprocess with an absolute path.
pip version
25.0.1
Python version
3.13.2
OS
macOS
How to Reproduce
- Create a
setup.py
with content:
# setup.py
import os
import shutil
from pathlib import Path
from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext
HERE = Path(__file__).absolute().parent
class CMakeExtension(Extension):
def __init__(self, name, source_dir=".", target=None, **kwargs):
super().__init__(name, sources=[], **kwargs)
self.source_dir = Path(source_dir).absolute()
self.target = target if target is not None else name.rpartition(".")[-1]
@classmethod
def cmake_executable(cls):
cmake = os.getenv("CMAKE_EXECUTABLE", "")
if not cmake:
cmake = shutil.which("cmake")
return cmake
class cmake_build_ext(build_ext):
def build_extension(self, ext):
if not isinstance(ext, CMakeExtension):
super().build_extension(ext)
return
cmake = ext.cmake_executable()
if cmake is None:
raise RuntimeError("Cannot find CMake executable.")
self.spawn([cmake, "--version"])
setup(
name="cmake-venv-test",
version="0.0.1",
cmdclass={"build_ext": cmake_build_ext},
ext_modules=[CMakeExtension("cmake_venv_test._C", source_dir=HERE)],
)
- Run the following commands:
$ python3 -m venv venv
$ source venv/bin/activate
$ pip3 install cmake
$ which cmake
${PROJECT}/venv/bin/cmake
$ pip3 install .
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Processing ${PROJECT}
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: cmake-venv-test
Building wheel for cmake-venv-test (pyproject.toml) ... error
error: subprocess-exited-with-error
× Building wheel for cmake-venv-test (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [9 lines of output]
running bdist_wheel
running build
running build_ext
${PROJECT}/venv/bin/cmake --version
Traceback (most recent call last):
File "${PROJECT}/venv/bin/cmake", line 5, in <module>
from cmake import cmake
ModuleNotFoundError: No module named 'cmake'
error: command '${PROJECT}/venv/bin/cmake' failed with exit code 1
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for cmake-venv-test
Failed to build cmake-venv-test
ERROR: Failed to build installable wheels for some pyproject.toml based projects (cmake-venv-test)
Output
$ pip3 install .
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Processing ${PROJECT}
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: cmake-venv-test
Building wheel for cmake-venv-test (pyproject.toml) ... error
error: subprocess-exited-with-error
× Building wheel for cmake-venv-test (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [9 lines of output]
running bdist_wheel
running build
running build_ext
${PROJECT}/venv/bin/cmake --version
Traceback (most recent call last):
File "${PROJECT}/venv/bin/cmake", line 5, in <module>
from cmake import cmake
ModuleNotFoundError: No module named 'cmake'
error: command '${PROJECT}/venv/bin/cmake' failed with exit code 1
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for cmake-venv-test
Failed to build cmake-venv-test
ERROR: Failed to build installable wheels for some pyproject.toml based projects (cmake-venv-test)
The error raises when installing with and without the --editable
flag.
There will be no error if do either of the following:
- Add
cmake
tobuild-system.requires
inpyproject.toml
. - Install with flag
--no-build-isolation
.
Code of Conduct
- I agree to follow the PSF Code of Conduct.