Skip to content

Commit 491b7a3

Browse files
authored
Merge pull request #4858 from lexming/fix-cmake-library-path
use new `ModEnvVarType.STRICT_PATH_WITH_FILES` with `CMAKE_LIBRARY_PATH` environment variable
2 parents 6e02e34 + 8a41852 commit 491b7a3

File tree

4 files changed

+29
-8
lines changed

4 files changed

+29
-8
lines changed

easybuild/framework/easyblock.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,6 +1774,12 @@ def expand_module_search_path(self, search_path, path_type=ModEnvVarType.PATH_WI
17741774
- PATH_WITH_FILES: must contain at least one file in them (default)
17751775
- PATH_WITH_TOP_FILES: increase stricness to require files in top level directory
17761776
"""
1777+
populated_path_types = (
1778+
ModEnvVarType.PATH_WITH_FILES,
1779+
ModEnvVarType.PATH_WITH_TOP_FILES,
1780+
ModEnvVarType.STRICT_PATH_WITH_FILES,
1781+
)
1782+
17771783
if os.path.isabs(search_path):
17781784
abs_glob = search_path
17791785
else:
@@ -1784,10 +1790,17 @@ def expand_module_search_path(self, search_path, path_type=ModEnvVarType.PATH_WI
17841790

17851791
retained_search_paths = []
17861792
for abs_path in exp_search_paths:
1787-
check_dir_files = path_type in (ModEnvVarType.PATH_WITH_FILES, ModEnvVarType.PATH_WITH_TOP_FILES)
1788-
if os.path.isdir(abs_path) and check_dir_files:
1793+
# avoid going through symlink for strict path types
1794+
if path_type is ModEnvVarType.STRICT_PATH_WITH_FILES and abs_path != os.path.realpath(abs_path):
1795+
self.log.debug(
1796+
f"Discarded strict search path '{search_path} of type '{path_type}' that does not correspond "
1797+
f"to its real path: {abs_path}"
1798+
)
1799+
continue
1800+
1801+
if os.path.isdir(abs_path) and path_type in populated_path_types:
17891802
# only retain paths to directories that contain at least one file
1790-
recursive = path_type == ModEnvVarType.PATH_WITH_FILES
1803+
recursive = path_type in (ModEnvVarType.PATH_WITH_FILES, ModEnvVarType.STRICT_PATH_WITH_FILES)
17911804
if not dir_contains_files(abs_path, recursive=recursive):
17921805
self.log.debug("Discarded search path to empty directory: %s", abs_path)
17931806
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

test/framework/toy_build.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,7 +1650,6 @@ def test_toy_module_fulltxt(self):
16501650
r'',
16511651
r'conflict\("toy"\)',
16521652
r'',
1653-
r'prepend_path\("CMAKE_LIBRARY_PATH", pathJoin\(root, "lib"\)\)',
16541653
r'prepend_path\("CMAKE_PREFIX_PATH", root\)',
16551654
r'prepend_path\("LD_LIBRARY_PATH", pathJoin\(root, "lib"\)\)',
16561655
r'prepend_path\("LIBRARY_PATH", pathJoin\(root, "lib"\)\)',
@@ -1692,7 +1691,6 @@ def test_toy_module_fulltxt(self):
16921691
r'',
16931692
r'conflict toy',
16941693
r'',
1695-
r'prepend-path CMAKE_LIBRARY_PATH \$root/lib',
16961694
r'prepend-path CMAKE_PREFIX_PATH \$root',
16971695
r'prepend-path LD_LIBRARY_PATH \$root/lib',
16981696
r'prepend-path LIBRARY_PATH \$root/lib',

0 commit comments

Comments
 (0)