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-]arm: enable or disable installation of arm cross toolchain"
17 echo "--[no-]chromeos-fonts: enable or disable installation of Chrome OS"\
19 echo "--no-prompt: silently select standard options/defaults"
20 echo "Script will prompt interactively if options not given."
27 --syms) do_inst_syms
=1;;
28 --no-syms) do_inst_syms
=0;;
29 --lib32) do_inst_lib32
=1;;
30 --no-lib32) do_inst_lib32
=0;;
31 --arm) do_inst_arm
=1;;
32 --no-arm) do_inst_arm
=0;;
33 --chromeos-fonts) do_inst_chromeos_fonts
=1;;
34 --no-chromeos-fonts) do_inst_chromeos_fonts
=0;;
35 --no-prompt) do_default
=1
36 do_quietly
="-qq --assume-yes"
38 --unsupported) do_unsupported
=1;;
44 ubuntu_versions
="10\.04|10\.10|11\.04|11\.10|12\.04|12\.10"
45 ubuntu_codenames
="lucid|maverick|natty|oneiric|precise|quantal"
46 ubuntu_issue
="Ubuntu ($ubuntu_versions|$ubuntu_codenames)"
47 # GCEL is an Ubuntu-derived VM image used on Google Compute Engine; /etc/issue
48 # doesn't contain a version number so just trust that the user knows what
52 if [ 0 -eq "${do_unsupported-0}" ] ; then
53 if ! egrep -q "($ubuntu_issue|$gcel_issue)" /etc
/issue
; then
54 echo "ERROR: Only Ubuntu 10.04 (lucid) through 12.10 (quantal) are"\
55 "currently supported" >&2
59 if ! uname
-m |
egrep -q "i686|x86_64"; then
60 echo "Only x86 architectures are currently supported" >&2
65 if [ "x$(id -u)" != x0
]; then
66 echo "Running as non-root user."
67 echo "You might have to enter your password one or more times for 'sudo'."
71 # Packages needed for chromeos only
72 chromeos_dev_list
="libbluetooth-dev"
74 # Packages need for development
75 dev_list
="apache2.2-bin bison curl elfutils fakeroot flex g++ gperf
76 language-pack-fr libapache2-mod-php5 libasound2-dev libbz2-dev
77 libcairo2-dev libcups2-dev libcurl4-gnutls-dev libelf-dev
78 libgconf2-dev libgl1-mesa-dev libglib2.0-dev libglu1-mesa-dev
79 libgnome-keyring-dev libgtk2.0-dev libkrb5-dev libnspr4-dev
80 libnss3-dev libpam0g-dev libpci-dev libpulse-dev libsctp-dev
81 libspeechd-dev libsqlite3-dev libssl-dev libudev-dev libwww-perl
82 libxslt1-dev libxss-dev libxt-dev libxtst-dev mesa-common-dev
83 metacity patch perl php5-cgi pkg-config python python-cherrypy3
84 python-dev python-psutil rpm ruby subversion ttf-dejavu-core
85 ttf-indic-fonts ttf-kochi-gothic ttf-kochi-mincho ttf-thai-tlwg
89 # 64-bit systems need a minimum set of 32-bit compat packages for the pre-built
90 # NaCl binaries. These are always needed, regardless of whether or not we want
91 # the full 32-bit "cross-compile" support (--lib32).
92 if [ "$(uname -m)" = "x86_64" ]; then
93 dev_list
="${dev_list} libc6-i386 lib32gcc1 lib32stdc++6"
96 # Run-time libraries required by chromeos only
97 chromeos_lib_list
="libpulse0 libbz2-1.0 libcurl4-gnutls-dev"
99 # Full list of required run-time libraries
100 lib_list
="libatk1.0-0 libc6 libasound2 libcairo2 libcups2 libexpat1
101 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0
102 libgtk2.0-0 libpam0g libpango1.0-0 libpci3 libpcre3 libpixman-1-0
103 libpng12-0 libspeechd2 libstdc++6 libsqlite3-0 libudev0 libx11-6
104 libxau6 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6
105 libxext6 libxfixes3 libxi6 libxinerama1 libxrandr2 libxrender1
106 libxtst6 zlib1g $chromeos_lib_list"
108 # Debugging symbols for all of the run-time libraries
109 dbg_list
="libatk1.0-dbg libc6-dbg libcairo2-dbg libfontconfig1-dbg
110 libglib2.0-0-dbg libgtk2.0-0-dbg libpango1.0-0-dbg libpcre3-dbg
111 libpixman-1-0-dbg libsqlite3-0-dbg libx11-6-dbg libxau6-dbg
112 libxcb1-dbg libxcomposite1-dbg libxcursor1-dbg libxdamage1-dbg
113 libxdmcp6-dbg libxext6-dbg libxfixes3-dbg libxi6-dbg libxinerama1-dbg
114 libxrandr2-dbg libxrender1-dbg libxtst6-dbg zlib1g-dbg"
116 # arm cross toolchain packages needed to build chrome on arm
117 arm_list
="libc6-armel-cross libc6-dev-armel-cross libgcc1-armel-cross
118 libgomp1-armel-cross linux-libc-dev-armel-cross
119 libgcc1-dbg-armel-cross libgomp1-dbg-armel-cross
120 binutils-arm-linux-gnueabi cpp-arm-linux-gnueabi
121 gcc-arm-linux-gnueabi g++-arm-linux-gnueabi
122 libmudflap0-dbg-armel-cross"
125 # Some package names have changed over time
126 if apt-cache show ttf-mscorefonts-installer
>/dev
/null
2>&1; then
127 dev_list
="${dev_list} ttf-mscorefonts-installer"
129 dev_list
="${dev_list} msttcorefonts"
131 if apt-cache show libnspr4-dbg
>/dev
/null
2>&1; then
132 dbg_list
="${dbg_list} libnspr4-dbg libnss3-dbg"
133 lib_list
="${lib_list} libnspr4 libnss3"
135 dbg_list
="${dbg_list} libnspr4-0d-dbg libnss3-1d-dbg"
136 lib_list
="${lib_list} libnspr4-0d libnss3-1d"
138 if apt-cache show libjpeg-dev
>/dev
/null
2>&1; then
139 dev_list
="${dev_list} libjpeg-dev"
141 dev_list
="${dev_list} libjpeg62-dev"
144 # Some packages are only needed, if the distribution actually supports
146 if apt-cache show appmenu-gtk
>/dev
/null
2>&1; then
147 lib_list
="$lib_list appmenu-gtk"
150 # Waits for the user to press 'Y' or 'N'. Either uppercase of lowercase is
151 # accepted. Returns 0 for 'Y' and 1 for 'N'. If an optional parameter has
152 # been provided to yes_no(), the function also accepts RETURN as a user input.
153 # The parameter specifies the exit code that should be returned in that case.
154 # The function will echo the user's selection followed by a newline character.
155 # Users can abort the function by pressing CTRL-C. This will call "exit 1".
157 if [ 0 -ne "${do_default-0}" ] ; then
162 c
="$(trap 'stty echo -iuclc icanon 2>/dev/null' EXIT INT TERM QUIT
163 stty -echo iuclc -icanon 2>/dev/null
164 dd count=1 bs=1 2>/dev/null | od -An -tx1)"
166 " 0a") if [ -n "$1" ]; then
167 [ $1 -eq 0 ] && echo "Y" ||
echo "N"
177 "") echo "Aborted" >&2
180 *) # The user pressed an unrecognized key. As we are not echoing
181 # any incorrect user input, alert the user by ringing the bell.
182 (tput bel
) 2>/dev
/null
188 if test "$do_inst_syms" = ""
190 echo "This script installs all tools and libraries needed to build Chromium."
192 echo "For most of the libraries, it can also install debugging symbols, which"
193 echo "will allow you to debug code in the system libraries. Most developers"
194 echo "won't need these symbols."
195 echo -n "Do you want me to install them for you (y/N) "
200 if test "$do_inst_syms" = "1"; then
201 echo "Installing debugging symbols."
203 echo "Skipping installation of debugging symbols."
207 # Install the Chrome OS default fonts.
208 if test "$do_inst_chromeos_fonts" != "0"; then
210 echo "Installing Chrome OS fonts."
211 dir
=`echo $0 | sed -r -e 's/\/[^/]+$//'`
212 if ! sudo
$dir/linux
/install-chromeos-fonts.py
; then
213 echo "ERROR: The installation of the Chrome OS default fonts failed."
214 if [ `stat -f -c %T $dir` == "nfs" ]; then
215 echo "The reason is that your repo is installed on a remote file system."
217 echo "This is expected if your repo is installed on a remote file system."
219 echo "It is recommended to install your repo on a local file system."
220 echo "You can skip the installation of the Chrome OS default founts with"
221 echo "the command line option: --no-chromeos-fonts."
225 echo "Skipping installation of Chrome OS fonts."
228 # When cross building for arm on 64-bit systems the host binaries
229 # that are part of v8 need to be compiled with -m32 which means
230 # that basic multilib support is needed.
231 if [ "$(uname -m)" = "x86_64" ]; then
232 arm_list
="$arm_list g++-multilib"
235 if test "$do_inst_arm" = "1"; then
237 if test "$DISTRIB_CODENAME" != "precise"; then
238 echo "ERROR: Installing the ARM cross toolchain is only available on" \
239 "Ubuntu precise." >&2
242 echo "Installing ARM cross toolchain."
244 echo "Skipping installation of ARM cross toolchain."
250 # We initially run "apt-get" with the --reinstall option and parse its output.
251 # This way, we can find all the packages that need to be newly installed
252 # without accidentally promoting any packages from "auto" to "manual".
253 # We then re-run "apt-get" with just the list of missing packages.
254 echo "Finding missing packages..."
255 packages
="${dev_list} ${lib_list} ${dbg_list} ${arm_list}"
256 # Intentionally leaving $packages unquoted so it's more readable.
257 echo "Packages required: " $packages
259 new_list_cmd
="sudo apt-get install --reinstall $(echo $packages)"
260 if new_list
="$(yes n | LANG=C $new_list_cmd)"; then
261 # We probably never hit this following line.
262 echo "No missing packages, and the packages are up-to-date."
263 elif [ $?
-eq 1 ]; then
264 # We expect apt-get to have exit status of 1.
265 # This indicates that we cancelled the install with "yes n|".
266 new_list
=$
(echo "$new_list" |
267 sed -e '1,/The following NEW packages will be installed:/d;s/^ //;t;d')
268 new_list
=$
(echo "$new_list" |
sed 's/ *$//')
269 if [ -z "$new_list" ] ; then
270 echo "No missing packages, and the packages are up-to-date."
272 echo "Installing missing packages: $new_list."
273 sudo apt-get
install ${do_quietly-} ${new_list}
277 # An apt-get exit status of 100 indicates that a real error has occurred.
279 # I am intentionally leaving out the '"'s around new_list_cmd,
280 # as this makes it easier to cut and paste the output
281 echo "The following command failed: " ${new_list_cmd}
283 echo "It produces the following output:"
284 yes n |
$new_list_cmd || true
286 echo "You will have to install the above packages yourself."
291 # Install 32bit backwards compatibility support for 64bit systems
292 if [ "$(uname -m)" = "x86_64" ]; then
293 if test "$do_inst_lib32" != "1"
295 echo "NOTE: If you were expecting the option to install 32bit libs,"
296 echo "please run with the --lib32 flag."
298 echo "Installation complete."
304 echo "We no longer recommend that you use this script to install"
305 echo "32bit libraries on a 64bit system. Instead, consider using the"
306 echo "install-chroot.sh script to help you set up a 32bit environment"
307 echo "for building and testing 32bit versions of Chrome."
309 echo "The code for installing 32bit libraries on a 64bit system is"
310 echo "unmaintained and might not work with modern versions of Ubuntu"
313 echo -n "Are you sure you want to proceed (y/N) "
317 if test "$do_inst_lib32" != "1"
322 # Standard 32bit compatibility libraries
323 echo "First, installing the limited existing 32-bit support..."
324 cmp_list
="ia32-libs lib32asound2-dev lib32stdc++6 lib32z1
325 lib32z1-dev libc6-dev-i386 libc6-i386 g++-multilib"
326 if [ -n "`apt-cache search lib32readline-gplv2-dev 2>/dev/null`" ]; then
327 cmp_list
="${cmp_list} lib32readline-gplv2-dev"
329 cmp_list
="${cmp_list} lib32readline5-dev"
331 sudo apt-get
install ${do_quietly-} $cmp_list
333 tmp
=/tmp
/install-32bit.$$
334 trap 'rm -rf "${tmp}"' EXIT INT TERM QUIT
335 mkdir
-p "${tmp}/apt/lists/partial" "${tmp}/cache" "${tmp}/partial"
336 touch "${tmp}/status"
338 [ -r /etc
/apt
/apt.conf
] && cp /etc
/apt
/apt.conf
"${tmp}/apt/"
339 cat >>"${tmp}/apt/apt.conf" <<EOF
340 Apt::Architecture "i386";
341 Dir::Cache "${tmp}/cache";
342 Dir::Cache::Archives "${tmp}/";
343 Dir::State::Lists "${tmp}/apt/lists/";
344 Dir::State::status "${tmp}/status";
347 # Download 32bit packages
348 echo "Computing list of available 32bit packages..."
349 sudo apt-get
-c="${tmp}/apt/apt.conf" update
351 echo "Downloading available 32bit packages..."
352 sudo apt-get
-c="${tmp}/apt/apt.conf" \
353 --yes --download-only --force-yes --reinstall install \
354 ${lib_list} ${dbg_list}
356 # Open packages, remove everything that is not a library, move the
357 # library to a lib32 directory and package everything as a *.deb file.
358 echo "Repackaging and installing 32bit packages for use on 64bit systems..."
359 for i
in ${lib_list} ${dbg_list}; do
360 orig
="$(echo "${tmp}/${i}"_*_i386.deb)"
361 compat
="$(echo "${orig}" |
362 sed -e 's,\(_[^_/]*_\)i386\(.deb\),-ia32\1amd64\2,')"
363 rm -rf "${tmp}/staging"
364 msg
="$(fakeroot -u sh -exc '
365 # Unpack 32bit Debian archive
367 mkdir -p "'"${tmp}"'/staging
/dpkg
/DEBIAN
"
368 cd "'"${tmp}"'/staging
"
370 tar Cfx dpkg data.tar*
371 tar zCfx dpkg/DEBIAN control.tar.gz
373 # Create a posix extended regular expression fragment that will
374 # recognize the includes which have changed. Should be rare,
375 # will almost always be empty.
376 includes=`sed -n -e "s
/^
[0-9a-z]* //g
" \
377 -e "\
,usr
/include
/,p
" dpkg/DEBIAN/md5sums |
378 xargs -n 1 -I FILE /bin/sh -c \
379 "cmp -s dpkg
/FILE
/FILE ||
echo FILE
" |
383 # If empty, set it to not match anything.
384 test -z "$includes" && includes="^
//"
386 # Turn the conflicts into an extended RE for removal from the
388 conflicts=`sed -n -e "/Conflicts
/s
/Conflicts
: *//;T
;s
/, */|
/g
;p
" \
391 # Rename package, change architecture, remove conflicts and dependencies
393 -e "/Package
/s
/$
/-ia32/" \
394 -e "/Architecture
/s
/:.
*$
/: amd64
/" \
395 -e "/Depends
/s
/:.
*/: ia32-libs
/" \
396 -e "/Provides
/s
/($conflicts)(, *)?
//g
;T1
;s
/, *$
//;:1" \
401 # Only keep files that live in "lib
" directories or the includes
404 -e "/\
/lib64\
//d
" -e "/\
/.?bin\
//d
" \
405 -e "\
,$includes,s
,[ /]include
/,&32/,g
;s
,include
/32/,include32
/,g
" \
406 -e "s
, lib
/, lib32
/,g
" \
407 -e "s
,/lib
/,/lib32
/,g
" \
409 -e "\
,^
/usr
/lib32
/debug\
(.
*/lib32\
),s
,^
/usr
/lib32
/debug
,/usr
/lib
/debug
," \
412 # Re-run ldconfig after installation/removal
413 { echo "#!/bin/sh"; echo "[ \"x\$1\" = xconfigure ]&&ldconfig||:"; } \
414 >dpkg
/DEBIAN
/postinst
415 { echo "#!/bin/sh"; echo "[ \"x\$1\" = xremove ]&&ldconfig||:"; } \
417 chmod 755 dpkg
/DEBIAN
/postinst dpkg
/DEBIAN
/postrm
419 # Remove any other control files
420 find dpkg
/DEBIAN
-mindepth 1 "(" -name control
-o -name md5sums
-o \
421 -name postinst
-o -name postrm
")" -o -print |
424 # Remove any files/dirs that live outside of "lib" directories,
425 # or are not in our list of changed includes.
426 find dpkg
-mindepth 1 -regextype posix-extended \
427 "(" -name DEBIAN
-o -name lib
-o -regex "dpkg/($includes)" ")" \
428 -prune -o -print |
tac |
429 xargs -r -n 1 sh
-c "rm \$0 2>/dev/null || rmdir \$0 2>/dev/null || : "
430 find dpkg
-name lib64
-o -name bin
-o -name "?bin" |
431 tac |
xargs -r rm -rf
433 # Remove any symbolic links that were broken by the above steps.
434 find -L dpkg
-type l
-print |
tac |
xargs -r rm -rf
436 # Rename lib to lib32, but keep debug symbols in /usr/lib/debug/usr/lib32
437 # That is where gdb looks for them.
438 find dpkg
-type d
-o -path "*/lib/*" -print |
439 xargs -r -n 1 sh
-c "
440 i=\$(echo \"\${0}\" |
441 sed -e s,/lib/,/lib32/,g \
442 -e s,/usr/lib32/debug\\\\\(.*/lib32\\\\\),/usr/lib/debug\\\\1,);
443 mkdir -p \"\${i%/*}\";
444 mv \"\${0}\" \"\${i}\""
446 # Rename include to include32.
447 [ -d "dpkg/usr/include" ] && mv "dpkg/usr/include" "dpkg/usr/include32"
449 # Prune any empty directories
450 find dpkg
-type d |
tac |
xargs -r -n 1 rmdir 2>/dev
/null ||
:
452 # Create our own Debian package
454 dpkg
--build staging
/dpkg .
' 2>&1)"
455 compat="$(eval echo $(echo "${compat}" |
456 sed -e 's
,_
[^_
/]*_amd64.deb
,_
*_amd64.deb
,'))"
457 [ -r "${compat}" ] || {
459 echo "Failed to build new Debian archive!" >&2
463 msg="$(sudo dpkg -i "${compat}" 2>&1)" && {
464 echo "Installed ${compat##*/}"
467 echo "Skipped ${compat##*/}"
471 # Add symbolic links for developing 32bit code
472 echo "Adding missing symbolic links, enabling 32bit code development..."
473 for i in $(find /lib32 /usr/lib32 -maxdepth 1 -name \*.so.\* |
474 sed -e 's
/[.
]so
[.
][0-9].
*/.so
/' |
476 [ "x${i##*/}" = "xld-linux.so" ] && continue
477 [ -r "$i" ] && continue
478 j="$(ls "$i."* | sed -e 's
/.
*[.
]so
[.
]\
([^.
]*\
)$
/\
1/;t
;d
' |
479 sort -n | tail -n 1)"
480 [ -r "$i.$j" ] || continue
481 sudo ln -s "${i##*/}.$j" "$i"