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 test and install step of CMakePythonPackage easyblock #2318

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
101 changes: 81 additions & 20 deletions easybuild/easyblocks/generic/cmakepythonpackage.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,56 +30,117 @@
@author: Kenneth Hoste (Ghent University)
@author: Pieter De Baets (Ghent University)
@author: Jens Timmerman (Ghent University)
@author: Alex Domingo (Vrije Universiteit Brussel)
"""
import os

from easybuild.easyblocks.generic.cmakemake import CMakeMake
from easybuild.easyblocks.generic.pythonpackage import PythonPackage
from easybuild.framework.easyconfig import CUSTOM
from easybuild.tools.environment import setvar
from easybuild.tools.filetools import change_dir
from easybuild.tools.py2vs3 import string_type


class CMakePythonPackage(CMakeMake, PythonPackage):
"""Build a Python package and module with cmake.
class CMakePythonPackage(PythonPackage, CMakeMake):
"""Build a Python package and module with CMake.

Some packages use cmake to first build and install C Python packages
and then put the Python package in lib/pythonX.Y/site-packages.

We install this in a seperate location and generate a module file
which sets the PYTHONPATH.

We use the default CMake implementation, and use make_module_extra from PythonPackage.
The steps of CMakePythonPackage are based on PythonPackage, except for
the configure and build steps which use CMakeMake. The tests can be
arbitrarily carried out with both. The installation is always done with
CMake, but the option 'start_dir_python' allows to execute an extra install
with PythonPackage.
"""
@staticmethod
def extra_options(extra_vars=None):
"""Easyconfig parameters specific to Python packages thar are configured/built/installed via CMake"""
extra_vars = PythonPackage.extra_options(extra_vars=extra_vars)
extra_vars = CMakeMake.extra_options(extra_vars=extra_vars)
extra_vars.update({
'start_dir_python': [None, ('Path to Python package source code. It will be installed as a regular '
'Python package after the installation process with make.'), CUSTOM],
# redefine default options to be exclusive of PythonPackage
'installopts': ['', 'Extra options for installation of Python package', CUSTOM],
'runtest': [True, 'Test to run for the Python package.', CUSTOM],
# add extra options as their counterparts for CMakeMake
'installopts_make': ['', 'Extra options for installation with make', CUSTOM],
'runtest_make': [None, ('Indicates if a test should be run after make; should specify argument '
'after make (for e.g.,"test" for make test)'), CUSTOM],
})
# enable out-of-source build
extra_vars['separate_build_dir'][0] = True
return extra_vars

def __init__(self, *args, **kwargs):
"""Initialize with PythonPackage."""
PythonPackage.__init__(self, *args, **kwargs)

def configure_step(self, *args, **kwargs):
"""Main configuration using cmake"""

PythonPackage.configure_step(self, *args, **kwargs)
"""Add extra configuration using CMakeMake"""
super(CMakePythonPackage, self).configure_step()

return CMakeMake.configure_step(self, *args, **kwargs)

def build_step(self, *args, **kwargs):
"""Build Python package with cmake"""
"""Build Python package with CMakeMake"""
return CMakeMake.build_step(self, *args, **kwargs)

def install_step(self):
"""Install with cmake install"""
return CMakeMake.install_step(self)
def test_step(self):
"""Combined test with CMakeMake and PythonPackage tests"""
runtest_python = self.cfg['runtest']

def sanity_check_step(self, *args, **kwargs):
# execute 'runtest_make' in test step of CMakeMake
if self.cfg['runtest_make'] and isinstance(self.cfg['runtest_make'], string_type):
self.cfg['runtest'] = self.cfg['runtest_make']
CMakeMake.test_step(self)

# execute 'runtest' in test step of PythonPackage
self.cfg['runtest'] = runtest_python
if self.cfg['runtest']:
super(CMakePythonPackage, self).test_step()

def install_step(self):
"""
Custom sanity check for Python packages
Always install with CMakeMake install step
Python packages not part of CMakeMake installation can be installed separately with PythonPackage
"""
return PythonPackage.sanity_check_step(self, *args, **kwargs)
# set installopts for installation with CMakeMake
installopts_python = self.cfg['installopts']
self.cfg['installopts'] = self.cfg['installopts_make']

if self.cfg['start_dir_python'] is None:
# single install with CMakeMake
return CMakeMake.install_step(self)
else:
# install with CMakeMake plus PythonPackage
CMakeMake.install_step(self)

# update build environment with CMakeMake installation
new_buildenv = [
('LD_LIBRARY_PATH', 'lib'),
('CPATH', 'include'),
]
for (envar, envpath) in new_buildenv:
oldvar = os.environ.get(envar, '')
newvar = os.path.join(self.installdir, envpath)
setvar(envar, os.pathsep.join([newvar, oldvar]))

# set installopts for installation with PythonPackage
self.cfg['installopts'] = installopts_python

# move to Python package source directory
if os.path.isabs(self.cfg['start_dir_python']):
pysrc_dir = self.cfg['start_dir_python']
else:
pysrc_dir = os.path.join(self.builddir, 'easybuild_obj', self.cfg['start_dir_python'])

change_dir(pysrc_dir)

super(CMakePythonPackage, self).install_step()

def make_module_extra(self):
"""Add extra Python package module parameters"""
return PythonPackage.make_module_extra(self)
def post_install_step(self):
"""Reset working directory before post-installation commands"""
change_dir(os.path.join(self.builddir, 'easybuild_obj'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct if build_in_installdir is True for the CMake part, or if separate_builddir is False.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lexming friendly reminder, any updates on this?

super(CMakePythonPackage, self).post_install_step()