Skip to content

Make GROMACS easyblock work with --module-only #2414

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

Merged
merged 7 commits into from
May 12, 2021
Merged
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
74 changes: 45 additions & 29 deletions easybuild/easyblocks/g/gromacs.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ def __init__(self, *args, **kwargs):
self.lib_subdir = ''
self.pre_env = ''
self.cfg['build_shared_libs'] = self.cfg.get('build_shared_libs', False)
if LooseVersion(self.version) >= LooseVersion('2019'):
# Building the gmxapi interface requires shared libraries
self.cfg['build_shared_libs'] = True
if self.cfg['build_shared_libs']:
self.libext = get_shared_lib_ext()
else:
self.libext = 'a'

def get_gromacs_arch(self):
"""Determine value of GMX_SIMD CMake flag based on optarch string.
Expand Down Expand Up @@ -269,8 +276,8 @@ def configure_step(self):
mpi_numprocs)

if LooseVersion(self.version) >= LooseVersion('2019'):
# Building the gmxapi interface requires shared libraries
self.cfg['build_shared_libs'] = True
# Building the gmxapi interface requires shared libraries,
# this is handled in the class initialisation so --module-only works
self.cfg.update('configopts', "-DGMXAPI=ON")

if LooseVersion(self.version) >= LooseVersion('2020'):
Expand Down Expand Up @@ -463,35 +470,8 @@ def install_step(self):
else:
# run 'make install' in parallel since it involves more compilation
self.cfg.update('installopts', "-j %s" % self.cfg['parallel'])

super(EB_GROMACS, self).install_step()

# the GROMACS libraries get installed in different locations (deeper subdirectory),
# depending on the platform;
# this is determined by the GNUInstallDirs CMake module;
# rather than trying to replicate the logic, we just figure out where the library was placed

if self.cfg['build_shared_libs']:
self.libext = get_shared_lib_ext()
else:
self.libext = 'a'

if LooseVersion(self.version) < LooseVersion('5.0'):
libname = 'libgmx*.%s' % self.libext
else:
libname = 'libgromacs*.%s' % self.libext

for libdir in ['lib', 'lib64']:
if os.path.exists(os.path.join(self.installdir, libdir)):
for subdir in [libdir, os.path.join(libdir, '*')]:
libpaths = glob.glob(os.path.join(self.installdir, subdir, libname))
if libpaths:
self.lib_subdir = os.path.dirname(libpaths[0])[len(self.installdir) + 1:]
self.log.info("Found lib subdirectory that contains %s: %s", libname, self.lib_subdir)
break
if not self.lib_subdir:
raise EasyBuildError("Failed to determine lib subdirectory in %s", self.installdir)

def extensions_step(self, fetch=False):
""" Custom extensions step, only handle extensions after the last iteration round"""
if self.iter_idx < self.variants_to_build - 1:
Expand All @@ -508,9 +488,42 @@ def extensions_step(self, fetch=False):
super(EB_GROMACS, self).extensions_step(fetch)
self.cfg['runtest'] = orig_runtest

def get_lib_subdir(self):
# the GROMACS libraries get installed in different locations (deeper subdirectory),
# depending on the platform;
# this is determined by the GNUInstallDirs CMake module;
# rather than trying to replicate the logic, we just figure out where the library was placed

if LooseVersion(self.version) < LooseVersion('5.0'):
libname = 'libgmx*.%s' % self.libext
else:
libname = 'libgromacs*.%s' % self.libext
lib_subdir = None
for libdir in ['lib', 'lib64']:
if os.path.exists(os.path.join(self.installdir, libdir)):
for subdir in [libdir, os.path.join(libdir, '*')]:
libpaths = glob.glob(os.path.join(self.installdir, subdir, libname))
if libpaths:
lib_subdir = os.path.dirname(libpaths[0])[len(self.installdir) + 1:]
self.log.info("Found lib subdirectory that contains %s: %s", libname, lib_subdir)
break
if not lib_subdir:
raise EasyBuildError("Failed to determine lib subdirectory in %s", self.installdir)

return lib_subdir

def make_module_req_guess(self):
"""Custom library subdirectories for GROMACS."""
guesses = super(EB_GROMACS, self).make_module_req_guess()
if not self.lib_subdir:
try:
self.lib_subdir = self.get_lib_subdir()
except EasyBuildError as error:
if build_option('force') and build_option('module_only'):
self.log.info("No lib subdirectory directory found in installation: %s", error)
self.log.info("You are forcing module creation for a non-existent installation!")
else:
raise error
guesses.update({
'LD_LIBRARY_PATH': [self.lib_subdir],
'LIBRARY_PATH': [self.lib_subdir],
Expand Down Expand Up @@ -592,6 +605,9 @@ def sanity_check_step(self):
])
bin_files.extend([b + suff for b in bins + mpi_bins for suff in suffixes])

if not self.lib_subdir:
self.lib_subdir = self.get_lib_subdir()

# pkgconfig dir not available for earlier versions, exact version to use here is unclear
if LooseVersion(self.version) >= LooseVersion('4.6'):
dirs.append(os.path.join(self.lib_subdir, 'pkgconfig'))
Expand Down