• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash -e
2
3# Copyright (c) 2012 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7# Script to install everything needed to build chromium (well, ideally, anyway)
8# See http://code.google.com/p/chromium/wiki/LinuxBuildInstructions
9# and http://code.google.com/p/chromium/wiki/LinuxBuild64Bit
10
11usage() {
12  echo "Usage: $0 [--options]"
13  echo "Options:"
14  echo "--[no-]syms: enable or disable installation of debugging symbols"
15  echo "--[no-]lib32: enable or disable installation of 32 bit libraries"
16  echo "--[no-]arm: enable or disable installation of arm cross toolchain"
17  echo "--[no-]chromeos-fonts: enable or disable installation of Chrome OS"\
18       "fonts"
19  echo "--[no-]nacl: enable or disable installation of prerequisites for"\
20       "building standalone NaCl and all its toolchains"
21  echo "--no-prompt: silently select standard options/defaults"
22  echo "--quick-check: quickly try to determine if dependencies are installed"
23  echo "               (this avoids interactive prompts and sudo commands,"
24  echo "               so might not be 100% accurate)"
25  echo "--unsupported: attempt installation even on unsupported systems"
26  echo "Script will prompt interactively if options not given."
27  exit 1
28}
29
30# Checks whether a particular package is available in the repos.
31# USAGE: $ package_exists <package name>
32package_exists() {
33  apt-cache pkgnames | grep -x "$1" > /dev/null 2>&1
34}
35
36# These default to on because (some) bots need them and it keeps things
37# simple for the bot setup if all bots just run the script in its default
38# mode.  Developers who don't want stuff they don't need installed on their
39# own workstations can pass --no-arm --no-nacl when running the script.
40do_inst_arm=1
41do_inst_nacl=1
42
43while test "$1" != ""
44do
45  case "$1" in
46  --syms)                   do_inst_syms=1;;
47  --no-syms)                do_inst_syms=0;;
48  --lib32)                  do_inst_lib32=1;;
49  --no-lib32)               do_inst_lib32=0;;
50  --arm)                    do_inst_arm=1;;
51  --no-arm)                 do_inst_arm=0;;
52  --chromeos-fonts)         do_inst_chromeos_fonts=1;;
53  --no-chromeos-fonts)      do_inst_chromeos_fonts=0;;
54  --nacl)                   do_inst_nacl=1;;
55  --no-nacl)                do_inst_nacl=0;;
56  --no-prompt)              do_default=1
57                            do_quietly="-qq --assume-yes"
58    ;;
59  --quick-check)            do_quick_check=1;;
60  --unsupported)            do_unsupported=1;;
61  *) usage;;
62  esac
63  shift
64done
65
66# Check for lsb_release command in $PATH
67if ! which lsb_release > /dev/null; then
68  echo "ERROR: lsb_release not found in \$PATH" >&2
69  exit 1;
70fi
71
72lsb_release=$(lsb_release --codename --short)
73ubuntu_codenames="(precise|quantal|raring|saucy|trusty)"
74if [ 0 -eq "${do_unsupported-0}" ] && [ 0 -eq "${do_quick_check-0}" ] ; then
75  if [[ ! $lsb_release =~ $ubuntu_codenames ]]; then
76    echo "ERROR: Only Ubuntu 12.04 (precise) through 14.04 (trusty) are"\
77        "currently supported" >&2
78    exit 1
79  fi
80
81  if ! uname -m | egrep -q "i686|x86_64"; then
82    echo "Only x86 architectures are currently supported" >&2
83    exit
84  fi
85fi
86
87if [ "x$(id -u)" != x0 ] && [ 0 -eq "${do_quick_check-0}" ]; then
88  echo "Running as non-root user."
89  echo "You might have to enter your password one or more times for 'sudo'."
90  echo
91fi
92
93# Packages needed for chromeos only
94chromeos_dev_list="libbluetooth-dev"
95
96# Packages needed for development
97dev_list="apache2.2-bin bison curl dpkg-dev elfutils devscripts fakeroot flex
98          fonts-thai-tlwg g++ git-core gperf language-pack-da language-pack-fr
99          language-pack-he language-pack-zh-hant libapache2-mod-php5
100          libasound2-dev libbrlapi-dev libbz2-dev libcairo2-dev libcap-dev
101          libcups2-dev libcurl4-gnutls-dev libdrm-dev libelf-dev libexif-dev
102          libgconf2-dev libgl1-mesa-dev libglib2.0-dev libglu1-mesa-dev
103          libgnome-keyring-dev libgtk2.0-dev libkrb5-dev libnspr4-dev
104          libnss3-dev libpam0g-dev libpci-dev libpulse-dev libsctp-dev
105          libspeechd-dev libsqlite3-dev libssl-dev libudev-dev libwww-perl
106          libxslt1-dev libxss-dev libxt-dev libxtst-dev mesa-common-dev openbox
107          patch perl php5-cgi pkg-config python python-cherrypy3 python-dev
108          python-psutil rpm ruby subversion ttf-dejavu-core ttf-indic-fonts
109          ttf-kochi-gothic ttf-kochi-mincho wdiff xfonts-mathml zip
110          $chromeos_dev_list"
111
112# 64-bit systems need a minimum set of 32-bit compat packages for the pre-built
113# NaCl binaries. These are always needed, regardless of whether or not we want
114# the full 32-bit "cross-compile" support (--lib32).
115if file /sbin/init | grep -q 'ELF 64-bit'; then
116  dev_list="${dev_list} libc6-i386 lib32gcc1 lib32stdc++6"
117fi
118
119# Run-time libraries required by chromeos only
120chromeos_lib_list="libpulse0 libbz2-1.0"
121
122# Full list of required run-time libraries
123lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcap2 libcups2 libexpat1
124          libexif12 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0
125          libgtk2.0-0 libpam0g libpango1.0-0 libpci3 libpcre3 libpixman-1-0
126          libpng12-0 libspeechd2 libstdc++6 libsqlite3-0 libx11-6
127          libxau6 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6
128          libxext6 libxfixes3 libxi6 libxinerama1 libxrandr2 libxrender1
129          libxtst6 zlib1g $chromeos_lib_list"
130
131# Debugging symbols for all of the run-time libraries
132dbg_list="libatk1.0-dbg libc6-dbg libcairo2-dbg libfontconfig1-dbg
133          libglib2.0-0-dbg libgtk2.0-0-dbg libpango1.0-0-dbg libpcre3-dbg
134          libpixman-1-0-dbg libsqlite3-0-dbg libx11-6-dbg libxau6-dbg
135          libxcb1-dbg libxcomposite1-dbg libxcursor1-dbg libxdamage1-dbg
136          libxdmcp6-dbg libxext6-dbg libxfixes3-dbg libxi6-dbg libxinerama1-dbg
137          libxrandr2-dbg libxrender1-dbg libxtst6-dbg zlib1g-dbg
138          libstdc++6-4.6-dbg"
139
140# arm cross toolchain packages needed to build chrome on armhf
141arm_list="libc6-dev-armhf-cross
142          linux-libc-dev-armhf-cross
143          g++-arm-linux-gnueabihf"
144
145# Packages to build NaCl, its toolchains, and its ports.
146nacl_list="autoconf bison cmake g++-mingw-w64-i686 gawk lib32z1-dev
147           libasound2:i386 libcap2:i386 libelf-dev:i386 libexif12:i386
148           libfontconfig1:i386 libgconf-2-4:i386 libglib2.0-0:i386 libgpm2:i386
149           libgtk2.0-0:i386 libncurses5:i386 libnss3:i386 libpango1.0-0:i386
150           libssl0.9.8:i386 libtinfo-dev libtinfo-dev:i386 libtool
151           libxcomposite1:i386 libxcursor1:i386 libxdamage1:i386 libxi6:i386
152           libxrandr2:i386 libxss1:i386 libxtst6:i386 texinfo xvfb"
153
154# Find the proper version of libgbm-dev. We can't just install libgbm-dev as
155# it depends on mesa, and only one version of mesa can exists on the system.
156# Hence we must match the same version or this entire script will fail.
157mesa_variant=""
158for variant in "-lts-quantal" "-lts-raring" "-lts-saucy"; do
159  if $(dpkg-query -Wf'${Status}' libgl1-mesa-glx${variant} | \
160       grep -q " ok installed"); then
161    mesa_variant="${variant}"
162  fi
163done
164dev_list="${dev_list} libgbm-dev${mesa_variant}"
165nacl_list="${nacl_list} libgl1-mesa-glx${mesa_variant}:i386"
166
167# Some package names have changed over time
168if package_exists ttf-mscorefonts-installer; then
169  dev_list="${dev_list} ttf-mscorefonts-installer"
170else
171  dev_list="${dev_list} msttcorefonts"
172fi
173if package_exists libnspr4-dbg; then
174  dbg_list="${dbg_list} libnspr4-dbg libnss3-dbg"
175  lib_list="${lib_list} libnspr4 libnss3"
176else
177  dbg_list="${dbg_list} libnspr4-0d-dbg libnss3-1d-dbg"
178  lib_list="${lib_list} libnspr4-0d libnss3-1d"
179fi
180if package_exists libjpeg-dev; then
181  dev_list="${dev_list} libjpeg-dev"
182else
183  dev_list="${dev_list} libjpeg62-dev"
184fi
185if package_exists libudev1; then
186  dev_list="${dev_list} libudev1"
187  nacl_list="${nacl_list} libudev1:i386"
188else
189  dev_list="${dev_list} libudev0"
190  nacl_list="${nacl_list} libudev0:i386"
191fi
192if package_exists libbrlapi0.6; then
193  dev_list="${dev_list} libbrlapi0.6"
194else
195  dev_list="${dev_list} libbrlapi0.5"
196fi
197
198
199# Some packages are only needed if the distribution actually supports
200# installing them.
201if package_exists appmenu-gtk; then
202  lib_list="$lib_list appmenu-gtk"
203fi
204
205# Waits for the user to press 'Y' or 'N'. Either uppercase of lowercase is
206# accepted. Returns 0 for 'Y' and 1 for 'N'. If an optional parameter has
207# been provided to yes_no(), the function also accepts RETURN as a user input.
208# The parameter specifies the exit code that should be returned in that case.
209# The function will echo the user's selection followed by a newline character.
210# Users can abort the function by pressing CTRL-C. This will call "exit 1".
211yes_no() {
212  if [ 0 -ne "${do_default-0}" ] ; then
213    [ $1 -eq 0 ] && echo "Y" || echo "N"
214    return $1
215  fi
216  local c
217  while :; do
218    c="$(trap 'stty echo -iuclc icanon 2>/dev/null' EXIT INT TERM QUIT
219         stty -echo iuclc -icanon 2>/dev/null
220         dd count=1 bs=1 2>/dev/null | od -An -tx1)"
221    case "$c" in
222      " 0a") if [ -n "$1" ]; then
223               [ $1 -eq 0 ] && echo "Y" || echo "N"
224               return $1
225             fi
226             ;;
227      " 79") echo "Y"
228             return 0
229             ;;
230      " 6e") echo "N"
231             return 1
232             ;;
233      "")    echo "Aborted" >&2
234             exit 1
235             ;;
236      *)     # The user pressed an unrecognized key. As we are not echoing
237             # any incorrect user input, alert the user by ringing the bell.
238             (tput bel) 2>/dev/null
239             ;;
240    esac
241  done
242}
243
244if test "$do_inst_syms" = "" && test 0 -eq ${do_quick_check-0}
245then
246  echo "This script installs all tools and libraries needed to build Chromium."
247  echo ""
248  echo "For most of the libraries, it can also install debugging symbols, which"
249  echo "will allow you to debug code in the system libraries. Most developers"
250  echo "won't need these symbols."
251  echo -n "Do you want me to install them for you (y/N) "
252  if yes_no 1; then
253    do_inst_syms=1
254  fi
255fi
256if test "$do_inst_syms" = "1"; then
257  echo "Including debugging symbols."
258else
259  echo "Skipping debugging symbols."
260  dbg_list=
261fi
262
263# When cross building for arm on 64-bit systems the host binaries
264# that are part of v8 need to be compiled with -m32 which means
265# that basic multilib support is needed.
266if file /sbin/init | grep -q 'ELF 64-bit'; then
267  if [ "$lsb_release" = "trusty" ]; then
268    # gcc-multilib conflicts with the arm cross compiler in trusty but
269    # g++-4.8-multilib gives us the 32-bit support that we need.
270    arm_list="$arm_list g++-4.8-multilib"
271  else
272    arm_list="$arm_list g++-multilib"
273  fi
274fi
275
276if test "$do_inst_arm" = "1" ; then
277  echo "Including ARM cross toolchain."
278else
279  echo "Skipping ARM cross toolchain."
280  arm_list=
281fi
282
283if test "$do_inst_nacl" = "1"; then
284  echo "Including NaCl, NaCl toolchain, NaCl ports dependencies."
285else
286  echo "Skipping NaCl, NaCl toolchain, NaCl ports dependencies."
287  nacl_list=
288fi
289
290packages="$(
291  echo "${dev_list} ${lib_list} ${dbg_list} ${arm_list} ${nacl_list}" |
292  tr " " "\n" | sort -u | tr "\n" " "
293)"
294
295if [ 1 -eq "${do_quick_check-0}" ] ; then
296  failed_check="$(dpkg-query -W -f '${PackageSpec}:${Status}\n' \
297    ${packages} 2>&1 | grep -v "ok installed" || :)"
298  if [ -n "${failed_check}" ]; then
299    echo
300    nomatch="$(echo "${failed_check}" | \
301      sed -e "s/^No packages found matching \(.*\).$/\1/;t;d")"
302    missing="$(echo "${failed_check}" | \
303      sed -e "/^No packages found matching/d;s/^\(.*\):.*$/\1/")"
304    if [ "$nomatch" ]; then
305      # Distinguish between packages that actually aren't available to the
306      # system (i.e. not in any repo) and packages that just aren't known to
307      # dpkg (i.e. managed by apt).
308      unknown=""
309      for p in ${nomatch}; do
310        if apt-cache show ${p} > /dev/null 2>&1; then
311          missing="${p}\n${missing}"
312        else
313          unknown="${p}\n${unknown}"
314        fi
315      done
316      if [ -n "${unknown}" ]; then
317        echo "WARNING: The following packages are unknown to your system"
318        echo "(maybe missing a repo or need to 'sudo apt-get update'):"
319        echo -e "${unknown}" | sed -e "s/^/  /"
320      fi
321    fi
322    if [ -n "${missing}" ]; then
323      echo "WARNING: The following packages are not installed:"
324      echo -e "${missing}" | sed -e "s/^/  /"
325    fi
326    exit 1
327  fi
328  exit 0
329fi
330
331sudo apt-get update
332
333# We initially run "apt-get" with the --reinstall option and parse its output.
334# This way, we can find all the packages that need to be newly installed
335# without accidentally promoting any packages from "auto" to "manual".
336# We then re-run "apt-get" with just the list of missing packages.
337echo "Finding missing packages..."
338# Intentionally leaving $packages unquoted so it's more readable.
339echo "Packages required: " $packages
340echo
341new_list_cmd="sudo apt-get install --reinstall $(echo $packages)"
342if new_list="$(yes n | LANGUAGE=en LANG=C $new_list_cmd)"; then
343  # We probably never hit this following line.
344  echo "No missing packages, and the packages are up-to-date."
345elif [ $? -eq 1 ]; then
346  # We expect apt-get to have exit status of 1.
347  # This indicates that we cancelled the install with "yes n|".
348  new_list=$(echo "$new_list" |
349    sed -e '1,/The following NEW packages will be installed:/d;s/^  //;t;d')
350  new_list=$(echo "$new_list" | sed 's/ *$//')
351  if [ -z "$new_list" ] ; then
352    echo "No missing packages, and the packages are up-to-date."
353  else
354    echo "Installing missing packages: $new_list."
355    sudo apt-get install ${do_quietly-} ${new_list}
356  fi
357  echo
358else
359  # An apt-get exit status of 100 indicates that a real error has occurred.
360
361  # I am intentionally leaving out the '"'s around new_list_cmd,
362  # as this makes it easier to cut and paste the output
363  echo "The following command failed: " ${new_list_cmd}
364  echo
365  echo "It produces the following output:"
366  yes n | $new_list_cmd || true
367  echo
368  echo "You will have to install the above packages yourself."
369  echo
370  exit 100
371fi
372
373# Install the Chrome OS default fonts. This must go after running
374# apt-get, since install-chromeos-fonts depends on curl.
375if test "$do_inst_chromeos_fonts" != "0"; then
376  echo
377  echo "Installing Chrome OS fonts."
378  dir=`echo $0 | sed -r -e 's/\/[^/]+$//'`
379  if ! sudo $dir/linux/install-chromeos-fonts.py; then
380    echo "ERROR: The installation of the Chrome OS default fonts failed."
381    if [ `stat -f -c %T $dir` == "nfs" ]; then
382      echo "The reason is that your repo is installed on a remote file system."
383    else
384      echo "This is expected if your repo is installed on a remote file system."
385    fi
386    echo "It is recommended to install your repo on a local file system."
387    echo "You can skip the installation of the Chrome OS default founts with"
388    echo "the command line option: --no-chromeos-fonts."
389    exit 1
390  fi
391else
392  echo "Skipping installation of Chrome OS fonts."
393fi
394
395if test "$do_inst_nacl" = "1"; then
396  echo "Installing symbolic links for NaCl."
397  if [ ! -r /usr/lib/i386-linux-gnu/libcrypto.so ]; then
398    sudo ln -fs libcrypto.so.0.9.8 /usr/lib/i386-linux-gnu/libcrypto.so
399  fi
400  if [ ! -r /usr/lib/i386-linux-gnu/libssl.so ]; then
401    sudo ln -fs libssl.so.0.9.8 /usr/lib/i386-linux-gnu/libssl.so
402  fi
403else
404  echo "Skipping symbolic links for NaCl."
405fi
406
407# Install 32bit backwards compatibility support for 64bit systems
408if file /sbin/init | grep -q 'ELF 64-bit'; then
409  if test "$do_inst_lib32" != "1"
410  then
411    echo "NOTE: If you were expecting the option to install 32bit libs,"
412    echo "please run with the --lib32 flag."
413    echo
414    echo "Installation complete."
415    exit 0
416  else
417    # This conditional statement has been added to deprecate and eventually
418    # remove support for 32bit libraries on 64bit systems. But for the time
419    # being, we still have to support a few legacy systems (e.g. bots), where
420    # this feature is needed.
421    # We only even give the user the option to install these libraries, if
422    # they explicitly requested doing so by setting the --lib32 command line
423    # flag.
424    # And even then, we interactively ask them one more time whether they are
425    # absolutely sure.
426    # In order for that to work, we must reset the ${do_inst_lib32} variable.
427    # There are other ways to achieve the same goal. But resetting the
428    # variable is the best way to document the intended behavior -- and to
429    # allow us to gradually deprecate and then remove the obsolete code.
430    if test "${do_default-0}" -ne 1; then
431      do_inst_lib32=
432    fi
433  fi
434
435  echo "WARNING"
436  echo
437  echo "We no longer recommend that you use this script to install"
438  echo "32bit libraries on a 64bit system. Instead, consider using the"
439  echo "install-chroot.sh script to help you set up a 32bit environment"
440  echo "for building and testing 32bit versions of Chrome."
441  echo
442  echo "The code for installing 32bit libraries on a 64bit system is"
443  echo "unmaintained and might not work with modern versions of Ubuntu"
444  echo "or Debian."
445  if test "$do_inst_lib32" != "" ; then
446    echo
447    echo -n "Are you sure you want to proceed (y/N) "
448    if yes_no 1; then
449      do_inst_lib32=1
450    fi
451  fi
452  if test "$do_inst_lib32" != "1"
453  then
454    exit 0
455  fi
456
457  # Standard 32bit compatibility libraries
458  echo "First, installing the limited existing 32-bit support..."
459  cmp_list="ia32-libs lib32asound2-dev lib32stdc++6 lib32z1
460            lib32z1-dev libc6-dev-i386 libc6-i386 g++-multilib"
461  if [ -n "`apt-cache search lib32readline-gplv2-dev 2>/dev/null`" ]; then
462    cmp_list="${cmp_list} lib32readline-gplv2-dev"
463  else
464    cmp_list="${cmp_list} lib32readline5-dev"
465  fi
466  sudo apt-get install ${do_quietly-} $cmp_list
467
468  tmp=/tmp/install-32bit.$$
469  trap 'rm -rf "${tmp}"' EXIT INT TERM QUIT
470  mkdir -p "${tmp}/apt/lists/partial" "${tmp}/cache" "${tmp}/partial"
471  touch "${tmp}/status"
472
473  [ -r /etc/apt/apt.conf ] && cp /etc/apt/apt.conf "${tmp}/apt/"
474  cat >>"${tmp}/apt/apt.conf" <<EOF
475        Apt::Architecture "i386";
476        Dir::Cache "${tmp}/cache";
477        Dir::Cache::Archives "${tmp}/";
478        Dir::State::Lists "${tmp}/apt/lists/";
479        Dir::State::status "${tmp}/status";
480EOF
481
482  # Download 32bit packages
483  echo "Computing list of available 32bit packages..."
484  sudo apt-get -c="${tmp}/apt/apt.conf" update
485
486  echo "Downloading available 32bit packages..."
487  sudo apt-get -c="${tmp}/apt/apt.conf" \
488          --yes --download-only --force-yes --reinstall install \
489          ${lib_list} ${dbg_list}
490
491  # Open packages, remove everything that is not a library, move the
492  # library to a lib32 directory and package everything as a *.deb file.
493  echo "Repackaging and installing 32bit packages for use on 64bit systems..."
494  for i in ${lib_list} ${dbg_list}; do
495    orig="$(echo "${tmp}/${i}"_*_i386.deb)"
496    compat="$(echo "${orig}" |
497              sed -e 's,\(_[^_/]*_\)i386\(.deb\),-ia32\1amd64\2,')"
498    rm -rf "${tmp}/staging"
499    msg="$(fakeroot -u sh -exc '
500      # Unpack 32bit Debian archive
501      umask 022
502      mkdir -p "'"${tmp}"'/staging/dpkg/DEBIAN"
503      cd "'"${tmp}"'/staging"
504      ar x "'${orig}'"
505      tar Cfx dpkg data.tar*
506      tar zCfx dpkg/DEBIAN control.tar.gz
507
508      # Create a posix extended regular expression fragment that will
509      # recognize the includes which have changed. Should be rare,
510      # will almost always be empty.
511      includes=`sed -n -e "s/^[0-9a-z]*  //g" \
512                       -e "\,usr/include/,p" dpkg/DEBIAN/md5sums |
513                  xargs -n 1 -I FILE /bin/sh -c \
514                    "cmp -s dpkg/FILE /FILE || echo FILE" |
515                  tr "\n" "|" |
516                  sed -e "s,|$,,"`
517
518      # If empty, set it to not match anything.
519      test -z "$includes" && includes="^//"
520
521      # Turn the conflicts into an extended RE for removal from the
522      # Provides line.
523      conflicts=`sed -n -e "/Conflicts/s/Conflicts: *//;T;s/, */|/g;p" \
524                   dpkg/DEBIAN/control`
525
526      # Rename package, change architecture, remove conflicts and dependencies
527      sed -r -i                              \
528          -e "/Package/s/$/-ia32/"           \
529          -e "/Architecture/s/:.*$/: amd64/" \
530          -e "/Depends/s/:.*/: ia32-libs/"   \
531          -e "/Provides/s/($conflicts)(, *)?//g;T1;s/, *$//;:1"   \
532          -e "/Recommends/d"                 \
533          -e "/Conflicts/d"                  \
534        dpkg/DEBIAN/control
535
536      # Only keep files that live in "lib" directories or the includes
537      # that have changed.
538      sed -r -i                                                               \
539          -e "/\/lib64\//d" -e "/\/.?bin\//d"                                 \
540          -e "\,$includes,s,[ /]include/,&32/,g;s,include/32/,include32/,g"   \
541          -e "s, lib/, lib32/,g"                                              \
542          -e "s,/lib/,/lib32/,g"                                              \
543          -e "t;d"                                                            \
544          -e "\,^/usr/lib32/debug\(.*/lib32\),s,^/usr/lib32/debug,/usr/lib/debug," \
545        dpkg/DEBIAN/md5sums
546
547      # Re-run ldconfig after installation/removal
548      { echo "#!/bin/sh"; echo "[ \"x\$1\" = xconfigure ]&&ldconfig||:"; } \
549        >dpkg/DEBIAN/postinst
550      { echo "#!/bin/sh"; echo "[ \"x\$1\" = xremove ]&&ldconfig||:"; } \
551        >dpkg/DEBIAN/postrm
552      chmod 755 dpkg/DEBIAN/postinst dpkg/DEBIAN/postrm
553
554      # Remove any other control files
555      find dpkg/DEBIAN -mindepth 1 "(" -name control -o -name md5sums -o \
556                       -name postinst -o -name postrm ")" -o -print |
557        xargs -r rm -rf
558
559      # Remove any files/dirs that live outside of "lib" directories,
560      # or are not in our list of changed includes.
561      find dpkg -mindepth 1 -regextype posix-extended \
562          "(" -name DEBIAN -o -name lib -o -regex "dpkg/($includes)" ")" \
563          -prune -o -print | tac |
564        xargs -r -n 1 sh -c "rm \$0 2>/dev/null || rmdir \$0 2>/dev/null || : "
565      find dpkg -name lib64 -o -name bin -o -name "?bin" |
566        tac | xargs -r rm -rf
567
568      # Remove any symbolic links that were broken by the above steps.
569      find -L dpkg -type l -print | tac | xargs -r rm -rf
570
571      # Rename lib to lib32, but keep debug symbols in /usr/lib/debug/usr/lib32
572      # That is where gdb looks for them.
573      find dpkg -type d -o -path "*/lib/*" -print |
574        xargs -r -n 1 sh -c "
575          i=\$(echo \"\${0}\" |
576               sed -e s,/lib/,/lib32/,g \
577               -e s,/usr/lib32/debug\\\\\(.*/lib32\\\\\),/usr/lib/debug\\\\1,);
578          mkdir -p \"\${i%/*}\";
579          mv \"\${0}\" \"\${i}\""
580
581      # Rename include to include32.
582      [ -d "dpkg/usr/include" ] && mv "dpkg/usr/include" "dpkg/usr/include32"
583
584      # Prune any empty directories
585      find dpkg -type d | tac | xargs -r -n 1 rmdir 2>/dev/null || :
586
587      # Create our own Debian package
588      cd ..
589      dpkg --build staging/dpkg .' 2>&1)"
590    compat="$(eval echo $(echo "${compat}" |
591                          sed -e 's,_[^_/]*_amd64.deb,_*_amd64.deb,'))"
592    [ -r "${compat}" ] || {
593      echo "${msg}" >&2
594      echo "Failed to build new Debian archive!" >&2
595      exit 1
596    }
597
598    msg="$(sudo dpkg -i "${compat}" 2>&1)" && {
599        echo "Installed ${compat##*/}"
600      } || {
601        # echo "${msg}" >&2
602        echo "Skipped ${compat##*/}"
603      }
604  done
605
606  # Add symbolic links for developing 32bit code
607  echo "Adding missing symbolic links, enabling 32bit code development..."
608  for i in $(find /lib32 /usr/lib32 -maxdepth 1 -name \*.so.\* |
609             sed -e 's/[.]so[.][0-9].*/.so/' |
610             sort -u); do
611    [ "x${i##*/}" = "xld-linux.so" ] && continue
612    [ -r "$i" ] && continue
613    j="$(ls "$i."* | sed -e 's/.*[.]so[.]\([^.]*\)$/\1/;t;d' |
614         sort -n | tail -n 1)"
615    [ -r "$i.$j" ] || continue
616    sudo ln -s "${i##*/}.$j" "$i"
617  done
618fi
619