blob: 28af8974e72fe27328b15971b61cf3eacac7504b [file] [log] [blame]
[email protected]e041ed12009-03-10 16:43:011#!/bin/bash -e
2
[email protected]aac39c92012-02-08 18:39:533# Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]e46cdae2009-08-25 20:59:274# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
[email protected]cf1df402008-10-31 21:45:307# Script to install everything needed to build chromium (well, ideally, anyway)
[email protected]592ea8ca2008-11-03 19:47:368# See http://code.google.com/p/chromium/wiki/LinuxBuildInstructions
9# and http://code.google.com/p/chromium/wiki/LinuxBuild64Bit
[email protected]cf1df402008-10-31 21:45:3010
[email protected]1eae2bfb2010-01-26 18:17:5311usage() {
12 echo "Usage: $0 [--options]"
13 echo "Options:"
14 echo "--[no-]syms: enable or disable installation of debugging symbols"
[email protected]1eae2bfb2010-01-26 18:17:5315 echo "--[no-]lib32: enable or disable installation of 32 bit libraries"
[email protected]e2544ed42012-04-23 04:48:3116 echo "--no-prompt: silently select standard options/defaults"
[email protected]1eae2bfb2010-01-26 18:17:5317 echo "Script will prompt interactively if options not given."
18 exit 1
19}
20
21while test "$1" != ""
22do
23 case "$1" in
[email protected]ce774642011-09-12 23:21:3924 --syms) do_inst_syms=1;;
25 --no-syms) do_inst_syms=0;;
[email protected]ce774642011-09-12 23:21:3926 --lib32) do_inst_lib32=1;;
27 --no-lib32) do_inst_lib32=0;;
[email protected]e2544ed42012-04-23 04:48:3128 --no-prompt) do_default=1
29 do_quietly="-qq --assume-yes"
30 ;;
[email protected]1eae2bfb2010-01-26 18:17:5331 *) usage;;
32 esac
33 shift
34done
35
[email protected]a51551d2010-07-15 22:59:4836if ! egrep -q \
[email protected]757c2962012-03-15 19:05:1837 'Ubuntu (10\.04|10\.10|11\.04|11\.10|12\.04|lucid|maverick|natty|oneiric|precise)' \
[email protected]a51551d2010-07-15 22:59:4838 /etc/issue; then
[email protected]757c2962012-03-15 19:05:1839 echo "Only Ubuntu 10.04 (lucid) through 12.04 (precise) are currently" \
[email protected]a51551d2010-07-15 22:59:4840 "supported" >&2
[email protected]cf1df402008-10-31 21:45:3041 exit 1
42fi
[email protected]cf1df402008-10-31 21:45:3043
[email protected]e041ed12009-03-10 16:43:0144if ! uname -m | egrep -q "i686|x86_64"; then
45 echo "Only x86 architectures are currently supported" >&2
46 exit
47fi
48
49if [ "x$(id -u)" != x0 ]; then
50 echo "Running as non-root user."
51 echo "You might have to enter your password one or more times for 'sudo'."
[email protected]8ada8c52009-03-10 21:53:0852 echo
[email protected]e041ed12009-03-10 16:43:0153fi
54
[email protected]fdc6bf52010-06-07 22:01:5755# Packages needed for chromeos only
[email protected]e8626b92012-04-20 18:06:1856chromeos_dev_list="libbluetooth-dev libpulse-dev"
[email protected]fdc6bf52010-06-07 22:01:5757
[email protected]e041ed12009-03-10 16:43:0158# Packages need for development
[email protected]041d14a2011-12-13 01:42:4859dev_list="apache2.2-bin bison curl elfutils fakeroot flex g++ gperf
60 language-pack-fr libapache2-mod-php5 libasound2-dev libbz2-dev
61 libcairo2-dev libcups2-dev libcurl4-gnutls-dev libdbus-glib-1-dev
62 libelf-dev libgconf2-dev libgl1-mesa-dev libglib2.0-dev
[email protected]b11411c2012-03-21 22:09:4163 libglu1-mesa-dev libgnome-keyring-dev libgtk2.0-dev
[email protected]041d14a2011-12-13 01:42:4864 libkrb5-dev libnspr4-dev libnss3-dev libpam0g-dev libsctp-dev
[email protected]6de217b72011-12-17 03:36:3265 libsqlite3-dev libssl-dev libudev-dev libwww-perl libxslt1-dev
[email protected]757c2962012-03-15 19:05:1866 libxss-dev libxt-dev libxtst-dev mesa-common-dev patch
[email protected]6de217b72011-12-17 03:36:3267 perl php5-cgi pkg-config python python-cherrypy3 python-dev
68 python-psutil rpm ruby subversion ttf-dejavu-core ttf-indic-fonts
[email protected]52de18db2012-02-15 23:38:0769 ttf-kochi-gothic ttf-kochi-mincho ttf-thai-tlwg wdiff git-core
[email protected]9dc4bed2010-11-04 19:23:3070 $chromeos_dev_list"
[email protected]fdc6bf52010-06-07 22:01:5771
72# Run-time libraries required by chromeos only
[email protected]34799f9d2010-07-08 17:51:3373chromeos_lib_list="libpulse0 libbz2-1.0 libcurl4-gnutls-dev"
[email protected]e041ed12009-03-10 16:43:0174
75# Full list of required run-time libraries
[email protected]a9259a52011-05-21 01:05:2276lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcups2 libdbus-glib-1-2
77 libexpat1 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0
78 libgtk2.0-0 libpam0g libpango1.0-0 libpcre3 libpixman-1-0
[email protected]6de217b72011-12-17 03:36:3279 libpng12-0 libstdc++6 libsqlite3-0 libudev0 libx11-6 libxau6 libxcb1
[email protected]fd11101b2011-02-16 04:46:4680 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6 libxext6 libxfixes3
81 libxi6 libxinerama1 libxrandr2 libxrender1 libxtst6 zlib1g
[email protected]9dc4bed2010-11-04 19:23:3082 $chromeos_lib_list"
[email protected]e041ed12009-03-10 16:43:0183
84# Debugging symbols for all of the run-time libraries
[email protected]f3307aa2011-10-21 22:52:3885dbg_list="libatk1.0-dbg libc6-dbg libcairo2-dbg libdbus-glib-1-2-dbg
[email protected]1a0f64a2011-05-20 17:53:5586 libfontconfig1-dbg libglib2.0-0-dbg libgtk2.0-0-dbg
87 libpango1.0-0-dbg libpcre3-dbg libpixman-1-0-dbg
[email protected]b944e322011-05-18 20:01:3588 libsqlite3-0-dbg
[email protected]e759c4b2010-03-10 19:04:5889 libx11-6-dbg libxau6-dbg libxcb1-dbg libxcomposite1-dbg
[email protected]e041ed12009-03-10 16:43:0190 libxcursor1-dbg libxdamage1-dbg libxdmcp6-dbg libxext6-dbg
91 libxfixes3-dbg libxi6-dbg libxinerama1-dbg libxrandr2-dbg
[email protected]9dc4bed2010-11-04 19:23:3092 libxrender1-dbg libxtst6-dbg zlib1g-dbg"
[email protected]e041ed12009-03-10 16:43:0193
[email protected]31a605532011-08-23 22:27:3594# Plugin lists needed for tests.
95plugin_list="flashplugin-installer"
96
[email protected]757c2962012-03-15 19:05:1897# Some package names have changed over time
[email protected]b11411c2012-03-21 22:09:4198if apt-cache show ttf-mscorefonts-installer >/dev/null 2>&1; then
[email protected]757c2962012-03-15 19:05:1899 dev_list="${dev_list} ttf-mscorefonts-installer"
[email protected]b11411c2012-03-21 22:09:41100else
101 dev_list="${dev_list} msttcorefonts"
[email protected]757c2962012-03-15 19:05:18102fi
[email protected]b11411c2012-03-21 22:09:41103if apt-cache show libnspr4-dbg >/dev/null 2>&1; then
[email protected]1a0f64a2011-05-20 17:53:55104 dbg_list="${dbg_list} libnspr4-dbg libnss3-dbg"
105 lib_list="${lib_list} libnspr4 libnss3"
[email protected]757c2962012-03-15 19:05:18106else
107 dbg_list="${dbg_list} libnspr4-0d-dbg libnss3-1d-dbg"
108 lib_list="${lib_list} libnspr4-0d libnss3-1d"
109fi
[email protected]b11411c2012-03-21 22:09:41110if apt-cache show libjpeg-dev >/dev/null 2>&1; then
111 dev_list="${dev_list} libjpeg-dev"
112else
113 dev_list="${dev_list} libjpeg62-dev"
114fi
[email protected]757c2962012-03-15 19:05:18115
116# Some packages are only needed, if the distribution actually supports
117# installing them.
[email protected]b11411c2012-03-21 22:09:41118if apt-cache show appmenu-gtk >/dev/null 2>&1; then
[email protected]757c2962012-03-15 19:05:18119 lib_list="$lib_list appmenu-gtk"
[email protected]4da8fad2011-04-11 18:42:42120fi
121
[email protected]8ada8c52009-03-10 21:53:08122# Waits for the user to press 'Y' or 'N'. Either uppercase of lowercase is
123# accepted. Returns 0 for 'Y' and 1 for 'N'. If an optional parameter has
124# been provided to yes_no(), the function also accepts RETURN as a user input.
125# The parameter specifies the exit code that should be returned in that case.
126# The function will echo the user's selection followed by a newline character.
127# Users can abort the function by pressing CTRL-C. This will call "exit 1".
128yes_no() {
[email protected]e2544ed42012-04-23 04:48:31129 if [ 0 -ne "${do_default-0}" ] ; then
130 return $1
131 fi
[email protected]8ada8c52009-03-10 21:53:08132 local c
133 while :; do
134 c="$(trap 'stty echo -iuclc icanon 2>/dev/null' EXIT INT TERM QUIT
135 stty -echo iuclc -icanon 2>/dev/null
136 dd count=1 bs=1 2>/dev/null | od -An -tx1)"
137 case "$c" in
138 " 0a") if [ -n "$1" ]; then
139 [ $1 -eq 0 ] && echo "Y" || echo "N"
140 return $1
141 fi
142 ;;
143 " 79") echo "Y"
144 return 0
145 ;;
146 " 6e") echo "N"
147 return 1
148 ;;
149 "") echo "Aborted" >&2
150 exit 1
151 ;;
152 *) # The user pressed an unrecognized key. As we are not echoing
153 # any incorrect user input, alert the user by ringing the bell.
154 (tput bel) 2>/dev/null
155 ;;
156 esac
157 done
158}
159
[email protected]1eae2bfb2010-01-26 18:17:53160if test "$do_inst_syms" = ""
161then
162 echo "This script installs all tools and libraries needed to build Chromium."
163 echo ""
164 echo "For most of the libraries, it can also install debugging symbols, which"
165 echo "will allow you to debug code in the system libraries. Most developers"
166 echo "won't need these symbols."
167 echo -n "Do you want me to install them for you (y/N) "
168 if yes_no 1; then
169 do_inst_syms=1
170 fi
171fi
172if test "$do_inst_syms" = "1"; then
[email protected]8ada8c52009-03-10 21:53:08173 echo "Installing debugging symbols."
174else
175 echo "Skipping installation of debugging symbols."
176 dbg_list=
177fi
178
[email protected]e041ed12009-03-10 16:43:01179sudo apt-get update
180
181# We initially run "apt-get" with the --reinstall option and parse its output.
182# This way, we can find all the packages that need to be newly installed
183# without accidentally promoting any packages from "auto" to "manual".
184# We then re-run "apt-get" with just the list of missing packages.
185echo "Finding missing packages..."
[email protected]31a605532011-08-23 22:27:35186packages="${dev_list} ${lib_list} ${dbg_list} ${plugin_list}"
[email protected]757c2962012-03-15 19:05:18187# Intentionally leaving $packages unquoted so it's more readable.
[email protected]b6e064522009-08-10 18:47:51188echo "Packages required: " $packages
189echo
[email protected]79a9d2962009-08-06 21:10:58190new_list_cmd="sudo apt-get install --reinstall $(echo $packages)"
[email protected]b62f11e72010-05-03 17:20:45191if new_list="$(yes n | LANG=C $new_list_cmd)"; then
[email protected]b6e064522009-08-10 18:47:51192 # We probably never hit this following line.
[email protected]79a9d2962009-08-06 21:10:58193 echo "No missing packages, and the packages are up-to-date."
[email protected]b62f11e72010-05-03 17:20:45194elif [ $? -eq 1 ]; then
[email protected]79a9d2962009-08-06 21:10:58195 # We expect apt-get to have exit status of 1.
[email protected]757c2962012-03-15 19:05:18196 # This indicates that we cancelled the install with "yes n|".
[email protected]b6e064522009-08-10 18:47:51197 new_list=$(echo "$new_list" |
[email protected]79a9d2962009-08-06 21:10:58198 sed -e '1,/The following NEW packages will be installed:/d;s/^ //;t;d')
[email protected]b6e064522009-08-10 18:47:51199 new_list=$(echo "$new_list" | sed 's/ *$//')
200 if [ -z "$new_list" ] ; then
201 echo "No missing packages, and the packages are up-to-date."
202 else
203 echo "Installing missing packages: $new_list."
[email protected]e2544ed42012-04-23 04:48:31204 sudo apt-get install ${do_quietly-} ${new_list}
[email protected]b6e064522009-08-10 18:47:51205 fi
206 echo
[email protected]79a9d2962009-08-06 21:10:58207else
208 # An apt-get exit status of 100 indicates that a real error has occurred.
[email protected]e041ed12009-03-10 16:43:01209
[email protected]79a9d2962009-08-06 21:10:58210 # I am intentionally leaving out the '"'s around new_list_cmd,
211 # as this makes it easier to cut and paste the output
[email protected]79a9d2962009-08-06 21:10:58212 echo "The following command failed: " ${new_list_cmd}
213 echo
214 echo "It produces the following output:"
215 yes n | $new_list_cmd || true
216 echo
217 echo "You will have to install the above packages yourself."
218 echo
219 exit 100
220fi
[email protected]e041ed12009-03-10 16:43:01221
222# Install 32bit backwards compatibility support for 64bit systems
[email protected]b6e064522009-08-10 18:47:51223if [ "$(uname -m)" = "x86_64" ]; then
[email protected]1eae2bfb2010-01-26 18:17:53224 if test "$do_inst_lib32" = ""
225 then
[email protected]e76a3632012-03-15 20:56:27226 echo "We no longer recommend that you use this script to install"
227 echo "32bit libraries on a 64bit system. Instead, consider using"
228 echo "the install-chroot.sh script to help you set up a 32bit"
229 echo "environment for building and testing 32bit versions of Chrome."
[email protected]1eae2bfb2010-01-26 18:17:53230 echo
[email protected]e76a3632012-03-15 20:56:27231 echo "If you nonetheless want to try installing 32bit libraries"
232 echo "directly, you can do so by explicitly passing the --lib32"
[email protected]472f5e192012-03-16 00:02:20233 echo "option to install-build-deps.sh."
[email protected]1eae2bfb2010-01-26 18:17:53234 fi
235 if test "$do_inst_lib32" != "1"
236 then
[email protected]8ada8c52009-03-10 21:53:08237 echo "Exiting without installing any 32bit libraries."
238 exit 0
239 fi
[email protected]b62f11e72010-05-03 17:20:45240
[email protected]e76a3632012-03-15 20:56:27241 echo "N.B. the code for installing 32bit libraries on a 64bit"
242 echo " system is no longer actively maintained and might"
243 echo " not work with modern versions of Ubuntu or Debian."
244 echo
245
[email protected]b62f11e72010-05-03 17:20:45246 # Standard 32bit compatibility libraries
247 echo "First, installing the limited existing 32-bit support..."
[email protected]7cf14b372011-12-08 18:32:52248 cmp_list="ia32-libs lib32asound2-dev lib32stdc++6 lib32z1
[email protected]b62f11e72010-05-03 17:20:45249 lib32z1-dev libc6-dev-i386 libc6-i386 g++-multilib"
[email protected]7cf14b372011-12-08 18:32:52250 if [ -n "`apt-cache search lib32readline-gplv2-dev 2>/dev/null`" ]; then
251 cmp_list="${cmp_list} lib32readline-gplv2-dev"
252 else
253 cmp_list="${cmp_list} lib32readline5-dev"
254 fi
[email protected]221569d32012-05-20 04:55:48255 sudo apt-get install ${do_quietly-} $cmp_list
[email protected]b62f11e72010-05-03 17:20:45256
[email protected]e041ed12009-03-10 16:43:01257 tmp=/tmp/install-32bit.$$
258 trap 'rm -rf "${tmp}"' EXIT INT TERM QUIT
259 mkdir -p "${tmp}/apt/lists/partial" "${tmp}/cache" "${tmp}/partial"
260 touch "${tmp}/status"
261
262 [ -r /etc/apt/apt.conf ] && cp /etc/apt/apt.conf "${tmp}/apt/"
[email protected]b6e064522009-08-10 18:47:51263 cat >>"${tmp}/apt/apt.conf" <<EOF
[email protected]79a9d2962009-08-06 21:10:58264 Apt::Architecture "i386";
265 Dir::Cache "${tmp}/cache";
266 Dir::Cache::Archives "${tmp}/";
267 Dir::State::Lists "${tmp}/apt/lists/";
268 Dir::State::status "${tmp}/status";
[email protected]b6e064522009-08-10 18:47:51269EOF
[email protected]1bf2ac972009-06-30 23:57:48270
[email protected]e041ed12009-03-10 16:43:01271 # Download 32bit packages
272 echo "Computing list of available 32bit packages..."
[email protected]a81e44e12010-05-17 21:16:53273 sudo apt-get -c="${tmp}/apt/apt.conf" update
[email protected]e041ed12009-03-10 16:43:01274
275 echo "Downloading available 32bit packages..."
[email protected]a81e44e12010-05-17 21:16:53276 sudo apt-get -c="${tmp}/apt/apt.conf" \
277 --yes --download-only --force-yes --reinstall install \
[email protected]e041ed12009-03-10 16:43:01278 ${lib_list} ${dbg_list}
279
280 # Open packages, remove everything that is not a library, move the
281 # library to a lib32 directory and package everything as a *.deb file.
282 echo "Repackaging and installing 32bit packages for use on 64bit systems..."
283 for i in ${lib_list} ${dbg_list}; do
284 orig="$(echo "${tmp}/${i}"_*_i386.deb)"
285 compat="$(echo "${orig}" |
286 sed -e 's,\(_[^_/]*_\)i386\(.deb\),-ia32\1amd64\2,')"
287 rm -rf "${tmp}/staging"
288 msg="$(fakeroot -u sh -exc '
289 # Unpack 32bit Debian archive
290 umask 022
291 mkdir -p "'"${tmp}"'/staging/dpkg/DEBIAN"
292 cd "'"${tmp}"'/staging"
293 ar x "'${orig}'"
294 tar zCfx dpkg data.tar.gz
295 tar zCfx dpkg/DEBIAN control.tar.gz
296
[email protected]34799f9d2010-07-08 17:51:33297 # Create a posix extended regular expression fragment that will
298 # recognize the includes which have changed. Should be rare,
299 # will almost always be empty.
300 includes=`sed -n -e "s/^[0-9a-z]* //g" \
301 -e "\,usr/include/,p" dpkg/DEBIAN/md5sums |
302 xargs -n 1 -I FILE /bin/sh -c \
303 "cmp -s dpkg/FILE /FILE || echo FILE" |
304 tr "\n" "|" |
305 sed -e "s,|$,,"`
[email protected]e041ed12009-03-10 16:43:01306
[email protected]34799f9d2010-07-08 17:51:33307 # If empty, set it to not match anything.
308 test -z "$includes" && includes="^//"
309
310 # Turn the conflicts into an extended RE for removal from the
311 # Provides line.
312 conflicts=`sed -n -e "/Conflicts/s/Conflicts: *//;T;s/, */|/g;p" \
313 dpkg/DEBIAN/control`
314
315 # Rename package, change architecture, remove conflicts and dependencies
316 sed -r -i \
317 -e "/Package/s/$/-ia32/" \
318 -e "/Architecture/s/:.*$/: amd64/" \
319 -e "/Depends/s/:.*/: ia32-libs/" \
320 -e "/Provides/s/($conflicts)(, *)?//g;T1;s/, *$//;:1" \
321 -e "/Recommends/d" \
322 -e "/Conflicts/d" \
323 dpkg/DEBIAN/control
324
325 # Only keep files that live in "lib" directories or the includes
326 # that have changed.
327 sed -r -i \
328 -e "/\/lib64\//d" -e "/\/.?bin\//d" \
329 -e "\,$includes,s,[ /]include/,&32/,g;s,include/32/,include32/,g" \
330 -e "s, lib/, lib32/,g" \
331 -e "s,/lib/,/lib32/,g" \
332 -e "t;d" \
333 -e "\,^/usr/lib32/debug\(.*/lib32\),s,^/usr/lib32/debug,/usr/lib/debug," \
334 dpkg/DEBIAN/md5sums
[email protected]e041ed12009-03-10 16:43:01335
336 # Re-run ldconfig after installation/removal
337 { echo "#!/bin/sh"; echo "[ \"x\$1\" = xconfigure ]&&ldconfig||:"; } \
338 >dpkg/DEBIAN/postinst
339 { echo "#!/bin/sh"; echo "[ \"x\$1\" = xremove ]&&ldconfig||:"; } \
340 >dpkg/DEBIAN/postrm
341 chmod 755 dpkg/DEBIAN/postinst dpkg/DEBIAN/postrm
342
343 # Remove any other control files
344 find dpkg/DEBIAN -mindepth 1 "(" -name control -o -name md5sums -o \
345 -name postinst -o -name postrm ")" -o -print |
346 xargs -r rm -rf
347
[email protected]34799f9d2010-07-08 17:51:33348 # Remove any files/dirs that live outside of "lib" directories,
349 # or are not in our list of changed includes.
350 find dpkg -mindepth 1 -regextype posix-extended \
351 "(" -name DEBIAN -o -name lib -o -regex "dpkg/($includes)" ")" \
352 -prune -o -print | tac |
353 xargs -r -n 1 sh -c "rm \$0 2>/dev/null || rmdir \$0 2>/dev/null || : "
[email protected]e041ed12009-03-10 16:43:01354 find dpkg -name lib64 -o -name bin -o -name "?bin" |
355 tac | xargs -r rm -rf
356
[email protected]34799f9d2010-07-08 17:51:33357 # Remove any symbolic links that were broken by the above steps.
358 find -L dpkg -type l -print | tac | xargs -r rm -rf
359
[email protected]e041ed12009-03-10 16:43:01360 # Rename lib to lib32, but keep debug symbols in /usr/lib/debug/usr/lib32
361 # That is where gdb looks for them.
362 find dpkg -type d -o -path "*/lib/*" -print |
363 xargs -r -n 1 sh -c "
364 i=\$(echo \"\${0}\" |
365 sed -e s,/lib/,/lib32/,g \
366 -e s,/usr/lib32/debug\\\\\(.*/lib32\\\\\),/usr/lib/debug\\\\1,);
367 mkdir -p \"\${i%/*}\";
368 mv \"\${0}\" \"\${i}\""
369
[email protected]34799f9d2010-07-08 17:51:33370 # Rename include to include32.
371 [ -d "dpkg/usr/include" ] && mv "dpkg/usr/include" "dpkg/usr/include32"
372
[email protected]e041ed12009-03-10 16:43:01373 # Prune any empty directories
374 find dpkg -type d | tac | xargs -r -n 1 rmdir 2>/dev/null || :
375
376 # Create our own Debian package
377 cd ..
378 dpkg --build staging/dpkg .' 2>&1)"
379 compat="$(eval echo $(echo "${compat}" |
380 sed -e 's,_[^_/]*_amd64.deb,_*_amd64.deb,'))"
381 [ -r "${compat}" ] || {
382 echo "${msg}" >&2
383 echo "Failed to build new Debian archive!" >&2
384 exit 1
385 }
386
387 msg="$(sudo dpkg -i "${compat}" 2>&1)" && {
388 echo "Installed ${compat##*/}"
389 } || {
390 # echo "${msg}" >&2
391 echo "Skipped ${compat##*/}"
392 }
393 done
394
395 # Add symbolic links for developing 32bit code
396 echo "Adding missing symbolic links, enabling 32bit code development..."
397 for i in $(find /lib32 /usr/lib32 -maxdepth 1 -name \*.so.\* |
398 sed -e 's/[.]so[.][0-9].*/.so/' |
399 sort -u); do
400 [ "x${i##*/}" = "xld-linux.so" ] && continue
401 [ -r "$i" ] && continue
402 j="$(ls "$i."* | sed -e 's/.*[.]so[.]\([^.]*\)$/\1/;t;d' |
403 sort -n | tail -n 1)"
404 [ -r "$i.$j" ] || continue
405 sudo ln -s "${i##*/}.$j" "$i"
406 done
407fi