Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 22 additions & 26 deletions repos/spack_repo/builtin/build_systems/cmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,6 @@ def _extract_primary_generator(generator):
return _primary_generator_extractor.match(generator).group(1)


def _maybe_set_python_hints(pkg: 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) or not pkg.spec.dependencies(
"python", deptype=("build", "link")
):
return
python_executable = pkg.spec["python"].command.path
args.extend(
[
define("PYTHON_EXECUTABLE", python_executable),
define("Python_EXECUTABLE", python_executable),
define("Python3_EXECUTABLE", python_executable),
]
)


def _supports_compilation_databases(pkg: PackageBase) -> bool:
"""Check if this package (and CMake) can support compilation databases."""

Expand Down Expand Up @@ -172,20 +154,16 @@ class CMakePackage(PackageBase):
https://cmake.org/cmake/help/latest/
"""

#: List of package names for which CMake argument injection should be disabled
disable_cmake_hints_from: List[str] = []

#: This attribute is used in UI queries that need to know the build
#: system base class
build_system_class = "CMakePackage"

#: Legacy buildsystem attribute used to deserialize and install old specs
default_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"):
Expand Down Expand Up @@ -405,7 +383,25 @@ def std_args(pkg: PackageBase, generator: Optional[str] = None) -> List[str]:
)

_conditional_cmake_defaults(pkg, args)
_maybe_set_python_hints(pkg, args)

# Append extra hint/option arguments from dependencies
# TODO: Consider properties from virtual packages like Mpi
disable_cmake_hints_from = getattr(pkg, "disable_cmake_hints_from", [])
for dep in pkg.spec.edges_to_dependencies():
# Skip packages without the callback
dep_pkg = dep.spec.package
if not hasattr(dep_pkg, "dependent_cmake_args"):
continue

# Skip disabled dependency cmake args
if dep_pkg.name in disable_cmake_hints_from:
continue

# Skip disabled virtual dependency cmake args
if any(v in disable_cmake_hints_from for v in dep.virtuals):
continue

args.extend(dep_pkg.dependent_cmake_args(pkg.spec))

return args

Expand Down
2 changes: 1 addition & 1 deletion repos/spack_repo/builtin/packages/opencv/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Opencv(CMakePackage, CudaPackage):
homepage = "https://opencv.org/"
url = "https://github.com/opencv/opencv/archive/4.5.0.tar.gz"
git = "https://github.com/opencv/opencv.git"
find_python_hints = False # opencv uses custom OpenCVDetectPython.cmake
disable_cmake_hints_from = ["python"] # opencv uses custom OpenCVDetectPython.cmake

maintainers("bvanessen", "adamjstewart")

Expand Down
10 changes: 10 additions & 0 deletions repos/spack_repo/builtin/packages/python/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -1324,6 +1324,16 @@ def setup_dependent_package(self, module, dependent_spec):
module.python_platlib = join_path(dependent_spec.prefix, self.platlib)
module.python_purelib = join_path(dependent_spec.prefix, self.purelib)

def dependent_cmake_args(self, dependent_spec: Spec) -> List[str]:
# pkg.spec["python"] can re-direct to python-venv if pkg extends python
# ref. https://github.com/spack/spack/pull/40773
python_executable = dependent_spec["python"].command.path
return [
f"-DPYTHON_EXECUTABLE:PATH={python_executable}",
f"-DPython_EXECUTABLE:PATH={python_executable}",
f"-DPython3_EXECUTABLE:PATH={python_executable}",
]

def add_files_to_view(self, view, merge_map, skip_if_exists=True):
"""Make the view a virtual environment if it isn't one already.

Expand Down
6 changes: 6 additions & 0 deletions tests/build_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,12 @@ def test_cmake_std_args(self, default_mock_concretization):
s = default_mock_concretization("mpich")
assert cmake.CMakeBuilder.std_args(s.package)

def test_cmake_dependent_args(self, default_mock_concretization):
# Call the function on a CMakePackage instance
s = default_mock_concretization("cmake-client +cmake_hints")
args = cmake.CMakeBuilder.std_args(s.package)
assert '-DCMAKE_HINTS_ARG:STRING="Foo"' in args

def test_cmake_bad_generator(self, default_mock_concretization):
s = default_mock_concretization("cmake-client")
with pytest.raises(InstallError):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ class CmakeClient(CMakePackage):
)
variant("single", description="", default="blue", values=("blue", "red", "green"), multi=False)
variant("truthy", description="", default=True)
variant("cmake_hints", description="", default=False)

depends_on("c", type="build")
depends_on("cmake-hints", when="+cmake_hints")

callback_counter = 0

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright Spack Project Developers. See COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from typing import List

from spack.package import Package, PackageBase, version


def check(condition, msg):
"""Raise an install error if condition is False."""
if not condition:
raise InstallError(msg)


class CmakeHints(Package):
"""A dummy package that uses cmake."""

homepage = "https://www.example.com"
url = "https://www.example.com/cmake-hints-1.0.tar.gz"
version("1.0", md5="4cb3ff35b2472aae70f542116d616e63")

def dependent_cmake_args(self, pkg: PackageBase) -> List[str]:
return ['-DCMAKE_HINTS_ARG:STRING="Foo"']
Loading