summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorkwryankrattiger <80296582+kwryankrattiger@users.noreply.github.com>2024-01-22 09:31:16 -0600
committerGitHub <noreply@github.com>2024-01-22 16:31:16 +0100
commit2d9c6c32228f94e3e5595283b52ae7cc5a160e16 (patch)
treef11c3ffba04496f7878a0a4dff57e030f6c9bed0 /lib
parentb28692dc723fa74a19d0b0795b46176b2dc59c5c (diff)
downloadspack-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.py42
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(
[