#!/bin/bash # Copyright (c) 2015-2016 Sandro Mani # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE buildroot="$RPM_BUILD_ROOT" if [ ! -d "$buildroot" ]; then >&2 echo "Invalid buildroot" exit 1 fi # Arguments are passed to elfdeps elfdepsargs="$@" # Search for all MPI implementations: # - Search all modules which start with mpi # - For each module, store $MPI_DIR -> $MPI_COMPILER and # $MPI_COMPILER -> $MPI_LIB in assoc. array declare -A mpi_compiler_for_dir declare -A mpi_lib_for_compiler if [ -e /etc/profile.d/modules.sh ]; then . /etc/profile.d/modules.sh; # Add moduledirs in buildroot also for cases where an MPI implementation # package is being built, meaning that its module files are not yet installed IFS=':' read -ra _MODULEPATH <<< "$MODULEPATH" for i in "${!_MODULEPATH[@]}"; do _MODULEPATH[$i]=$buildroot${_MODULEPATH[$i]} done export MODULEPATH="$MODULEPATH:$(IFS=:; echo "${_MODULEPATH[*]}")" for module in $(module -t avail 2>&1 | grep "^mpi/." | sed "s/(default)$//"); do module load $module mpi_compiler_for_dir[${MPI_HOME}]=${MPI_COMPILER} mpi_compiler_for_dir[${MPI_FORTRAN_MOD_DIR}]=${MPI_COMPILER} if [ -n "${MPI_PYTHON2_SITEARCH}" ]; then mpi_compiler_for_dir[${MPI_PYTHON2_SITEARCH}]=${MPI_COMPILER} elif [ -n "${MPI_PYTHON_SITEARCH}" ]; then mpi_compiler_for_dir[${MPI_PYTHON_SITEARCH}]=${MPI_COMPILER} fi if [ -n "${MPI_PYTHON3_SITEARCH}" ]; then mpi_compiler_for_dir[${MPI_PYTHON3_SITEARCH}]=${MPI_COMPILER} fi mpi_lib_for_compiler[${MPI_COMPILER}]=${MPI_LIB} module unload $module done fi # Read file list from stdin filelist=`sed "s/[]['\"*?{}]/\\\\\&/g"` # List requires: if [ -x /usr/lib/rpm/elfdeps -a -n "$filelist" ]; then for file in $(echo $filelist | tr '[:blank:]' \\n); do # Get the default requres string from elfdeps reqs=$(echo $file | /usr/lib/rpm/elfdeps --requires $elfdepsargs) # Check whether the scanned binary is inside a know mpi binary dir mpi_comp= for mpi_dir in "${!mpi_compiler_for_dir[@]}"; do if [[ "$file" == "$buildroot$mpi_dir"* ]]; then mpi_comp="${mpi_compiler_for_dir[$mpi_dir]}" break fi done # If the scanned binary is inside an mpi dir, for each dependency, check # whether the library exists in $MPI_LIB, and if yes, append # ($MPI_COMPILER) to each requires string if [ ! -z "$mpi_comp" ]; then mpi_lib=${mpi_lib_for_compiler[$mpi_comp]} for req in $reqs; do lib=$(echo $req | grep -Eo '^.*\.so[^(]*') if [ ! -z "$lib" ] && ( [ -e "$mpi_lib/$lib" ] || [ -e "$buildroot$mpi_lib/$lib" ] ); then req="${req}($mpi_comp)" fi echo "$req" done else echo "$reqs" fi done fi