[BUG] Cannot find the `cmake` module in a wheel build venv when the `cmake` executable is installed in another venv
## Expected Behavior
`cmake` should work with an arbitrary runtime environment when calling the `cmake` executable with an absolution path.
## Current Behavior
When a `venv` (A) is installed with the `cmake` PyPI package, a `venv/bin/cmake` executable will present in `PATH` if the `venv` (A) is activated. While install a PyPI package from source, a build `venv` (B) will be created. In the build `venv` (B), run `cmake` installed in the `venv` (A) with absolute path will raise an error that cannot find the `cmake` module (installed in `venv` (A)).
After adding some debug script to the `cmake` executable:
```diff
#!${PROJECT}/venvA/bin/python3.13
# -*- coding: utf-8 -*-
import re
import sys
+ import site
+ from pprint import pformat
+
+ with open('debug.txt', 'w') as f:
+ print(f'site-packages: {pformat(site.getsitepackages())}', file=f)
+ print(f'sys.path: {pformat(sys.path)}', file=f)
+
from cmake import cmake
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(cmake())
```
I got:
```text
site-packages: ['${PROJECT}/venvA/lib/python3.13/site-packages']
sys.path: ['${PROJECT}/venvA/bin',
'${TMP}/pip-build-env-xxx/site',
'/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python313.zip',
'/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13',
'/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/lib-dynload',
'${TMP}/pip-build-env-xxx/overlay/lib/python3.13/site-packages',
'${TMP}/pip-build-env-xxx/normal/lib/python3.13/site-packages']
```
where the `site-packages` of `venv` (A) is not present in `sys.path`.
## Reproduce Script
```python
# 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)],
)
```
```console
$ 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)
```
## Additional Context
Related:
- metaopt/optree#187
- metaopt/optree#188
The above issue and PR changed to use the `cmake` executable in `PATH` instead of adding the `cmake` PyPI package to `build-system.requires` in `pyproject.toml`.
cc @mgorny
14 条评论