1 #!/bin/sh 2 # 3 # $NetBSD: rump_wmd.sh,v 1.4 2014/01/28 13:58:25 pooka Exp $ 4 # 5 # Copyright (c) 2014 Antti Kantee <pooka (at] iki.fi> 6 # 7 # Redistribution and use in source and binary forms, with or without 8 # modification, are permitted provided that the following conditions 9 # are met: 10 # 1. Redistributions of source code must retain the above copyright 11 # notice, this list of conditions and the following disclaimer. 12 # 2. Redistributions in binary form must reproduce the above copyright 13 # notice, this list of conditions and the following disclaimer in the 14 # documentation and/or other materials provided with the distribution. 15 # 16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 # SUCH DAMAGE. 27 # 28 29 : ${CC:=cc} 30 DEBUGLEVEL=0 31 LIBDIR=/usr/lib 32 33 die () 34 { 35 36 echo $* >&2 37 exit 1 38 } 39 40 usage () 41 { 42 43 die "Usage: $0 [-hv] [-L libdir] -lrump_component [...]" 44 } 45 46 unset FIRSTLIB 47 while getopts 'hl:L:v' opt; do 48 case "${opt}" in 49 l) 50 : ${FIRSTLIB:=${OPTIND}} 51 ;; 52 L) 53 [ -z "${FIRSTLIB}" ] || usage 54 LIBDIR=${OPTARG} 55 ;; 56 v) 57 [ -z "${FIRSTLIB}" ] || usage 58 DEBUGLEVEL=$((DEBUGLEVEL + 1)) 59 ;; 60 -h|*) 61 usage 62 ;; 63 esac 64 done 65 [ -z "${FIRSTLIB}" ] && usage 66 shift $((${FIRSTLIB} - 2)) 67 [ $# -eq 0 ] && usage 68 69 debug () 70 { 71 72 [ ${DEBUGLEVEL} -ge ${1} ] && \ 73 { lvl=$1; shift; echo DEBUG${lvl}: $* >&2; } 74 } 75 76 # filters from list 77 filter () 78 { 79 80 filtee=$1 81 vname=$2 82 tmplist='' 83 found=false 84 for x in $(eval echo \${${vname}}); do 85 if [ "${filtee}" = "${x}" ]; then 86 found=true 87 else 88 tmplist="${tmplist} ${x}" 89 fi 90 done 91 ${found} || die \"${1}\" not found in \$${2} 92 93 eval ${vname}="\${tmplist}" 94 } 95 96 SEEDPROG='int rump_init(void); int main() { rump_init(); }' 97 CCPARAMS='-Wl,--no-as-needed -o /dev/null -x c -' 98 99 # sanity-check 100 for lib in $* ; do 101 [ "${lib#-l}" = "${lib}" -o -z "${lib#-l}" ] \ 102 && die Param \"${lib}\" is not of format -llib 103 done 104 105 # starting set and available components 106 WANTEDCOMP="$*" 107 RUMPBASE='-lrump -lrumpuser' 108 CURCOMP="${WANTEDCOMP}" 109 NEEDEDCOMP='' 110 ALLCOMP=$(ls ${LIBDIR} 2>/dev/null \ 111 | sed -n '/^librump.*.so$/{s/lib/-l/;s/\.so//p;}') 112 [ -z "${ALLCOMP}" ] && die No rump kernel components in \"${LIBDIR}\" 113 114 # filter out ones we'll definitely not use 115 for f in ${CURCOMP} -lrumphijack -lrumpclient; do 116 filter ${f} ALLCOMP 117 done 118 119 # put the factions first so that they'll be tried first. 120 # this is an optimization to minimize link attempts. 121 FACTIONS='-lrumpvfs -lrumpnet -lrumpdev' 122 for f in ${FACTIONS}; do 123 filter ${f} ALLCOMP 124 done 125 ALLCOMP="${FACTIONS} ${ALLCOMP}" 126 127 debug 0 Searching component combinations. This may take a while ... 128 while :; do 129 debug 1 Current components: ${CURCOMP} 130 131 IFS=' ' 132 out=$(echo ${SEEDPROG} \ 133 | ${CC} -L${LIBDIR} ${CCPARAMS} ${CURCOMP} ${RUMPBASE} 2>&1) 134 [ -z "${out}" ] && break 135 undef=$(echo ${out} \ 136 | sed -n '/undefined reference to/{s/.*`//;s/.$//p;q;}') 137 [ -z "${undef}" ] && break 138 139 debug 1 Trying to find ${undef} 140 for attempt in ${ALLCOMP}; do 141 debug 2 Component attempt: ${attempt} 142 unset IFS 143 nowundef=$(echo ${SEEDPROG} \ 144 | ${CC} -L${LIBDIR} ${CCPARAMS} \ 145 ${attempt} ${CURCOMP} ${RUMPBASE} 2>&1 \ 146 | sed -n '/undefined reference to/{s/.*`//;s/.$//p;}') 147 for one in ${nowundef}; do 148 [ "${one}" = "${undef}" ] && continue 2 149 done 150 CURCOMP="${attempt} ${CURCOMP}" 151 filter ${attempt} ALLCOMP 152 debug 1 Found ${undef} from ${attempt} 153 continue 2 154 done 155 die Internal error: unreachable statement 156 done 157 158 [ ! -z "${out}" ] && { echo 'ERROR:' >&2 ; echo ${out} >&2 ; exit 1 ; } 159 debug 0 Found a set 160 echo ${CURCOMP} 161 exit 0 162