Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

let CMakeMake easyblock also set Python_EXECUTABLE option, as well as Python3_EXECUTABLE and Python2_EXECUTABLE derivatives (when appropriate) #3463

Merged
merged 12 commits into from
Oct 11, 2024
56 changes: 51 additions & 5 deletions easybuild/easyblocks/generic/cmakemake.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,52 @@ def setup_cmake_env(tc):
setvar("CMAKE_LIBRARY_PATH", library_paths)


def setup_cmake_env_python_hints(cmake_version=None):
"""Set environment variables as hints for CMake to prefer the Python module, if loaded.
Useful when there is no way to specify arguments for CMake directly,
e.g. when CMake is called from within another build system.
Otherwise get_cmake_python_config_[str/dict] should be used instead.
"""
if cmake_version is None:
cmake_version = det_cmake_version()
if LooseVersion(cmake_version) < '3.12':
raise EasyBuildError("Setting Python hints for CMake requires CMake version 3.12 or newer")
python_root = get_software_root('Python')
if python_root:
python_version = LooseVersion(get_software_version('Python'))
setvar('Python_ROOT_DIR', python_root)
if python_version >= "3":
setvar('Python3_ROOT_DIR', python_root)
else:
setvar('Python2_ROOT_DIR', python_root)


def get_cmake_python_config_dict():
"""Get a dictionary with CMake configuration options for finding Python if loaded as a module."""
options = {}
python_root = get_software_root('Python')
if python_root:
python_version = LooseVersion(get_software_version('Python'))
python_exe = os.path.join(python_root, 'bin', 'python')
# This is required for (deprecated) `find_package(PythonInterp ...)`
options['PYTHON_EXECUTABLE'] = python_exe
# Ensure that both `find_package(Python) and find_package(Python2/3)` work as intended
options['Python_EXECUTABLE'] = python_exe
if python_version >= "3":
options['Python3_EXECUTABLE'] = python_exe
else:
options['Python2_EXECUTABLE'] = python_exe
return options


def get_cmake_python_config_str():
"""Get CMake configuration arguments for finding Python if loaded as a module.
This string is intended to be passed to the invocation of `cmake`.
"""
options = get_cmake_python_config_dict()
return ' '.join('-D%s=%s' % (key, value) for key, value in options.items())


class CMakeMake(ConfigureMake):
"""Support for configuring build with CMake instead of traditional configure script"""

Expand Down Expand Up @@ -273,17 +319,15 @@ def configure_step(self, srcdir=None, builddir=None):
# see https://github.com/Kitware/CMake/commit/3ec9226779776811240bde88a3f173c29aa935b5
options['CMAKE_SKIP_RPATH'] = 'ON'

# make sure that newer CMAKE picks python based on location, not just the newest python
# Avoids issues like e.g. https://github.com/EESSI/software-layer/pull/370#issuecomment-1785594932
if LooseVersion(self.cmake_version) >= '3.15':
options['CMAKE_POLICY_DEFAULT_CMP0094'] = 'NEW'

# show what CMake is doing by default
options['CMAKE_VERBOSE_MAKEFILE'] = 'ON'

# disable CMake user package repository
options['CMAKE_FIND_USE_PACKAGE_REGISTRY'] = 'OFF'

# ensure CMake uses EB python, not system or virtualenv python
options.update(get_cmake_python_config_dict())

if not self.cfg.get('allow_system_boost', False):
boost_root = get_software_root('Boost')
if boost_root:
Expand All @@ -302,6 +346,8 @@ def configure_step(self, srcdir=None, builddir=None):
options['BOOST_ROOT'] = boost_root
options['Boost_NO_SYSTEM_PATHS'] = 'ON'

self.cmake_options = options

if self.cfg.get('configure_cmd') == DEFAULT_CONFIGURE_CMD:
self.prepend_config_opts(options)
command = ' '.join([
Expand Down
Loading