Skip to content

Commit

Permalink
Merge pull request #2661 from easybuilders/4.5.x
Browse files Browse the repository at this point in the history
release EasyBuild v4.5.2
  • Loading branch information
migueldiascosta authored Jan 24, 2022
2 parents 0a4ba87 + 2fff5b5 commit 7bea2ad
Show file tree
Hide file tree
Showing 20 changed files with 348 additions and 67 deletions.
30 changes: 29 additions & 1 deletion RELEASE_NOTES
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,35 @@ For more detailed information, please see the git log.

These release notes can also be consulted at http://easybuild.readthedocs.org/en/latest/Release_notes.html.

The latest version of easybuild-easyblocks provides 242 software-specific easyblocks and 37 generic easyblocks.
The latest version of easybuild-easyblocks provides 243 software-specific easyblocks and 37 generic easyblocks.


v4.5.2 (January 24th 2022)
--------------------------

update/bugfix release

- minor enhancements and updates, including:
- remove necessity for license for oneAPI versions (>= 2021.x) in itac easyblock (#2492)
- add CUDA support in SuiteSparse easyblock (#2627)
- use all available cores for running Perl test suite (#2637)
- add option to not copy the license file for Gurobi (#2639, #2641)
- update AOCC easyblock to support version 3.2.0 (#2643)
- don't grep for specific version in --version output of Intel compiler commands for versions 2022.x (#2644)
- add support for enabling sanity checks for specific components in the Bundle easyblock (#2649)
- update Libint easyblock for LibInt v2.7.0 which requires configuring via CMake (#2650)
- update Mathematica easyblock for version 13 (#2652)
- add sanity check command for Bazel (#2653)
- update NAMD easyblock to allow non-system csh (#2654)
- enhance CUDA easyblock to create version independent pkgconfig files (#2656)
- add util subdirectory to $PATH for WPS (#2658)
- various bug fixes, including:
- convert version numbers to stricly numerical in Siesta easyblock (#2553)
- fix shebang of scripts in Perl installation if installation prefix is too long (#2640)
- enhance IntelBase easyblock to avoid crash when $USER is not set (#2642)
- fix quotes in definition of default platform macro and enhance sanity check in GATE easyblock (#2645)
- avoid excessively long shebang line in compile script for WRF (#2648)
- fix checking of Intel Fortran compiler version in CP2K easyblock for recent toolchains (#2651)


v4.5.1 (December 13th 2021)
Expand Down
2 changes: 1 addition & 1 deletion easybuild/easyblocks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
# recent setuptools versions will *TRANSFORM* something like 'X.Y.Zdev' into 'X.Y.Z.dev0', with a warning like
# UserWarning: Normalizing '2.4.0dev' to '2.4.0.dev0'
# This causes problems further up the dependency chain...
VERSION = LooseVersion('4.5.1')
VERSION = LooseVersion('4.5.2')
UNKNOWN = 'UNKNOWN'


Expand Down
5 changes: 3 additions & 2 deletions easybuild/easyblocks/a/aocc.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def _aocc_guess_clang_version(self):
'2.3.0': '11.0.0',
'3.0.0': '12.0.0',
'3.1.0': '12.0.0',
'3.2.0': '13.0.0',
}

if self.version in map_aocc_to_clang_ver:
Expand Down Expand Up @@ -143,8 +144,8 @@ def sanity_check_step(self):
'bin/clang', 'bin/clang++', 'bin/flang', 'bin/lld', 'bin/llvm-ar', 'bin/llvm-as', 'bin/llvm-config',
'bin/llvm-link', 'bin/llvm-nm', 'bin/llvm-symbolizer', 'bin/opt', 'bin/scan-build', 'bin/scan-view',
'include/clang-c/Index.h', 'include/llvm-c/Core.h', 'lib/clang/%s/include/omp.h' % self.clangversion,
'lib/clang/%s/include/stddef.h' % self.clangversion, 'lib/libc++.%s' % shlib_ext,
'lib/libc++abi.%s' % shlib_ext, 'lib/libclang.%s' % shlib_ext, 'lib/libomp.%s' % shlib_ext,
'lib/clang/%s/include/stddef.h' % self.clangversion, 'lib/libclang.%s' % shlib_ext,
'lib/libomp.%s' % shlib_ext,
],
'dirs': ['include/llvm', 'lib/clang/%s/lib' % self.clangversion, 'lib32'],
}
Expand Down
6 changes: 5 additions & 1 deletion easybuild/easyblocks/b/bazel.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,8 @@ def sanity_check_step(self):
'files': ['bin/bazel'],
'dirs': [],
}
super(EB_Bazel, self).sanity_check_step(custom_paths=custom_paths)
custom_commands = []
if LooseVersion(self.version) >= LooseVersion('1.0'):
custom_commands.append("bazel --help")

super(EB_Bazel, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)
13 changes: 11 additions & 2 deletions easybuild/easyblocks/c/cp2k.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,16 @@ def configure_intel_based(self):
options['FCFLAGSOPT'] += ' $(INCFLAGS) -heap-arrays 64'
options['FCFLAGSOPT2'] += ' $(INCFLAGS) -heap-arrays 64'

ifortver = LooseVersion(get_software_version('ifort'))
# for recent intel toolchains (>= intel/2021a), intel-compilers is the toolchain component
ifortver = get_software_version('intel-compilers')
if ifortver is None:
# fall back to trying to determining Intel Fortran compiler version using 'ifort' as software name
ifortver = get_software_version('ifort')

if ifortver:
ifortver = LooseVersion(ifortver)
else:
raise EasyBuildError("Failed to determine Intel Fortran compiler version!")

# Required due to memory leak that occurs if high optimizations are used (from CP2K 7.1 intel-popt-makefile)
if ifortver >= LooseVersion("2018.5"):
Expand Down Expand Up @@ -511,7 +520,7 @@ def configure_intel_based(self):
raise EasyBuildError(failmsg, "v12", "v2011.8")

elif ifortver >= LooseVersion("11"):
if LooseVersion(get_software_version('ifort')) >= LooseVersion("11.1.072"):
if ifortver >= LooseVersion("11.1.072"):
self.make_instructions += "qs_vxc_atom.o: qs_vxc_atom.F\n\t$(FC) -c $(FCFLAGS2) $<\n"

else:
Expand Down
34 changes: 29 additions & 5 deletions easybuild/easyblocks/c/cuda.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
@author: Robert Mijakovic (LuxProvide S.A.)
"""
import os
import re
import stat

from distutils.version import LooseVersion
Expand All @@ -43,8 +44,8 @@
from easybuild.framework.easyconfig import CUSTOM
from easybuild.tools.build_log import EasyBuildError
from easybuild.tools.config import IGNORE
from easybuild.tools.filetools import adjust_permissions, copy_dir, patch_perl_script_autoflush
from easybuild.tools.filetools import remove_file, symlink, which, write_file
from easybuild.tools.filetools import adjust_permissions, change_dir, copy_dir, expand_glob_paths
from easybuild.tools.filetools import patch_perl_script_autoflush, remove_file, symlink, which, write_file
from easybuild.tools.run import run_cmd, run_cmd_qa
from easybuild.tools.systemtools import AARCH64, POWER, X86_64, get_cpu_architecture, get_shared_lib_ext
import easybuild.tools.environment as env
Expand Down Expand Up @@ -201,7 +202,10 @@ def install_step(self):
run_cmd("/bin/sh " + patch['path'] + " --accept-eula --silent --installdir=" + self.installdir)

def post_install_step(self):
"""Create wrappers for the specified host compilers and generate the appropriate stub symlinks"""
"""
Create wrappers for the specified host compilers, generate the appropriate stub symlinks,
and create version independent pkgconfig files
"""
def create_wrapper(wrapper_name, wrapper_comp):
"""Create for a particular compiler, with a particular name"""
wrapper_f = os.path.join(self.installdir, 'bin', wrapper_name)
Expand Down Expand Up @@ -243,6 +247,19 @@ def create_wrapper(wrapper_name, wrapper_comp):
# Also create the lib dir as a symlink
symlink('lib64', os.path.join(new_stubs_dir, 'lib'), use_abspath_source=False)

# Packages like xpra look for version independent pc files.
# See e.g. https://github.com/Xpra-org/xpra/blob/master/setup.py#L206
# Distros provide these files, so let's do it here too
pkgconfig_dir = os.path.join(self.installdir, 'pkgconfig')
if os.path.exists(pkgconfig_dir):
pc_files = expand_glob_paths([os.path.join(pkgconfig_dir, '*.pc')])
cwd = change_dir(pkgconfig_dir)
for pc_file in pc_files:
pc_file = os.path.basename(pc_file)
link = re.sub('-[0-9]*.?[0-9]*(.[0-9]*)?.pc', '.pc', pc_file)
symlink(pc_file, link, use_abspath_source=False)
change_dir(cwd)

super(EB_CUDA, self).post_install_step()

def sanity_check_step(self):
Expand All @@ -266,6 +283,12 @@ def sanity_check_step(self):
custom_paths['files'].append(os.path.join("extras", "CUPTI", "lib64", "libcupti.%s") % shlib_ext)
custom_paths['dirs'].append(os.path.join("extras", "CUPTI", "include"))

# Just a subset of files are checked, since the whole list is likely to change,
# and irrelevant in most cases anyway
if os.path.exists(os.path.join(self.installdir, 'pkgconfig')):
pc_files = ['cublas.pc', 'cudart.pc', 'cuda.pc']
custom_paths['files'].extend(os.path.join('pkgconfig', x) for x in pc_files)

super(EB_CUDA, self).sanity_check_step(custom_paths=custom_paths)

def make_module_extra(self):
Expand Down Expand Up @@ -304,10 +327,11 @@ def make_module_req_guess(self):
inc_path.append(os.path.join('nvvm', 'include'))

guesses.update({
'PATH': bin_path,
'CPATH': inc_path,
'LD_LIBRARY_PATH': lib_path,
'LIBRARY_PATH': ['lib64', os.path.join('stubs', 'lib64')],
'CPATH': inc_path,
'PATH': bin_path,
'PKG_CONFIG_PATH': ['pkgconfig'],
})

return guesses
6 changes: 4 additions & 2 deletions easybuild/easyblocks/g/gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def build_step(self):

# redefine $CFLAGS/$CXXFLAGS via options to build command ('make')
cflags = os.getenv('CFLAGS')
cxxflags = "%s -DGC_DEFAULT_PLATFORM=\\'%s\\'" % (os.getenv('CXXFLAGS'), self.cfg['default_platform'])
cxxflags = "%s -DGC_DEFAULT_PLATFORM='\\\"%s\\\"'" % (os.getenv('CXXFLAGS'), self.cfg['default_platform'])
if self.toolchain.comp_family() in [toolchain.INTELCOMP]:
# make sure GNU macros are defined by Intel compiler
cflags += " -gcc"
Expand Down Expand Up @@ -214,4 +214,6 @@ def sanity_check_step(self):
'files': [os.path.join('bin', subdir, 'Gate')] + extra_files,
'dirs': dirs,
}
super(EB_GATE, self).sanity_check_step(custom_paths=custom_paths)
custom_commands = ["gjs -h | grep 'This executable is compiled with %s as default'"
% self.cfg['default_platform']]
super(EB_GATE, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)
30 changes: 27 additions & 3 deletions easybuild/easyblocks/g/gurobi.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@
EasyBuild support for installing Gurobi, implemented as an easyblock
@author: Bob Dröge (University of Groningen)
@author: Samuel Moors (Vrije Universiteit Brussel)
"""
import os

from easybuild.easyblocks.generic.pythonpackage import det_pylibdir
from easybuild.easyblocks.generic.tarball import Tarball
from easybuild.framework.easyconfig import CUSTOM
from easybuild.tools.build_log import EasyBuildError
from easybuild.tools.filetools import copy_file
from easybuild.tools.modules import get_software_root
Expand All @@ -41,15 +43,34 @@
class EB_Gurobi(Tarball):
"""Support for installing linux64 version of Gurobi."""

@staticmethod
def extra_options(extra_vars=None):
"""Define extra options for Gurobi"""
extra = {
'copy_license_file': [True, "Copy license_file to installdir", CUSTOM],
}
return Tarball.extra_options(extra_vars=extra)

def __init__(self, *args, **kwargs):
"""Easyblock constructor, define custom class variables specific to Gurobi."""
super(EB_Gurobi, self).__init__(*args, **kwargs)

self.license_file = self.cfg['license_file']

if self.cfg['copy_license_file']:
self.license_file = os.path.join(self.installdir, 'gurobi.lic')

def install_step(self):
"""Install Gurobi and license file."""

# make sure license file is available
if self.cfg['license_file'] is None or not os.path.exists(self.cfg['license_file']):
raise EasyBuildError("No existing license file specified: %s", self.cfg['license_file'])

super(EB_Gurobi, self).install_step()

copy_file(self.cfg['license_file'], os.path.join(self.installdir, 'gurobi.lic'))
if self.cfg['copy_license_file']:
copy_file(self.cfg['license_file'], self.license_file)

if get_software_root('Python'):
run_cmd("python setup.py install --prefix=%s" % self.installdir)
Expand All @@ -61,7 +82,10 @@ def sanity_check_step(self):
'dirs': [],
}

custom_commands = ["gurobi_cl --help"]
custom_commands = [
"gurobi_cl --help",
'test -f $GRB_LICENSE_FILE',
]

if get_software_root('Python'):
custom_commands.append("python -c 'import gurobipy'")
Expand All @@ -72,7 +96,7 @@ def make_module_extra(self):
"""Custom extra module file entries for Gurobi."""
txt = super(EB_Gurobi, self).make_module_extra()
txt += self.module_generator.set_environment('GUROBI_HOME', self.installdir)
txt += self.module_generator.set_environment('GRB_LICENSE_FILE', os.path.join(self.installdir, 'gurobi.lic'))
txt += self.module_generator.set_environment('GRB_LICENSE_FILE', self.license_file)

if get_software_root('Python'):
txt += self.module_generator.prepend_paths('PYTHONPATH', det_pylibdir())
Expand Down
41 changes: 40 additions & 1 deletion easybuild/easyblocks/generic/bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@author: Kenneth Hoste (Ghent University)
@author: Pieter De Baets (Ghent University)
@author: Jens Timmerman (Ghent University)
@author: Jasper Grimm (University of York)
"""
import copy
import os
Expand Down Expand Up @@ -58,6 +59,8 @@ def extra_options(extra_vars=None):
'altversion': [None, "Software name of dependency to use to define $EBVERSION for this bundle", CUSTOM],
'default_component_specs': [{}, "Default specs to use for every component", CUSTOM],
'components': [(), "List of components to install: tuples w/ name, version and easyblock to use", CUSTOM],
'sanity_check_components': [[], "List of components for which to run sanity checks", CUSTOM],
'sanity_check_all_components': [False, "Enable sanity checks for all components", CUSTOM],
'default_easyblock': [None, "Default easyblock to use for components", CUSTOM],
})
return EasyBlock.extra_options(extra_vars)
Expand All @@ -71,6 +74,9 @@ def __init__(self, *args, **kwargs):
# list of EasyConfig instances for components
self.comp_cfgs = []

# list of EasyConfig instances of components for which to run sanity checks
self.comp_cfgs_sanity_check = []

# list of sources for bundle itself *must* be empty
if self.cfg['sources']:
raise EasyBuildError("List of sources for bundle itself must be empty, found %s", self.cfg['sources'])
Expand All @@ -83,6 +89,20 @@ def __init__(self, *args, **kwargs):
# list of checksums for patches (must be included after checksums for sources)
checksums_patches = []

if self.cfg['sanity_check_components'] and self.cfg['sanity_check_all_components']:
raise EasyBuildError("sanity_check_components and sanity_check_all_components cannot be enabled together")

# backup and reset general sanity checks from main body of ec, if component-specific sanity checks are enabled
# necessary to avoid:
# - duplicating the general sanity check across all components running sanity checks
# - general sanity checks taking precedence over those defined in a component's easyblock
self.backup_sanity_paths = self.cfg['sanity_check_paths']
self.backup_sanity_cmds = self.cfg['sanity_check_commands']
if self.cfg['sanity_check_components'] or self.cfg['sanity_check_all_components']:
# reset general sanity checks, to be restored later
self.cfg['sanity_check_paths'] = {}
self.cfg['sanity_check_commands'] = {}

for comp in self.cfg['components']:
comp_name, comp_version, comp_specs = comp[0], comp[1], {}
if len(comp) == 3:
Expand Down Expand Up @@ -178,6 +198,11 @@ def __init__(self, *args, **kwargs):

self.cfg.enable_templating = True

# restore general sanity checks if using component-specific sanity checks
if self.cfg['sanity_check_components'] or self.cfg['sanity_check_all_components']:
self.cfg['sanity_check_paths'] = self.backup_sanity_paths
self.cfg['sanity_check_commands'] = self.backup_sanity_cmds

def check_checksums(self):
"""
Check whether a SHA256 checksum is available for all sources & patches (incl. extensions).
Expand Down Expand Up @@ -264,6 +289,10 @@ def install_step(self):
# location of first unpacked source is used to determine where to apply patch(es)
comp.src[-1]['finalpath'] = comp.cfg['start_dir']

# check if sanity checks are enabled for the component
if self.cfg['sanity_check_all_components'] or comp.cfg['name'] in self.cfg['sanity_check_components']:
self.comp_cfgs_sanity_check.append(comp)

# run relevant steps
for step_name in ['patch', 'configure', 'build', 'install']:
if step_name in cfg['skipsteps']:
Expand Down Expand Up @@ -299,7 +328,8 @@ def make_module_extra(self, *args, **kwargs):

def sanity_check_step(self, *args, **kwargs):
"""
Nothing is being installed, so just being able to load the (fake) module is sufficient
If component sanity checks are enabled, run sanity checks for the desired components listed.
If nothing is being installed, just being able to load the (fake) module is sufficient
"""
if self.cfg['exts_list'] or self.cfg['sanity_check_paths'] or self.cfg['sanity_check_commands']:
super(Bundle, self).sanity_check_step(*args, **kwargs)
Expand All @@ -308,3 +338,12 @@ def sanity_check_step(self, *args, **kwargs):
fake_mod_data = self.load_fake_module(purge=True)
self.log.debug("Cleaning up after testing loading of module")
self.clean_up_fake_module(fake_mod_data)

# run sanity checks for specific components
cnt = len(self.comp_cfgs_sanity_check)
for idx, comp in enumerate(self.comp_cfgs_sanity_check):
comp_name, comp_ver = comp.cfg['name'], comp.cfg['version']
print_msg("sanity checking bundle component %s v%s (%i/%i)...", comp_name, comp_ver, idx + 1, cnt)
self.log.info("Starting sanity check step for component %s v%s", comp_name, comp_ver)

comp.run_step('sanity_check', [lambda x: x.sanity_check_step])
2 changes: 1 addition & 1 deletion easybuild/easyblocks/generic/intelbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def __init__(self, *args, **kwargs):

self.home_subdir = os.path.join(os.getenv('HOME'), 'intel')
common_tmp_dir = os.path.dirname(tempfile.gettempdir()) # common tmp directory, same across nodes
self.home_subdir_local = os.path.join(common_tmp_dir, os.getenv('USER'), 'easybuild_intel')
self.home_subdir_local = os.path.join(common_tmp_dir, os.environ.get('USER', 'nouser'), 'easybuild_intel')

self.install_components = None

Expand Down
8 changes: 7 additions & 1 deletion easybuild/easyblocks/i/intel_compilers.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,13 @@ def sanity_check_step(self):

all_compiler_cmds = classic_compiler_cmds + oneapi_compiler_cmds
custom_commands = ["which %s" % c for c in all_compiler_cmds]
custom_commands.extend("%s --version | grep %s" % (c, self.version) for c in all_compiler_cmds)

# only for 2021.x versions do all compiler commands have the expected version;
# for example: for 2022.0.1, icc has version 2021.5.0, icpx has 2022.0.0
if LooseVersion(self.version) >= LooseVersion('2022.0'):
custom_commands.extend("%s --version" % c for c in all_compiler_cmds)
else:
custom_commands.extend("%s --version | grep %s" % (c, self.version) for c in all_compiler_cmds)

super(EB_intel_minus_compilers, self).sanity_check_step(custom_paths=custom_paths,
custom_commands=custom_commands)
Expand Down
Loading

0 comments on commit 7bea2ad

Please sign in to comment.