rump_wmd.sh revision 1.3 1 #!/bin/sh
2 #
3 # $NetBSD: rump_wmd.sh,v 1.3 2014/01/28 13:56:02 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 'l: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 shift $((${FIRSTLIB} - 2))
66 [ $# -eq 0 ] && usage
67
68 debug ()
69 {
70
71 [ ${DEBUGLEVEL} -ge ${1} ] && \
72 { lvl=$1; shift; echo DEBUG${lvl}: $* >&2; }
73 }
74
75 # filters from list
76 filter ()
77 {
78
79 filtee=$1
80 vname=$2
81 tmplist=''
82 found=false
83 for x in $(eval echo \${${vname}}); do
84 if [ "${filtee}" = "${x}" ]; then
85 found=true
86 else
87 tmplist="${tmplist} ${x}"
88 fi
89 done
90 ${found} || die \"${1}\" not found in \$${2}
91
92 eval ${vname}="\${tmplist}"
93 }
94
95 SEEDPROG='int rump_init(void); int main() { rump_init(); }'
96 CCPARAMS='-Wl,--no-as-needed -o /dev/null -x c -'
97
98 # sanity-check
99 for lib in $* ; do
100 [ "${lib#-l}" = "${lib}" -o -z "${lib#-l}" ] \
101 && die Param \"${lib}\" is not of format -llib
102 done
103
104 # starting set and available components
105 WANTEDCOMP="$*"
106 RUMPBASE='-lrump -lrumpuser'
107 CURCOMP="${WANTEDCOMP}"
108 NEEDEDCOMP=''
109 ALLCOMP=$(ls ${LIBDIR} 2>/dev/null \
110 | sed -n '/^librump.*.so$/{s/lib/-l/;s/\.so//p;}')
111 [ -z "${ALLCOMP}" ] && die No rump kernel components in \"${LIBDIR}\"
112
113 # filter out ones we'll definitely not use
114 for f in ${CURCOMP} -lrumphijack -lrumpclient; do
115 filter ${f} ALLCOMP
116 done
117
118 # put the factions first so that they'll be tried first.
119 # this is an optimization to minimize link attempts.
120 FACTIONS='-lrumpvfs -lrumpnet -lrumpdev'
121 for f in ${FACTIONS}; do
122 filter ${f} ALLCOMP
123 done
124 ALLCOMP="${FACTIONS} ${ALLCOMP}"
125
126 debug 0 Searching component combinations. This may take a while ...
127 while :; do
128 debug 1 Current components: ${CURCOMP}
129
130 IFS=' '
131 out=$(echo ${SEEDPROG} \
132 | ${CC} -L${LIBDIR} ${CCPARAMS} ${CURCOMP} ${RUMPBASE} 2>&1)
133 [ -z "${out}" ] && break
134 undef=$(echo ${out} \
135 | sed -n '/undefined reference to/{s/.*`//;s/.$//p;q;}')
136 [ -z "${undef}" ] && break
137
138 debug 1 Trying to find ${undef}
139 for attempt in ${ALLCOMP}; do
140 debug 2 Component attempt: ${attempt}
141 unset IFS
142 nowundef=$(echo ${SEEDPROG} \
143 | ${CC} -L${LIBDIR} ${CCPARAMS} \
144 ${attempt} ${CURCOMP} ${RUMPBASE} 2>&1 \
145 | sed -n '/undefined reference to/{s/.*`//;s/.$//p;}')
146 for one in ${nowundef}; do
147 [ "${one}" = "${undef}" ] && continue 2
148 done
149 CURCOMP="${attempt} ${CURCOMP}"
150 filter ${attempt} ALLCOMP
151 debug 1 Found ${undef} from ${attempt}
152 continue 2
153 done
154 die Internal error: unreachable statement
155 done
156
157 [ ! -z "${out}" ] && { echo 'ERROR:' >&2 ; echo ${out} >&2 ; exit 1 ; }
158 debug 0 Found a set
159 echo ${CURCOMP}
160 exit 0
161