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.
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
12 echo "Usage: $0 [--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-prompt: silently select standard options/defaults"
17 echo "Script will prompt interactively if options not given."
24 --syms) do_inst_syms
=1;;
25 --no-syms) do_inst_syms
=0;;
26 --lib32) do_inst_lib32
=1;;
27 --no-lib32) do_inst_lib32
=0;;
28 --no-prompt) do_default
=1
29 do_quietly
="-qq --assume-yes"
37 'Ubuntu (10\.04|10\.10|11\.04|11\.10|12\.04|lucid|maverick|natty|oneiric|precise)' \
39 echo "Only Ubuntu 10.04 (lucid) through 12.04 (precise) are currently" \
44 if ! uname
-m |
egrep -q "i686|x86_64"; then
45 echo "Only x86 architectures are currently supported" >&2
49 if [ "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'."
55 # Packages needed for chromeos only
56 chromeos_dev_list
="libbluetooth-dev libpulse-dev"
58 # Packages need for development
59 dev_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 libelf-dev
62 libgconf2-dev libgl1-mesa-dev libglib2.0-dev libglu1-mesa-dev
63 libgnome-keyring-dev libgtk2.0-dev libkrb5-dev libnspr4-dev
64 libnss3-dev libpam0g-dev libpci-dev libsctp-dev libsqlite3-dev
65 libssl-dev libudev-dev libwww-perl libxslt1-dev libxss-dev libxt-dev
66 libxtst-dev mesa-common-dev patch perl php5-cgi pkg-config python
67 python-cherrypy3 python-dev python-psutil rpm ruby subversion
68 ttf-dejavu-core ttf-indic-fonts ttf-kochi-gothic ttf-kochi-mincho
69 ttf-thai-tlwg wdiff git-core $chromeos_dev_list"
71 # 64-bit systems need a minimum set of 32-bit compat packages for the pre-built
72 # NaCl binaries. These are always needed, regardless of whether or not we want
73 # the full 32-bit "cross-compile" support (--lib32).
74 if [ "$(uname -m)" = "x86_64" ]; then
75 dev_list
="${dev_list} libc6-i386 lib32gcc1 lib32stdc++6"
78 # Run-time libraries required by chromeos only
79 chromeos_lib_list
="libpulse0 libbz2-1.0 libcurl4-gnutls-dev"
81 # Full list of required run-time libraries
82 lib_list
="libatk1.0-0 libc6 libasound2 libcairo2 libcups2 libexpat1
83 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0
84 libgtk2.0-0 libpam0g libpango1.0-0 libpci3 libpcre3 libpixman-1-0
85 libpng12-0 libstdc++6 libsqlite3-0 libudev0 libx11-6 libxau6 libxcb1
86 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6 libxext6 libxfixes3
87 libxi6 libxinerama1 libxrandr2 libxrender1 libxtst6 zlib1g
90 # Debugging symbols for all of the run-time libraries
91 dbg_list
="libatk1.0-dbg libc6-dbg libcairo2-dbg libfontconfig1-dbg
92 libglib2.0-0-dbg libgtk2.0-0-dbg libpango1.0-0-dbg libpcre3-dbg
93 libpixman-1-0-dbg libsqlite3-0-dbg libx11-6-dbg libxau6-dbg
94 libxcb1-dbg libxcomposite1-dbg libxcursor1-dbg libxdamage1-dbg
95 libxdmcp6-dbg libxext6-dbg libxfixes3-dbg libxi6-dbg libxinerama1-dbg
96 libxrandr2-dbg libxrender1-dbg libxtst6-dbg zlib1g-dbg"
98 # Plugin lists needed for tests.
99 plugin_list
="flashplugin-installer"
101 # Some package names have changed over time
102 if apt-cache show ttf-mscorefonts-installer
>/dev
/null
2>&1; then
103 dev_list
="${dev_list} ttf-mscorefonts-installer"
105 dev_list
="${dev_list} msttcorefonts"
107 if apt-cache show libnspr4-dbg
>/dev
/null
2>&1; then
108 dbg_list
="${dbg_list} libnspr4-dbg libnss3-dbg"
109 lib_list
="${lib_list} libnspr4 libnss3"
111 dbg_list
="${dbg_list} libnspr4-0d-dbg libnss3-1d-dbg"
112 lib_list
="${lib_list} libnspr4-0d libnss3-1d"
114 if apt-cache show libjpeg-dev
>/dev
/null
2>&1; then
115 dev_list
="${dev_list} libjpeg-dev"
117 dev_list
="${dev_list} libjpeg62-dev"
120 # Some packages are only needed, if the distribution actually supports
122 if apt-cache show appmenu-gtk
>/dev
/null
2>&1; then
123 lib_list
="$lib_list appmenu-gtk"
126 # Waits for the user to press 'Y' or 'N'. Either uppercase of lowercase is
127 # accepted. Returns 0 for 'Y' and 1 for 'N'. If an optional parameter has
128 # been provided to yes_no(), the function also accepts RETURN as a user input.
129 # The parameter specifies the exit code that should be returned in that case.
130 # The function will echo the user's selection followed by a newline character.
131 # Users can abort the function by pressing CTRL-C. This will call "exit 1".
133 if [ 0 -ne "${do_default-0}" ] ; then
138 c
="$(trap 'stty echo -iuclc icanon 2>/dev/null' EXIT INT TERM QUIT
139 stty -echo iuclc -icanon 2>/dev/null
140 dd count=1 bs=1 2>/dev/null | od -An -tx1)"
142 " 0a") if [ -n "$1" ]; then
143 [ $1 -eq 0 ] && echo "Y" ||
echo "N"
153 "") echo "Aborted" >&2
156 *) # The user pressed an unrecognized key. As we are not echoing
157 # any incorrect user input, alert the user by ringing the bell.
158 (tput bel
) 2>/dev
/null
164 if test "$do_inst_syms" = ""
166 echo "This script installs all tools and libraries needed to build Chromium."
168 echo "For most of the libraries, it can also install debugging symbols, which"
169 echo "will allow you to debug code in the system libraries. Most developers"
170 echo "won't need these symbols."
171 echo -n "Do you want me to install them for you (y/N) "
176 if test "$do_inst_syms" = "1"; then
177 echo "Installing debugging symbols."
179 echo "Skipping installation of debugging symbols."
185 # We initially run "apt-get" with the --reinstall option and parse its output.
186 # This way, we can find all the packages that need to be newly installed
187 # without accidentally promoting any packages from "auto" to "manual".
188 # We then re-run "apt-get" with just the list of missing packages.
189 echo "Finding missing packages..."
190 packages
="${dev_list} ${lib_list} ${dbg_list} ${plugin_list}"
191 # Intentionally leaving $packages unquoted so it's more readable.
192 echo "Packages required: " $packages
194 new_list_cmd
="sudo apt-get install --reinstall $(echo $packages)"
195 if new_list
="$(yes n | LANG=C $new_list_cmd)"; then
196 # We probably never hit this following line.
197 echo "No missing packages, and the packages are up-to-date."
198 elif [ $?
-eq 1 ]; then
199 # We expect apt-get to have exit status of 1.
200 # This indicates that we cancelled the install with "yes n|".
201 new_list
=$
(echo "$new_list" |
202 sed -e '1,/The following NEW packages will be installed:/d;s/^ //;t;d')
203 new_list
=$
(echo "$new_list" |
sed 's/ *$//')
204 if [ -z "$new_list" ] ; then
205 echo "No missing packages, and the packages are up-to-date."
207 echo "Installing missing packages: $new_list."
208 sudo apt-get
install ${do_quietly-} ${new_list}
212 # An apt-get exit status of 100 indicates that a real error has occurred.
214 # I am intentionally leaving out the '"'s around new_list_cmd,
215 # as this makes it easier to cut and paste the output
216 echo "The following command failed: " ${new_list_cmd}
218 echo "It produces the following output:"
219 yes n |
$new_list_cmd || true
221 echo "You will have to install the above packages yourself."
226 # Install 32bit backwards compatibility support for 64bit systems
227 if [ "$(uname -m)" = "x86_64" ]; then
228 if test "$do_inst_lib32" = ""
230 echo "We no longer recommend that you use this script to install"
231 echo "32bit libraries on a 64bit system. Instead, consider using"
232 echo "the install-chroot.sh script to help you set up a 32bit"
233 echo "environment for building and testing 32bit versions of Chrome."
235 echo "If you nonetheless want to try installing 32bit libraries"
236 echo "directly, you can do so by explicitly passing the --lib32"
237 echo "option to install-build-deps.sh."
239 if test "$do_inst_lib32" != "1"
241 echo "Exiting without installing any 32bit libraries."
245 echo "N.B. the code for installing 32bit libraries on a 64bit"
246 echo " system is no longer actively maintained and might"
247 echo " not work with modern versions of Ubuntu or Debian."
250 # Standard 32bit compatibility libraries
251 echo "First, installing the limited existing 32-bit support..."
252 cmp_list
="ia32-libs lib32asound2-dev lib32stdc++6 lib32z1
253 lib32z1-dev libc6-dev-i386 libc6-i386 g++-multilib"
254 if [ -n "`apt-cache search lib32readline-gplv2-dev 2>/dev/null`" ]; then
255 cmp_list
="${cmp_list} lib32readline-gplv2-dev"
257 cmp_list
="${cmp_list} lib32readline5-dev"
259 sudo apt-get
install ${do_quietly-} $cmp_list
261 tmp
=/tmp
/install-32bit.$$
262 trap 'rm -rf "${tmp}"' EXIT INT TERM QUIT
263 mkdir
-p "${tmp}/apt/lists/partial" "${tmp}/cache" "${tmp}/partial"
264 touch "${tmp}/status"
266 [ -r /etc
/apt
/apt.conf
] && cp /etc
/apt
/apt.conf
"${tmp}/apt/"
267 cat >>"${tmp}/apt/apt.conf" <<EOF
268 Apt::Architecture "i386";
269 Dir::Cache "${tmp}/cache";
270 Dir::Cache::Archives "${tmp}/";
271 Dir::State::Lists "${tmp}/apt/lists/";
272 Dir::State::status "${tmp}/status";
275 # Download 32bit packages
276 echo "Computing list of available 32bit packages..."
277 sudo apt-get
-c="${tmp}/apt/apt.conf" update
279 echo "Downloading available 32bit packages..."
280 sudo apt-get
-c="${tmp}/apt/apt.conf" \
281 --yes --download-only --force-yes --reinstall install \
282 ${lib_list} ${dbg_list}
284 # Open packages, remove everything that is not a library, move the
285 # library to a lib32 directory and package everything as a *.deb file.
286 echo "Repackaging and installing 32bit packages for use on 64bit systems..."
287 for i
in ${lib_list} ${dbg_list}; do
288 orig
="$(echo "${tmp}/${i}"_*_i386.deb)"
289 compat
="$(echo "${orig}" |
290 sed -e 's,\(_[^_/]*_\)i386\(.deb\),-ia32\1amd64\2,')"
291 rm -rf "${tmp}/staging"
292 msg
="$(fakeroot -u sh -exc '
293 # Unpack 32bit Debian archive
295 mkdir -p "'"${tmp}"'/staging
/dpkg
/DEBIAN
"
296 cd "'"${tmp}"'/staging
"
298 tar zCfx dpkg data.tar.gz
299 tar zCfx dpkg/DEBIAN control.tar.gz
301 # Create a posix extended regular expression fragment that will
302 # recognize the includes which have changed. Should be rare,
303 # will almost always be empty.
304 includes=`sed -n -e "s
/^
[0-9a-z]* //g
" \
305 -e "\
,usr
/include
/,p
" dpkg/DEBIAN/md5sums |
306 xargs -n 1 -I FILE /bin/sh -c \
307 "cmp -s dpkg
/FILE
/FILE ||
echo FILE
" |
311 # If empty, set it to not match anything.
312 test -z "$includes" && includes="^
//"
314 # Turn the conflicts into an extended RE for removal from the
316 conflicts=`sed -n -e "/Conflicts
/s
/Conflicts
: *//;T
;s
/, */|
/g
;p
" \
319 # Rename package, change architecture, remove conflicts and dependencies
321 -e "/Package
/s
/$
/-ia32/" \
322 -e "/Architecture
/s
/:.
*$
/: amd64
/" \
323 -e "/Depends
/s
/:.
*/: ia32-libs
/" \
324 -e "/Provides
/s
/($conflicts)(, *)?
//g
;T1
;s
/, *$
//;:1" \
329 # Only keep files that live in "lib
" directories or the includes
332 -e "/\
/lib64\
//d
" -e "/\
/.?bin\
//d
" \
333 -e "\
,$includes,s
,[ /]include
/,&32/,g
;s
,include
/32/,include32
/,g
" \
334 -e "s
, lib
/, lib32
/,g
" \
335 -e "s
,/lib
/,/lib32
/,g
" \
337 -e "\
,^
/usr
/lib32
/debug\
(.
*/lib32\
),s
,^
/usr
/lib32
/debug
,/usr
/lib
/debug
," \
340 # Re-run ldconfig after installation/removal
341 { echo "#!/bin/sh"; echo "[ \"x\$1\" = xconfigure ]&&ldconfig||:"; } \
342 >dpkg
/DEBIAN
/postinst
343 { echo "#!/bin/sh"; echo "[ \"x\$1\" = xremove ]&&ldconfig||:"; } \
345 chmod 755 dpkg
/DEBIAN
/postinst dpkg
/DEBIAN
/postrm
347 # Remove any other control files
348 find dpkg
/DEBIAN
-mindepth 1 "(" -name control
-o -name md5sums
-o \
349 -name postinst
-o -name postrm
")" -o -print |
352 # Remove any files/dirs that live outside of "lib" directories,
353 # or are not in our list of changed includes.
354 find dpkg
-mindepth 1 -regextype posix-extended \
355 "(" -name DEBIAN
-o -name lib
-o -regex "dpkg/($includes)" ")" \
356 -prune -o -print |
tac |
357 xargs -r -n 1 sh
-c "rm \$0 2>/dev/null || rmdir \$0 2>/dev/null || : "
358 find dpkg
-name lib64
-o -name bin
-o -name "?bin" |
359 tac |
xargs -r rm -rf
361 # Remove any symbolic links that were broken by the above steps.
362 find -L dpkg
-type l
-print |
tac |
xargs -r rm -rf
364 # Rename lib to lib32, but keep debug symbols in /usr/lib/debug/usr/lib32
365 # That is where gdb looks for them.
366 find dpkg
-type d
-o -path "*/lib/*" -print |
367 xargs -r -n 1 sh
-c "
368 i=\$(echo \"\${0}\" |
369 sed -e s,/lib/,/lib32/,g \
370 -e s,/usr/lib32/debug\\\\\(.*/lib32\\\\\),/usr/lib/debug\\\\1,);
371 mkdir -p \"\${i%/*}\";
372 mv \"\${0}\" \"\${i}\""
374 # Rename include to include32.
375 [ -d "dpkg/usr/include" ] && mv "dpkg/usr/include" "dpkg/usr/include32"
377 # Prune any empty directories
378 find dpkg
-type d |
tac |
xargs -r -n 1 rmdir 2>/dev
/null ||
:
380 # Create our own Debian package
382 dpkg
--build staging
/dpkg .
' 2>&1)"
383 compat="$(eval echo $(echo "${compat}" |
384 sed -e 's
,_
[^_
/]*_amd64.deb
,_
*_amd64.deb
,'))"
385 [ -r "${compat}" ] || {
387 echo "Failed to build new Debian archive!" >&2
391 msg="$(sudo dpkg -i "${compat}" 2>&1)" && {
392 echo "Installed ${compat##*/}"
395 echo "Skipped ${compat##*/}"
399 # Add symbolic links for developing 32bit code
400 echo "Adding missing symbolic links, enabling 32bit code development..."
401 for i in $(find /lib32 /usr/lib32 -maxdepth 1 -name \*.so.\* |
402 sed -e 's
/[.
]so
[.
][0-9].
*/.so
/' |
404 [ "x${i##*/}" = "xld-linux.so" ] && continue
405 [ -r "$i" ] && continue
406 j="$(ls "$i."* | sed -e 's
/.
*[.
]so
[.
]\
([^.
]*\
)$
/\
1/;t
;d
' |
407 sort -n | tail -n 1)"
408 [ -r "$i.$j" ] || continue
409 sudo ln -s "${i##*/}.$j" "$i"