rump_wmd.sh revision 1.4.4.2 1 #!/bin/sh
2 #
3 # $NetBSD: rump_wmd.sh,v 1.4.4.2 2014/05/22 11:42:49 yamt 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