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

enhance CMakeMake easyblock to check whether correct Python installation was picked up by CMake #3399

Open
wants to merge 2 commits into
base: 5.0.x
Choose a base branch
from
Open
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
56 changes: 54 additions & 2 deletions easybuild/easyblocks/generic/cmakemake.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@
from easybuild.framework.easyconfig import BUILD, CUSTOM
from easybuild.tools.build_log import EasyBuildError, print_warning
from easybuild.tools.config import build_option
from easybuild.tools.filetools import change_dir, create_unused_dir, mkdir, which
from easybuild.tools.filetools import change_dir, create_unused_dir, mkdir, read_file, which
from easybuild.tools.environment import setvar
from easybuild.tools.modules import get_software_root, get_software_version
from easybuild.tools.run import run_shell_cmd
from easybuild.tools.systemtools import get_shared_lib_ext
from easybuild.tools.utilities import nub
import easybuild.tools.toolchain as toolchain


DEFAULT_CONFIGURE_CMD = 'cmake'
Expand Down Expand Up @@ -331,9 +332,60 @@ def configure_step(self, srcdir=None, builddir=None):
self.cfg['configopts']])

res = run_shell_cmd(command)

self.check_python_paths()
return res.output

def check_python_paths(self):
"""Check that there are no detected Python paths outside the Python dependency provided by EasyBuild"""
if not os.path.exists('CMakeCache.txt'):
self.log.warning("CMakeCache.txt not found. Python paths checks skipped.")
return
cmake_cache = read_file('CMakeCache.txt')
if not cmake_cache:
self.log.warning("CMake Cache could not be read. Python paths checks skipped.")
return

self.log.info("Checking Python paths")

python_paths = {
"executable": [],
"include_dir": [],
"library": [],
}
python_regex = re.compile(r"_?(?:Python|PYTHON)\d?_(EXECUTABLE|INCLUDE_DIR|LIBRARY)[^=]*=(.*)")
for line in cmake_cache.splitlines():
match = python_regex.match(line)
if match:
path_type = match[1].lower()
path = match[2].strip()
self.log.info("Python %s path: %s", path_type, path)
python_paths[path_type].append(path)

ebrootpython_path = get_software_root("Python")
if not ebrootpython_path:
if any(python_paths.values()) and not self.toolchain.comp_family() == toolchain.SYSTEM:
self.log.warning("Found Python paths in CMake cache but Python is not a dependency")
# Can't do the check
return
ebrootpython_path = os.path.realpath(ebrootpython_path)

errors = []
for path_type, paths in python_paths.items():
for path in paths:
if path.endswith('-NOTFOUND'):
continue
if not os.path.exists(path):
errors.append("Python %s does not exist: %s" % (path_type, path))
elif not os.path.realpath(path).startswith(ebrootpython_path):
errors.append("Python %s path '%s' is outside EBROOTPYTHON (%s)" %
(path_type, path, ebrootpython_path))

if errors:
# Combine all errors into a single message
error_message = "\n".join(errors)
raise EasyBuildError("Python path errors:\n" + error_message)
self.log.info("Python check successful")

def test_step(self):
"""CMake specific test setup"""
# When using ctest for tests (default) then show verbose output if a test fails
Expand Down
Loading