Skip to content

Commit

Permalink
Merge pull request #2 from Flamefire/patch-1
Browse files Browse the repository at this point in the history
Improve Python check in cmakemake.py
  • Loading branch information
MartinsNadia authored Jun 3, 2024
2 parents b60ecd6 + 77884b9 commit 492c330
Showing 1 changed file with 36 additions and 34 deletions.
70 changes: 36 additions & 34 deletions easybuild/easyblocks/generic/cmakemake.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,17 @@
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_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'


def det_cmake_version():
"""
Determine active CMake version.
Expand Down Expand Up @@ -158,7 +160,6 @@ def prepend_config_opts(self, config_opts):
if '-D%s=' % key not in cfg_configopts)
self.cfg['configopts'] = ' '.join([new_opts, cfg_configopts])


def configure_step(self, srcdir=None, builddir=None):
"""Configure build using cmake"""

Expand Down Expand Up @@ -316,58 +317,59 @@ def configure_step(self, srcdir=None, builddir=None):
self.cfg['configopts']])

(out, _) = run_cmd(command, log_all=True, simple=False)
self.check_python_paths()

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

if LooseVersion(self.cmake_version) >= '3.16':
try:
with open('CMakeCache.txt', 'r') as file:
lines = file.readlines()
except FileNotFoundError:
self.log.warning("CMakeCache.txt not found. Python paths checks skipped.")
def check_python_paths(self):
"""Check that there are no detected Python paths outside the EB installed PythonF"""
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

if not os.getenv('EBROOTPYTHON'):
self.log.warning("EBROOTPYTHON is not set.")
else:
self.log.info("Skipping Python path checks as CMake version might be lower than 3.16.")
self.log.info("Checking Python paths")

python_paths = {
"executable": [],
"include": [],
"include_dir": [],
"library": [],
}
errors = []

for line in lines:
match = re.match(r"(?i)_Python(\d+)_((?:EXECUTABLE|INCLUDE_DIR|LIBRARY)):.*?=(.*)", line)
PYTHON_RE = re.compile(r"_?(?:Python|PYTHON)\d_(EXECUTABLE|INCLUDE_DIR|LIBRARY)[^=]*=(.*)")
for line in cmake_cache.splitlines():
match = PYTHON_RE.match(line)
if match:
prefix, path_type, path = match.groups()
if path_type == "INCLUDE_DIR":
python_paths["include"].append(path.strip())
self.log.info(f"Python {path_type} path: {path}")
elif path_type == "EXECUTABLE":
python_paths["executable"].append(path.strip())
self.log.info(f"Python {path_type} path: {path}")
elif path_type == "LIBRARY":
python_paths["library"].append(path.strip())
self.log.info(f"Python {path_type} path: {path}")

# Validate path and handle EBROOTHPYTHON
path_type = match[1].lower()
path = match[2].strip()
self.log.info(f"Python {path_type} path: {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(f"Python does not exist: {path}")

if ebrootpython_path and not path.startswith(ebrootpython_path):
errors.append(f"Python {path_type} does not exist: {path}")
elif not os.path.realpath(path).startswith(ebrootpython_path):
errors.append(f"Python {path_type} path '{path}' is outside EBROOTPYTHON ({ebrootpython_path})")

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

def test_step(self):
"""CMake specific test setup"""
Expand Down

0 comments on commit 492c330

Please sign in to comment.