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