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 "Script will prompt interactively if options not given."
23 --syms) do_inst_syms
=1;;
24 --no-syms) do_inst_syms
=0;;
25 --lib32) do_inst_lib32
=1;;
26 --no-lib32) do_inst_lib32
=0;;
33 'Ubuntu (10\.04|10\.10|11\.04|11\.10|lucid|maverick|natty|oneiric)' \
35 echo "Only Ubuntu 10.04 (lucid) through 11.10 (oneiric) are currently" \
40 if ! uname
-m |
egrep -q "i686|x86_64"; then
41 echo "Only x86 architectures are currently supported" >&2
45 if [ "x$(id -u)" != x0
]; then
46 echo "Running as non-root user."
47 echo "You might have to enter your password one or more times for 'sudo'."
51 # Packages needed for chromeos only
52 chromeos_dev_list
="libpulse-dev"
54 # Packages need for development
55 dev_list
="apache2.2-bin bison curl elfutils fakeroot flex g++ gperf
56 language-pack-fr libapache2-mod-php5 libasound2-dev libbz2-dev
57 libcairo2-dev libcups2-dev libcurl4-gnutls-dev libdbus-glib-1-dev
58 libelf-dev libgconf2-dev libgl1-mesa-dev libglib2.0-dev
59 libglu1-mesa-dev libgnome-keyring-dev libgtk2.0-dev libjpeg62-dev
60 libkrb5-dev libnspr4-dev libnss3-dev libpam0g-dev libsctp-dev
61 libsqlite3-dev libssl-dev libudev-dev libwww-perl libxslt1-dev
62 libxss-dev libxt-dev libxtst-dev mesa-common-dev msttcorefonts patch
63 perl php5-cgi pkg-config python python-cherrypy3 python-dev
64 python-psutil rpm ruby subversion ttf-dejavu-core ttf-indic-fonts
65 ttf-kochi-gothic ttf-kochi-mincho ttf-thai-tlwg wdiff git-core
68 # Run-time libraries required by chromeos only
69 chromeos_lib_list
="libpulse0 libbz2-1.0 libcurl4-gnutls-dev"
71 # Full list of required run-time libraries
72 lib_list
="libatk1.0-0 libc6 libasound2 libcairo2 libcups2 libdbus-glib-1-2
73 libexpat1 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0
74 libgtk2.0-0 libpam0g libpango1.0-0 libpcre3 libpixman-1-0
75 libpng12-0 libstdc++6 libsqlite3-0 libudev0 libx11-6 libxau6 libxcb1
76 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6 libxext6 libxfixes3
77 libxi6 libxinerama1 libxrandr2 libxrender1 libxtst6 zlib1g
80 # Debugging symbols for all of the run-time libraries
81 dbg_list
="libatk1.0-dbg libc6-dbg libcairo2-dbg libdbus-glib-1-2-dbg
82 libfontconfig1-dbg libglib2.0-0-dbg libgtk2.0-0-dbg
83 libpango1.0-0-dbg libpcre3-dbg libpixman-1-0-dbg
85 libx11-6-dbg libxau6-dbg libxcb1-dbg libxcomposite1-dbg
86 libxcursor1-dbg libxdamage1-dbg libxdmcp6-dbg libxext6-dbg
87 libxfixes3-dbg libxi6-dbg libxinerama1-dbg libxrandr2-dbg
88 libxrender1-dbg libxtst6-dbg zlib1g-dbg"
90 # Plugin lists needed for tests.
91 plugin_list
="flashplugin-installer"
93 # Some NSS packages were renamed in Natty.
94 if egrep -q 'Ubuntu (10\.04|10\.10)' /etc
/issue
; then
95 dbg_list
="${dbg_list} libnspr4-0d-dbg libnss3-1d-dbg"
96 lib_list
="${lib_list} libnspr4-0d libnss3-1d"
98 dbg_list
="${dbg_list} libnspr4-dbg libnss3-dbg"
99 lib_list
="${lib_list} libnspr4 libnss3"
102 # Waits for the user to press 'Y' or 'N'. Either uppercase of lowercase is
103 # accepted. Returns 0 for 'Y' and 1 for 'N'. If an optional parameter has
104 # been provided to yes_no(), the function also accepts RETURN as a user input.
105 # The parameter specifies the exit code that should be returned in that case.
106 # The function will echo the user's selection followed by a newline character.
107 # Users can abort the function by pressing CTRL-C. This will call "exit 1".
111 c
="$(trap 'stty echo -iuclc icanon 2>/dev/null' EXIT INT TERM QUIT
112 stty -echo iuclc -icanon 2>/dev/null
113 dd count=1 bs=1 2>/dev/null | od -An -tx1)"
115 " 0a") if [ -n "$1" ]; then
116 [ $1 -eq 0 ] && echo "Y" ||
echo "N"
126 "") echo "Aborted" >&2
129 *) # The user pressed an unrecognized key. As we are not echoing
130 # any incorrect user input, alert the user by ringing the bell.
131 (tput bel
) 2>/dev
/null
137 if test "$do_inst_syms" = ""
139 echo "This script installs all tools and libraries needed to build Chromium."
141 echo "For most of the libraries, it can also install debugging symbols, which"
142 echo "will allow you to debug code in the system libraries. Most developers"
143 echo "won't need these symbols."
144 echo -n "Do you want me to install them for you (y/N) "
149 if test "$do_inst_syms" = "1"; then
150 echo "Installing debugging symbols."
152 echo "Skipping installation of debugging symbols."
158 # We initially run "apt-get" with the --reinstall option and parse its output.
159 # This way, we can find all the packages that need to be newly installed
160 # without accidentally promoting any packages from "auto" to "manual".
161 # We then re-run "apt-get" with just the list of missing packages.
162 echo "Finding missing packages..."
163 packages
="${dev_list} ${lib_list} ${dbg_list} ${plugin_list}"
164 # Intentially leaving $packages unquoted so it's more readable.
165 echo "Packages required: " $packages
167 new_list_cmd
="sudo apt-get install --reinstall $(echo $packages)"
168 if new_list
="$(yes n | LANG=C $new_list_cmd)"; then
169 # We probably never hit this following line.
170 echo "No missing packages, and the packages are up-to-date."
171 elif [ $?
-eq 1 ]; then
172 # We expect apt-get to have exit status of 1.
173 # This indicates that we canceled the install with "yes n|".
174 new_list
=$
(echo "$new_list" |
175 sed -e '1,/The following NEW packages will be installed:/d;s/^ //;t;d')
176 new_list
=$
(echo "$new_list" |
sed 's/ *$//')
177 if [ -z "$new_list" ] ; then
178 echo "No missing packages, and the packages are up-to-date."
180 echo "Installing missing packages: $new_list."
181 sudo apt-get
install ${new_list}
185 # An apt-get exit status of 100 indicates that a real error has occurred.
187 # I am intentionally leaving out the '"'s around new_list_cmd,
188 # as this makes it easier to cut and paste the output
189 echo "The following command failed: " ${new_list_cmd}
191 echo "It produces the following output:"
192 yes n |
$new_list_cmd || true
194 echo "You will have to install the above packages yourself."
199 # Install 32bit backwards compatibility support for 64bit systems
200 if [ "$(uname -m)" = "x86_64" ]; then
201 if test "$do_inst_lib32" = ""
203 echo "Installing 32bit libraries not already provided by the system"
205 echo "This is only needed to build a 32-bit Chrome on your 64-bit system."
207 echo "While we only need to install a relatively small number of library"
208 echo "files, we temporarily need to download a lot of large *.deb packages"
209 echo "that contain these files. We will create new *.deb packages that"
210 echo "include just the 32bit libraries. These files will then be found on"
211 echo "your system in places like /lib32, /usr/lib32, /usr/lib/debug/lib32,"
212 echo "/usr/lib/debug/usr/lib32. If you ever need to uninstall these files,"
213 echo "look for packages named *-ia32.deb."
214 echo "Do you want me to download all packages needed to build new 32bit"
215 echo -n "package files (y/N) "
220 if test "$do_inst_lib32" != "1"
222 echo "Exiting without installing any 32bit libraries."
226 # Standard 32bit compatibility libraries
227 echo "First, installing the limited existing 32-bit support..."
228 cmp_list
="ia32-libs lib32asound2-dev lib32stdc++6 lib32z1
229 lib32z1-dev libc6-dev-i386 libc6-i386 g++-multilib"
230 if [ -n "`apt-cache search lib32readline-gplv2-dev 2>/dev/null`" ]; then
231 cmp_list
="${cmp_list} lib32readline-gplv2-dev"
233 cmp_list
="${cmp_list} lib32readline5-dev"
235 sudo apt-get
install $cmp_list
237 tmp
=/tmp
/install-32bit.$$
238 trap 'rm -rf "${tmp}"' EXIT INT TERM QUIT
239 mkdir
-p "${tmp}/apt/lists/partial" "${tmp}/cache" "${tmp}/partial"
240 touch "${tmp}/status"
242 [ -r /etc
/apt
/apt.conf
] && cp /etc
/apt
/apt.conf
"${tmp}/apt/"
243 cat >>"${tmp}/apt/apt.conf" <<EOF
244 Apt::Architecture "i386";
245 Dir::Cache "${tmp}/cache";
246 Dir::Cache::Archives "${tmp}/";
247 Dir::State::Lists "${tmp}/apt/lists/";
248 Dir::State::status "${tmp}/status";
251 # Download 32bit packages
252 echo "Computing list of available 32bit packages..."
253 sudo apt-get
-c="${tmp}/apt/apt.conf" update
255 echo "Downloading available 32bit packages..."
256 sudo apt-get
-c="${tmp}/apt/apt.conf" \
257 --yes --download-only --force-yes --reinstall install \
258 ${lib_list} ${dbg_list}
260 # Open packages, remove everything that is not a library, move the
261 # library to a lib32 directory and package everything as a *.deb file.
262 echo "Repackaging and installing 32bit packages for use on 64bit systems..."
263 for i
in ${lib_list} ${dbg_list}; do
264 orig
="$(echo "${tmp}/${i}"_*_i386.deb)"
265 compat
="$(echo "${orig}" |
266 sed -e 's,\(_[^_/]*_\)i386\(.deb\),-ia32\1amd64\2,')"
267 rm -rf "${tmp}/staging"
268 msg
="$(fakeroot -u sh -exc '
269 # Unpack 32bit Debian archive
271 mkdir -p "'"${tmp}"'/staging
/dpkg
/DEBIAN
"
272 cd "'"${tmp}"'/staging
"
274 tar zCfx dpkg data.tar.gz
275 tar zCfx dpkg/DEBIAN control.tar.gz
277 # Create a posix extended regular expression fragment that will
278 # recognize the includes which have changed. Should be rare,
279 # will almost always be empty.
280 includes=`sed -n -e "s
/^
[0-9a-z]* //g
" \
281 -e "\
,usr
/include
/,p
" dpkg/DEBIAN/md5sums |
282 xargs -n 1 -I FILE /bin/sh -c \
283 "cmp -s dpkg
/FILE
/FILE ||
echo FILE
" |
287 # If empty, set it to not match anything.
288 test -z "$includes" && includes="^
//"
290 # Turn the conflicts into an extended RE for removal from the
292 conflicts=`sed -n -e "/Conflicts
/s
/Conflicts
: *//;T
;s
/, */|
/g
;p
" \
295 # Rename package, change architecture, remove conflicts and dependencies
297 -e "/Package
/s
/$
/-ia32/" \
298 -e "/Architecture
/s
/:.
*$
/: amd64
/" \
299 -e "/Depends
/s
/:.
*/: ia32-libs
/" \
300 -e "/Provides
/s
/($conflicts)(, *)?
//g
;T1
;s
/, *$
//;:1" \
305 # Only keep files that live in "lib
" directories or the includes
308 -e "/\
/lib64\
//d
" -e "/\
/.?bin\
//d
" \
309 -e "\
,$includes,s
,[ /]include
/,&32/,g
;s
,include
/32/,include32
/,g
" \
310 -e "s
, lib
/, lib32
/,g
" \
311 -e "s
,/lib
/,/lib32
/,g
" \
313 -e "\
,^
/usr
/lib32
/debug\
(.
*/lib32\
),s
,^
/usr
/lib32
/debug
,/usr
/lib
/debug
," \
316 # Re-run ldconfig after installation/removal
317 { echo "#!/bin/sh"; echo "[ \"x\$1\" = xconfigure ]&&ldconfig||:"; } \
318 >dpkg
/DEBIAN
/postinst
319 { echo "#!/bin/sh"; echo "[ \"x\$1\" = xremove ]&&ldconfig||:"; } \
321 chmod 755 dpkg
/DEBIAN
/postinst dpkg
/DEBIAN
/postrm
323 # Remove any other control files
324 find dpkg
/DEBIAN
-mindepth 1 "(" -name control
-o -name md5sums
-o \
325 -name postinst
-o -name postrm
")" -o -print |
328 # Remove any files/dirs that live outside of "lib" directories,
329 # or are not in our list of changed includes.
330 find dpkg
-mindepth 1 -regextype posix-extended \
331 "(" -name DEBIAN
-o -name lib
-o -regex "dpkg/($includes)" ")" \
332 -prune -o -print |
tac |
333 xargs -r -n 1 sh
-c "rm \$0 2>/dev/null || rmdir \$0 2>/dev/null || : "
334 find dpkg
-name lib64
-o -name bin
-o -name "?bin" |
335 tac |
xargs -r rm -rf
337 # Remove any symbolic links that were broken by the above steps.
338 find -L dpkg
-type l
-print |
tac |
xargs -r rm -rf
340 # Rename lib to lib32, but keep debug symbols in /usr/lib/debug/usr/lib32
341 # That is where gdb looks for them.
342 find dpkg
-type d
-o -path "*/lib/*" -print |
343 xargs -r -n 1 sh
-c "
344 i=\$(echo \"\${0}\" |
345 sed -e s,/lib/,/lib32/,g \
346 -e s,/usr/lib32/debug\\\\\(.*/lib32\\\\\),/usr/lib/debug\\\\1,);
347 mkdir -p \"\${i%/*}\";
348 mv \"\${0}\" \"\${i}\""
350 # Rename include to include32.
351 [ -d "dpkg/usr/include" ] && mv "dpkg/usr/include" "dpkg/usr/include32"
353 # Prune any empty directories
354 find dpkg
-type d |
tac |
xargs -r -n 1 rmdir 2>/dev
/null ||
:
356 # Create our own Debian package
358 dpkg
--build staging
/dpkg .
' 2>&1)"
359 compat="$(eval echo $(echo "${compat}" |
360 sed -e 's
,_
[^_
/]*_amd64.deb
,_
*_amd64.deb
,'))"
361 [ -r "${compat}" ] || {
363 echo "Failed to build new Debian archive!" >&2
367 msg="$(sudo dpkg -i "${compat}" 2>&1)" && {
368 echo "Installed ${compat##*/}"
371 echo "Skipped ${compat##*/}"
375 # Add symbolic links for developing 32bit code
376 echo "Adding missing symbolic links, enabling 32bit code development..."
377 for i in $(find /lib32 /usr/lib32 -maxdepth 1 -name \*.so.\* |
378 sed -e 's
/[.
]so
[.
][0-9].
*/.so
/' |
380 [ "x${i##*/}" = "xld-linux.so" ] && continue
381 [ -r "$i" ] && continue
382 j="$(ls "$i."* | sed -e 's
/.
*[.
]so
[.
]\
([^.
]*\
)$
/\
1/;t
;d
' |
383 sort -n | tail -n 1)"
384 [ -r "$i.$j" ] || continue
385 sudo ln -s "${i##*/}.$j" "$i"