Skip to content

Commit 1e60010

Browse files
authored
Add util/check_libirc.sh to check for libirc.so used in spack-stack environments (#1639)
This PR adds a utility util/check_libirc.so that checks shared libraries and executables in a spack-stack environment for links to libirc.so. The documentation adds more details on why this is needed and when/how to use it, and I added the tool to the existing GitHub actions tests. The purpose of this utility is to catch issues with spack-stack environments only. I also created a wiki page that will provide details on how to avoid linking to libirc.so in downstream applications: https://github.com/JCSDA/spack-stack/wiki/Intel-oneAPI-compilers-and-libirc.so The newly added check found libirc.so in several met binaries. I fixed that and improved the existing fix for parallel-netcdf in JCSDA/spack#543.
1 parent ee3709f commit 1e60010

8 files changed

Lines changed: 71 additions & 8 deletions

File tree

.github/workflows/ubuntu-ci-x86_64-oneapi-ifx.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ jobs:
182182
spack install --fail-fast --source --no-check-signature 2>&1 | tee log.install.oneifx-2024.2.0-buildcache.unified-env
183183
spack buildcache create -u /home/ubuntu/spack-stack/build-cache/
184184
185+
# Check for libirc.so in shared libraries (returns 1=error if found)
186+
${SPACK_STACK_DIR}/util/check_libirc.sh
187+
185188
# Remove binary cache for next round of concretization
186189
if [ "$USE_BINARY_CACHE" = true ] ; then
187190
spack mirror rm local-binary
@@ -222,6 +225,9 @@ jobs:
222225
# Check shared libraries
223226
${SPACK_STACK_DIR}/util/ldd_check.py $SPACK_ENV 2>&1 | tee log.ldd_check
224227
228+
# Check for libirc.so in shared libraries (returns 1=error if found)
229+
${SPACK_STACK_DIR}/util/check_libirc.sh
230+
225231
# Create modules
226232
spack clean -a
227233
spack module tcl refresh -y

.github/workflows/ubuntu-ci-x86_64-oneapi.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ jobs:
182182
spack install --fail-fast --source --no-check-signature 2>&1 | tee log.install.oneapi-2024.2.0-buildcache.unified-env
183183
spack buildcache create -u /home/ubuntu/spack-stack/build-cache/
184184
185+
# Check for libirc.so in shared libraries (returns 1=error if found)
186+
${SPACK_STACK_DIR}/util/check_libirc.sh
187+
185188
# Remove binary cache for next round of concretization
186189
if [ "$USE_BINARY_CACHE" = true ] ; then
187190
spack mirror rm local-binary
@@ -222,6 +225,9 @@ jobs:
222225
# Check shared libraries
223226
${SPACK_STACK_DIR}/util/ldd_check.py $SPACK_ENV 2>&1 | tee log.ldd_check
224227
228+
# Check for libirc.so in shared libraries (returns 1=error if found)
229+
${SPACK_STACK_DIR}/util/check_libirc.sh
230+
225231
# Create modules
226232
spack clean -a
227233
spack module tcl refresh -y

configs/common/packages.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,10 @@ packages:
170170
require: '@2.53.0 ~shared ~f2py'
171171
variants: '+pflogger'
172172
met:
173-
require: '@12.0.1 +python +grib2'
173+
require:
174+
- '@12.0.1'
175+
- '+python'
176+
- '+grib2'
174177
metplus:
175178
require: '@6.0.0'
176179
metis:
@@ -209,7 +212,8 @@ packages:
209212
require:
210213
- '@2.6.2'
211214
parallel-netcdf:
212-
require: '@1.12.3'
215+
require:
216+
- '@1.12.3'
213217
pflogger:
214218
require: '+mpi'
215219
pixman:

configs/common/packages_oneapi.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ packages:
2424
require: '%gcc'
2525
libbsd:
2626
require: '%gcc'
27+
met:
28+
require:
29+
- '+shared-intel'
30+
parallel-netcdf:
31+
require:
32+
- '+shared-intel'
2733
qt:
2834
require:
2935
- '%gcc'

configs/sites/tier1/atlantis/compilers.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ compilers:
8888
- llvm/20.1.5
8989
environment:
9090
append_path:
91-
LD_LIBRARY_PATH: /gpfs/neptune/spack-stack/llvm-20.1.5/lib
91+
LD_LIBRARY_PATH: /gpfs/neptune/spack-stack/llvm-20.1.5/lib:/gpfs/neptune/spack-stack/llvm-20.1.5/lib/x86_64-unknown-linux-gnu
9292
prepend_path:
9393
MODULEPATH: /gpfs/neptune/spack-stack/openmpi-5.0.6/llvm-20.1.5/modulefiles:/gpfs/neptune/spack-stack/llvm-20.1.5/modulefiles
94-
extra_rpaths: [/gpfs/neptune/spack-stack/llvm-20.1.5/lib]
94+
extra_rpaths: [/gpfs/neptune/spack-stack/llvm-20.1.5/lib, /gpfs/neptune/spack-stack/llvm-20.1.5/lib/x86_64-unknown-linux-gnu ]
9595

doc/source/Utilities.rst

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,36 @@ In any case, the identification of any duplicates will yield a return code of 1.
2424
check_permissions.sh
2525
------------------------------
2626

27-
The utility located at util/check_permissions.sh can be run inside any spack-stack environment directory intended for multiple users (i.e., on an HPC or cloud platform). It will return errors if the environment directory is inaccessible to non-owning users and groups (i.e., if o+rx not set), as well as if any directories or files have permissions that make them inaccessible to other users.
27+
The utility located at ``util/check_permissions.sh`` can be run inside any spack-stack environment directory intended for multiple users (i.e., on an HPC or cloud platform). It will return errors if the environment directory is inaccessible to non-owning users and groups (i.e., if o+rx not set), as well as if any directories or files have permissions that make them inaccessible to other users.
2828

2929
.. _LDD_Checker:
3030

3131
------------------------------
3232
ldd_check.py (Linux only)
3333
------------------------------
3434

35-
The util/ldd_check.py utility should be run for new installations to ensure that no shared library or executable that uses shared libraries is missing a shared library dependency. If the script returns a warning for a given file, this may indicate that Spack's RPATH substitution has not been properly applied. In some instances, missing library dependencies may not indicate a problem, such as a library that is intended to be found through $LD_LIBRARY_PATH after, say, a compiler or MPI environment module is loaded. Though these paths should probably also be RPATH-ified, such instances of harmless missing dependencies may be ignored with ldd_check.py's ``--ignore`` option by specifying a Python regular expression to be excluded from consideration (see example below), or can be permanently whitelisted by modifying the ``whitelist`` variable at the top of the ldd_check.py script itself (in which case please submit a PR). The script searches the 'install/' subdirectory of a given path and runs ``ldd`` on all shared objects. The base path to be search can be specified as a lone positional argument, and by default is the current directory. In practice, this should be ``$SPACK_ENV`` for the environment in question. This utility is available for Linux only.
35+
The ``util/ldd_check.py`` utility should be run for new installations to ensure that no shared library or executable that uses shared libraries is missing a shared library dependency. If the script returns a warning for a given file, this may indicate that Spack's RPATH substitution has not been properly applied. In some instances, missing library dependencies may not indicate a problem, such as a library that is intended to be found through $LD_LIBRARY_PATH after, say, a compiler or MPI environment module is loaded. Though these paths should probably also be RPATH-ified, such instances of harmless missing dependencies may be ignored with ldd_check.py's ``--ignore`` option by specifying a Python regular expression to be excluded from consideration (see example below), or can be permanently whitelisted by modifying the ``whitelist`` variable at the top of the ldd_check.py script itself (in which case please submit a PR). The script searches the 'install/' subdirectory of a given path and runs ``ldd`` on all shared objects. The base path to be search can be specified as a lone positional argument, and by default is the current directory. In practice, this should be ``$SPACK_ENV`` for the environment in question. This utility is available for Linux only.
3636

3737
.. code-block:: console
3838
39-
cd $SPACK_ENV && ../../util/ldd_check.py
39+
cd ${SPACK_ENV} && ../../util/ldd_check.py
4040
# - OR -
4141
util/ldd_check.py $SPACK_ENV --ignore '^libfoo.+' # check for missing shared dependencies, but ignore missing libfoo*
4242
43+
.. _Libirc_Checker:
44+
45+
------------------------------
46+
check_libirc.sh (Linux only)
47+
------------------------------
48+
49+
The ``util/check_libirc.sh`` utility should be run for new installations with Intel oneAPI (``icx``, ``icpx``, ``ifort`` or ``ifx``). In an active environment after a successful ``spack install``, execute the following command to check if any of the shared libraries or executables is linked to ``libirc.so``. See https://github.com/JCSDA/spack-stack/issues/1436 for some background context and why we want need to avoid ``libirc.so``. If ``libirc.so`` is linked to a shared library or executable in a spack-stack environment, please create an issue in the spack-stack GitHub repository (https://github.com/JCSDA/spack-stack/issues). For downstream applications, see the spack-stack wiki (https://github.com/JCSDA/spack-stack/wiki/Intel-oneAPI-compilers-and-libirc.so).
50+
51+
.. code-block:: console
52+
53+
cd ${SPACK_ENV} && ../../util/check_libirc.sh
54+
# - OR -
55+
cd ${SPACK_STACK_DIR} && ./check_libirc.sh
56+
4357
.. _Parallel_Install:
4458

4559
------------------------------

util/check_libirc.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env bash
2+
3+
ierror=0
4+
5+
searchfor="libirc.so"
6+
7+
echo "Checking shared libraries for ${searchfor} ..."
8+
for file in `find ${SPACK_ENV} -type f -iname '*.so*'`; do
9+
# Return code from grep is 1 if not found, 0 if found
10+
ldd $file 2>&1 | grep "${searchfor}"
11+
if [[ $? -eq 0 ]]; then
12+
echo "Found ${searchfor} linked in ${file}"
13+
ierror=1
14+
fi
15+
done
16+
17+
echo "Checking executables for ${searchfor} ..."
18+
for file in `find ${SPACK_ENV} -type f -executable`; do
19+
# Return code from grep is 1 if not found, 0 if found
20+
ldd $file 2>&1 | grep "${searchfor}"
21+
if [[ $? -eq 0 ]]; then
22+
echo "Found ${searchfor} linked in ${file}"
23+
ierror=1
24+
fi
25+
done
26+
27+
exit ${ierror}

0 commit comments

Comments
 (0)