diff options
author | kwryankrattiger <80296582+kwryankrattiger@users.noreply.github.com> | 2024-01-22 09:31:16 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-22 16:31:16 +0100 |
commit | 2d9c6c32228f94e3e5595283b52ae7cc5a160e16 (patch) | |
tree | f11c3ffba04496f7878a0a4dff57e030f6c9bed0 /lib | |
parent | b28692dc723fa74a19d0b0795b46176b2dc59c5c (diff) | |
download | spack-2d9c6c32228f94e3e5595283b52ae7cc5a160e16.tar.gz spack-2d9c6c32228f94e3e5595283b52ae7cc5a160e16.tar.bz2 spack-2d9c6c32228f94e3e5595283b52ae7cc5a160e16.tar.xz spack-2d9c6c32228f94e3e5595283b52ae7cc5a160e16.zip |
CMakePackage pass python hints automatically (#42201)
This commit ensures that CMake packages that also have Python as a build/link dep get a couple defines for the Python path so that CMake's builtin `FindPython3`, `FindPython`, `FindPythonInterp` modules can locate Python correctly.
The main problem with those CMake modules is that they first search for Python versions known at the time of release, meaning that old CMake maybe find older system Python 3.8 even though Python 3.11 comes first in `CMAKE_PREFIX_PATH` and `PATH`.
Package maintainers can opt out of this by overriding the `find_python_hints = False` attribute in the package class.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/build_systems/cmake.py | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py index 73f88d4e8e..a92cb1b6b5 100644 --- a/lib/spack/spack/build_systems/cmake.py +++ b/lib/spack/spack/build_systems/cmake.py @@ -15,6 +15,7 @@ import llnl.util.filesystem as fs import spack.build_environment import spack.builder +import spack.deptypes as dt import spack.package_base from spack.directives import build_system, conflicts, depends_on, variant from spack.multimethod import when @@ -31,8 +32,30 @@ def _extract_primary_generator(generator): primary generator from the generator string which may contain an optional secondary generator. """ - primary_generator = _primary_generator_extractor.match(generator).group(1) - return primary_generator + return _primary_generator_extractor.match(generator).group(1) + + +def _maybe_set_python_hints(pkg: spack.package_base.PackageBase, args: List[str]) -> None: + """Set the PYTHON_EXECUTABLE, Python_EXECUTABLE, and Python3_EXECUTABLE CMake variables + if the package has Python as build or link dep and ``find_python_hints`` is set to True. See + ``find_python_hints`` for context.""" + if not getattr(pkg, "find_python_hints", False): + return + pythons = pkg.spec.dependencies("python", dt.BUILD | dt.LINK) + if len(pythons) != 1: + return + try: + python_executable = pythons[0].package.command.path + except RuntimeError: + return + + args.extend( + [ + CMakeBuilder.define("PYTHON_EXECUTABLE", python_executable), + CMakeBuilder.define("Python_EXECUTABLE", python_executable), + CMakeBuilder.define("Python3_EXECUTABLE", python_executable), + ] + ) def generator(*names: str, default: Optional[str] = None): @@ -86,6 +109,13 @@ class CMakePackage(spack.package_base.PackageBase): #: Legacy buildsystem attribute used to deserialize and install old specs legacy_buildsystem = "cmake" + #: When this package depends on Python and ``find_python_hints`` is set to True, pass the + #: defines {Python3,Python,PYTHON}_EXECUTABLE explicitly, so that CMake locates the right + #: Python in its builtin FindPython3, FindPython, and FindPythonInterp modules. Spack does + #: CMake's job because CMake's modules by default only search for Python versions known at the + #: time of release. + find_python_hints = True + build_system("cmake") with when("build_system=cmake"): @@ -241,9 +271,9 @@ class CMakeBuilder(BaseBuilder): """Standard cmake arguments provided as a property for convenience of package writers """ - std_cmake_args = CMakeBuilder.std_args(self.pkg, generator=self.generator) - std_cmake_args += getattr(self.pkg, "cmake_flag_args", []) - return std_cmake_args + args = CMakeBuilder.std_args(self.pkg, generator=self.generator) + args += getattr(self.pkg, "cmake_flag_args", []) + return args @staticmethod def std_args(pkg, generator=None): @@ -288,6 +318,8 @@ class CMakeBuilder(BaseBuilder): [define("CMAKE_FIND_FRAMEWORK", "LAST"), define("CMAKE_FIND_APPBUNDLE", "LAST")] ) + _maybe_set_python_hints(pkg, args) + # Set up CMake rpath args.extend( [ |