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