Skip to content

Commit 4d9f077

Browse files
committed
use new ModEnvVarType.STRICT_PATH_WITH_FILES for CMAKE_LIBRARY_PATH to avoid spurious default paths injected into generated module files
1 parent 3a82615 commit 4d9f077

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

easybuild/framework/easyblock.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,6 +1770,12 @@ def expand_module_search_path(self, search_path, path_type=ModEnvVarType.PATH_WI
17701770
- PATH_WITH_FILES: must contain at least one file in them (default)
17711771
- PATH_WITH_TOP_FILES: increase stricness to require files in top level directory
17721772
"""
1773+
populated_path_types = (
1774+
ModEnvVarType.PATH_WITH_FILES,
1775+
ModEnvVarType.PATH_WITH_TOP_FILES,
1776+
ModEnvVarType.STRICT_PATH_WITH_FILES,
1777+
)
1778+
17731779
if os.path.isabs(search_path):
17741780
abs_glob = search_path
17751781
else:
@@ -1780,10 +1786,17 @@ def expand_module_search_path(self, search_path, path_type=ModEnvVarType.PATH_WI
17801786

17811787
retained_search_paths = []
17821788
for abs_path in exp_search_paths:
1783-
check_dir_files = path_type in (ModEnvVarType.PATH_WITH_FILES, ModEnvVarType.PATH_WITH_TOP_FILES)
1784-
if os.path.isdir(abs_path) and check_dir_files:
1789+
# avoid going through symlink for strict path types
1790+
if path_type is ModEnvVarType.STRICT_PATH_WITH_FILES and abs_path != os.path.realpath(abs_path):
1791+
self.log.debug(
1792+
f"Discarded strict search path '{search_path} of type '{path_type}' that does not correspond "
1793+
f"to its real path: {abs_path}"
1794+
)
1795+
continue
1796+
1797+
if os.path.isdir(abs_path) and path_type in populated_path_types:
17851798
# only retain paths to directories that contain at least one file
1786-
recursive = path_type == ModEnvVarType.PATH_WITH_FILES
1799+
recursive = path_type in (ModEnvVarType.PATH_WITH_FILES, ModEnvVarType.STRICT_PATH_WITH_FILES)
17871800
if not dir_contains_files(abs_path, recursive=recursive):
17881801
self.log.debug("Discarded search path to empty directory: %s", abs_path)
17891802
continue

easybuild/tools/modules.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,10 @@ class ModEnvVarType(Enum):
144144
one or more files
145145
- PATH_WITH_TOP_FILES: (list of) of paths to existing directories
146146
containing one or more files in its top directory
147+
- STRICT_PATH_WITH_FILES: (list of) of paths to existing directories
148+
containing one or more files, given paths must correspond to real paths
147149
- """
148-
STRING, PATH, PATH_WITH_FILES, PATH_WITH_TOP_FILES = range(0, 4)
150+
STRING, PATH, PATH_WITH_FILES, PATH_WITH_TOP_FILES, STRICT_PATH_WITH_FILES = range(0, 5)
149151

150152

151153
class ModuleEnvironmentVariable:
@@ -239,6 +241,7 @@ def is_path(self):
239241
ModEnvVarType.PATH,
240242
ModEnvVarType.PATH_WITH_FILES,
241243
ModEnvVarType.PATH_WITH_TOP_FILES,
244+
ModEnvVarType.STRICT_PATH_WITH_FILES,
242245
]
243246
return self.type in path_like_types
244247

@@ -286,7 +289,8 @@ def __init__(self, aliases=None):
286289
self._env_vars = {}
287290
self.ACLOCAL_PATH = [os.path.join('share', 'aclocal')]
288291
self.CLASSPATH = ['*.jar']
289-
self.CMAKE_LIBRARY_PATH = ['lib64'] # only needed for installations with standalone lib64
292+
# CMAKE_LIBRARY_PATH only needed for installations outside of 'lib'
293+
self.CMAKE_LIBRARY_PATH = {'contents': ['lib64'], 'var_type': "STRICT_PATH_WITH_FILES"}
290294
self.CMAKE_PREFIX_PATH = ['']
291295
self.GI_TYPELIB_PATH = [os.path.join(x, 'girepository-*') for x in SEARCH_PATH_LIB_DIRS]
292296
self.LD_LIBRARY_PATH = SEARCH_PATH_LIB_DIRS
@@ -374,7 +378,7 @@ def _set_module_environment_variable(self, name, value):
374378
if not self.regex['env_var_name'].match(name):
375379
raise EasyBuildError(
376380
"Name of ModuleLoadEnvironment attribute does not conform to shell naming rules, "
377-
f"it must only have upper-case letters and underscores: '{name}'"
381+
f"it must only have upper-case letters, numbers and underscores: '{name}'"
378382
)
379383

380384
if not isinstance(value, dict):

test/framework/easyblock.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,16 +490,20 @@ def test_make_module_req(self):
490490
# -- No Files
491491
if get_module_syntax() == 'Tcl':
492492
self.assertFalse(re.search(r"^prepend-path\s+CMAKE_LIBRARY_PATH\s+\$root/lib64$", guess, re.M))
493+
self.assertFalse(re.search(r"^prepend-path\s+CMAKE_LIBRARY_PATH\s+\$root/lib$", guess, re.M))
493494
elif get_module_syntax() == 'Lua':
494495
self.assertNotIn('prepend_path("CMAKE_LIBRARY_PATH", pathJoin(root, "lib64"))', guess)
496+
self.assertNotIn('prepend_path("CMAKE_LIBRARY_PATH", pathJoin(root, "lib"))', guess)
495497
# -- With files
496498
write_file(os.path.join(eb.installdir, 'lib64', 'libfoo.so'), 'test')
497499
with eb.module_generator.start_module_creation():
498500
guess = eb.make_module_req()
499501
if get_module_syntax() == 'Tcl':
500502
self.assertTrue(re.search(r"^prepend-path\s+CMAKE_LIBRARY_PATH\s+\$root/lib64$", guess, re.M))
503+
self.assertFalse(re.search(r"^prepend-path\s+CMAKE_LIBRARY_PATH\s+\$root/lib$", guess, re.M))
501504
elif get_module_syntax() == 'Lua':
502505
self.assertIn('prepend_path("CMAKE_LIBRARY_PATH", pathJoin(root, "lib64"))', guess)
506+
self.assertNotIn('prepend_path("CMAKE_LIBRARY_PATH", pathJoin(root, "lib"))', guess)
503507
# -- With files in lib and lib64 symlinks to lib
504508
write_file(os.path.join(eb.installdir, 'lib', 'libfoo.so'), 'test')
505509
shutil.rmtree(os.path.join(eb.installdir, 'lib64'))
@@ -508,8 +512,10 @@ def test_make_module_req(self):
508512
guess = eb.make_module_req()
509513
if get_module_syntax() == 'Tcl':
510514
self.assertFalse(re.search(r"^prepend-path\s+CMAKE_LIBRARY_PATH\s+\$root/lib64$", guess, re.M))
515+
self.assertFalse(re.search(r"^prepend-path\s+CMAKE_LIBRARY_PATH\s+\$root/lib$", guess, re.M))
511516
elif get_module_syntax() == 'Lua':
512517
self.assertNotIn('prepend_path("CMAKE_LIBRARY_PATH", pathJoin(root, "lib64"))', guess)
518+
self.assertNotIn('prepend_path("CMAKE_LIBRARY_PATH", pathJoin(root, "lib"))', guess)
513519

514520
# With files in /lib and /lib64 symlinked to /lib there should be exactly 1 entry for (LD_)LIBRARY_PATH
515521
# pointing to /lib

0 commit comments

Comments
 (0)