1 #!/bin/bash -e 2 3 # Copyright (c) 2011 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-]gold: enable or disable installation of gold linker" 16 echo "--[no-]lib32: enable or disable installation of 32 bit libraries" 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 --gold) do_inst_gold=1;; 27 --no-gold) do_inst_gold=0;; 28 --lib32) do_inst_lib32=1;; 29 --no-lib32) do_inst_lib32=0;; 30 *) usage;; 31 esac 32 shift 33 done 34 35 install_gold() { 36 # Gold is optional; it's a faster replacement for ld, 37 # and makes life on 2GB machines much more pleasant. 38 39 # First make sure root can access this directory, as that's tripped 40 # up some folks. 41 if sudo touch xyz.$$ 42 then 43 sudo rm xyz.$$ 44 else 45 echo root cannot write to the current directory, not installing gold 46 return 47 fi 48 49 BINUTILS=binutils-2.21 50 BINUTILS_URL=http://ftp.gnu.org/gnu/binutils/$BINUTILS.tar.bz2 51 BINUTILS_SHA1=ef93235588eb443e4c4a77f229a8d131bccaecc6 52 53 test -f $BINUTILS.tar.bz2 || wget $BINUTILS_URL 54 if test "`sha1sum $BINUTILS.tar.bz2|cut -d' ' -f1`" != "$BINUTILS_SHA1" 55 then 56 echo Bad sha1sum for $BINUTILS.tar.bz2 57 exit 1 58 fi 59 60 tar -xjvf $BINUTILS.tar.bz2 61 cd $BINUTILS 62 patch -p1 <<EOF 63 diff -u -r1.103 -r1.103.2.1 64 --- src/gold/object.h 2010/09/08 23:54:51 1.103 65 +++ src/gold/object.h 2011/02/10 01:15:28 1.103.2.1 66 @@ -1,6 +1,6 @@ 67 // object.h -- support for an object file for linking in gold -*- C++ -*- 68 69 -// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 70 +// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 71 // Written by Ian Lance Taylor <iant@google.com>. 72 73 // This file is part of gold. 74 @@ -2165,15 +2165,6 @@ 75 Output_symtab_xindex*, 76 Output_symtab_xindex*); 77 78 - // Clear the local symbol information. 79 - void 80 - clear_local_symbols() 81 - { 82 - this->local_values_.clear(); 83 - this->local_got_offsets_.clear(); 84 - this->local_plt_offsets_.clear(); 85 - } 86 - 87 // Record a mapping from discarded section SHNDX to the corresponding 88 // kept section. 89 void 90 diff -u -r1.60 -r1.60.2.1 91 --- src/gold/reloc.cc 2010/10/14 22:10:22 1.60 92 +++ src/gold/reloc.cc 2011/02/10 01:15:28 1.60.2.1 93 @@ -1,6 +1,6 @@ 94 // reloc.cc -- relocate input files for gold. 95 96 -// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 97 +// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 98 // Written by Ian Lance Taylor <iant@google.com>. 99 100 // This file is part of gold. 101 @@ -685,9 +685,6 @@ 102 // Write out the local symbols. 103 this->write_local_symbols(of, layout->sympool(), layout->dynpool(), 104 layout->symtab_xindex(), layout->dynsym_xindex()); 105 - 106 - // We should no longer need the local symbol values. 107 - this->clear_local_symbols(); 108 } 109 110 // Sort a Read_multiple vector by file offset. 111 EOF 112 ./configure --prefix=/usr/local/gold --enable-gold --enable-threads 113 make maybe-all-binutils maybe-all-gold -j4 114 if sudo make maybe-install-binutils maybe-install-gold 115 then 116 # Still need to figure out graceful way of pointing gyp to use 117 # /usr/local/gold/bin/ld without requiring him to set environment 118 # variables. That will go into bootstrap-linux.sh when it's ready. 119 echo "Installing gold as /usr/bin/ld." 120 echo "To uninstall, do 'cd /usr/bin; sudo rm ld; sudo mv ld.orig ld'" 121 test -f /usr/bin/ld && test ! -f /usr/bin/ld.orig && \ 122 sudo mv /usr/bin/ld /usr/bin/ld.orig 123 sudo strip /usr/local/gold/bin/ld 124 sudo ln -fs /usr/local/gold/bin/ld /usr/bin/ld.gold 125 sudo ln -fs /usr/bin/ld.gold /usr/bin/ld 126 else 127 echo "make install failed, not installing gold" 128 fi 129 } 130 131 if ! egrep -q \ 132 'Ubuntu (8\.04|8\.10|9\.04|9\.10|10\.04|10\.10|karmic|lucid|maverick)' \ 133 /etc/issue; then 134 echo "Only Ubuntu 8.04 (hardy) through 10.10 (maverick) are currently" \ 135 "supported" >&2 136 exit 1 137 fi 138 139 if ! uname -m | egrep -q "i686|x86_64"; then 140 echo "Only x86 architectures are currently supported" >&2 141 exit 142 fi 143 144 if [ "x$(id -u)" != x0 ]; then 145 echo "Running as non-root user." 146 echo "You might have to enter your password one or more times for 'sudo'." 147 echo 148 fi 149 150 # Packages needed for chromeos only 151 chromeos_dev_list="libpulse-dev" 152 153 # Packages need for development 154 dev_list="bison fakeroot flex g++ gperf libapache2-mod-php5 libasound2-dev 155 libbz2-dev libcairo2-dev libdbus-glib-1-dev libgconf2-dev 156 libgl1-mesa-dev libglu1-mesa-dev libglib2.0-dev libgnome-keyring-dev 157 libgtk2.0-dev libjpeg62-dev libnspr4-dev libnss3-dev libpam0g-dev 158 libsctp-dev libsqlite3-dev libxslt1-dev libxss-dev libxtst-dev 159 mesa-common-dev msttcorefonts patch perl php5-cgi pkg-config python 160 python-dev rpm subversion ttf-dejavu-core ttf-kochi-gothic 161 ttf-kochi-mincho wdiff libcurl4-gnutls-dev 162 $chromeos_dev_list" 163 164 # Run-time libraries required by chromeos only 165 chromeos_lib_list="libpulse0 libbz2-1.0 libcurl4-gnutls-dev" 166 167 # Full list of required run-time libraries 168 lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libdbus-glib-1-2 libexpat1 169 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0 libgtk2.0-0 170 libnspr4-0d libnss3-1d libpam0g libpango1.0-0 libpcre3 libpixman-1-0 171 libpng12-0 libstdc++6 libsqlite3-0 libx11-6 libxau6 libxcb1 172 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6 libxext6 libxfixes3 173 libxi6 libxinerama1 libxrandr2 libxrender1 libxtst6 zlib1g 174 $chromeos_lib_list" 175 176 # Debugging symbols for all of the run-time libraries 177 dbg_list="libatk1.0-dbg libc6-dbg libcairo2-dbg 178 libfontconfig1-dbg libglib2.0-0-dbg libgtk2.0-0-dbg libnspr4-0d-dbg 179 libnss3-1d-dbg libpango1.0-0-dbg libpcre3-dbg libpixman-1-0-dbg 180 libx11-6-dbg libxau6-dbg libxcb1-dbg libxcomposite1-dbg 181 libxcursor1-dbg libxdamage1-dbg libxdmcp6-dbg libxext6-dbg 182 libxfixes3-dbg libxi6-dbg libxinerama1-dbg libxrandr2-dbg 183 libxrender1-dbg libxtst6-dbg zlib1g-dbg" 184 185 # CUPS package changed its name from hardy to the next version. Include 186 # proper package here depending on the system. 187 if egrep -q 'Ubuntu (8\.04|8\.10)' /etc/issue; then 188 dev_list="${dev_list} libcupsys2-dev" 189 else 190 dev_list="${dev_list} libcups2-dev" 191 fi 192 193 # apache2.2-bin package was introduced in karmic. 194 if egrep -q 'Ubuntu (8\.04|8\.10|9\.04)' /etc/issue; then 195 dev_list="${dev_list} apache2" 196 else 197 dev_list="${dev_list} apache2.2-bin" 198 fi 199 200 # Waits for the user to press 'Y' or 'N'. Either uppercase of lowercase is 201 # accepted. Returns 0 for 'Y' and 1 for 'N'. If an optional parameter has 202 # been provided to yes_no(), the function also accepts RETURN as a user input. 203 # The parameter specifies the exit code that should be returned in that case. 204 # The function will echo the user's selection followed by a newline character. 205 # Users can abort the function by pressing CTRL-C. This will call "exit 1". 206 yes_no() { 207 local c 208 while :; do 209 c="$(trap 'stty echo -iuclc icanon 2>/dev/null' EXIT INT TERM QUIT 210 stty -echo iuclc -icanon 2>/dev/null 211 dd count=1 bs=1 2>/dev/null | od -An -tx1)" 212 case "$c" in 213 " 0a") if [ -n "$1" ]; then 214 [ $1 -eq 0 ] && echo "Y" || echo "N" 215 return $1 216 fi 217 ;; 218 " 79") echo "Y" 219 return 0 220 ;; 221 " 6e") echo "N" 222 return 1 223 ;; 224 "") echo "Aborted" >&2 225 exit 1 226 ;; 227 *) # The user pressed an unrecognized key. As we are not echoing 228 # any incorrect user input, alert the user by ringing the bell. 229 (tput bel) 2>/dev/null 230 ;; 231 esac 232 done 233 } 234 235 if test "$do_inst_syms" = "" 236 then 237 echo "This script installs all tools and libraries needed to build Chromium." 238 echo "" 239 echo "For most of the libraries, it can also install debugging symbols, which" 240 echo "will allow you to debug code in the system libraries. Most developers" 241 echo "won't need these symbols." 242 echo -n "Do you want me to install them for you (y/N) " 243 if yes_no 1; then 244 do_inst_syms=1 245 fi 246 fi 247 if test "$do_inst_syms" = "1"; then 248 echo "Installing debugging symbols." 249 else 250 echo "Skipping installation of debugging symbols." 251 dbg_list= 252 fi 253 254 sudo apt-get update 255 256 # We initially run "apt-get" with the --reinstall option and parse its output. 257 # This way, we can find all the packages that need to be newly installed 258 # without accidentally promoting any packages from "auto" to "manual". 259 # We then re-run "apt-get" with just the list of missing packages. 260 echo "Finding missing packages..." 261 packages="${dev_list} ${lib_list} ${dbg_list}" 262 # Intentially leaving $packages unquoted so it's more readable. 263 echo "Packages required: " $packages 264 echo 265 new_list_cmd="sudo apt-get install --reinstall $(echo $packages)" 266 if new_list="$(yes n | LANG=C $new_list_cmd)"; then 267 # We probably never hit this following line. 268 echo "No missing packages, and the packages are up-to-date." 269 elif [ $? -eq 1 ]; then 270 # We expect apt-get to have exit status of 1. 271 # This indicates that we canceled the install with "yes n|". 272 new_list=$(echo "$new_list" | 273 sed -e '1,/The following NEW packages will be installed:/d;s/^ //;t;d') 274 new_list=$(echo "$new_list" | sed 's/ *$//') 275 if [ -z "$new_list" ] ; then 276 echo "No missing packages, and the packages are up-to-date." 277 else 278 echo "Installing missing packages: $new_list." 279 sudo apt-get install ${new_list} 280 fi 281 echo 282 else 283 # An apt-get exit status of 100 indicates that a real error has occurred. 284 285 # I am intentionally leaving out the '"'s around new_list_cmd, 286 # as this makes it easier to cut and paste the output 287 echo "The following command failed: " ${new_list_cmd} 288 echo 289 echo "It produces the following output:" 290 yes n | $new_list_cmd || true 291 echo 292 echo "You will have to install the above packages yourself." 293 echo 294 exit 100 295 fi 296 297 # Some operating systems already ship gold (on recent Debian and 298 # Ubuntu you can do "apt-get install binutils-gold" to get it), but 299 # older releases didn't. Additionally, gold 2.20 (included in Ubuntu 300 # Lucid) makes binaries that just segfault, and 2.20.1 does not support 301 # --map-whole-files. 302 # So install from source if we don't have a good version. 303 304 case `ld --version` in 305 *gold*2.2[1-9].*) ;; 306 * ) 307 if test "$do_inst_gold" = "" 308 then 309 echo "Gold is a new linker that links Chrome 5x faster than ld." 310 echo "Don't use it if you need to link other apps (e.g. valgrind, wine)" 311 echo -n "REPLACE SYSTEM LINKER ld with gold and back up ld? (y/N) " 312 if yes_no 1; then 313 do_inst_gold=1 314 fi 315 fi 316 if test "$do_inst_gold" = "1" 317 then 318 # If the system provides a good version of gold, just install it. 319 if apt-cache show binutils-gold | grep -Eq 'Version: 2.2[1-9].*'; then 320 echo "Installing binutils-gold. Backing up ld as ld.single." 321 sudo apt-get install binutils-gold 322 else 323 # FIXME: avoid installing as /usr/bin/ld 324 echo "Building binutils. Backing up ld as ld.orig." 325 install_gold || exit 99 326 fi 327 else 328 echo "Not installing gold." 329 fi 330 esac 331 332 # Install 32bit backwards compatibility support for 64bit systems 333 if [ "$(uname -m)" = "x86_64" ]; then 334 if test "$do_inst_lib32" = "" 335 then 336 echo "Installing 32bit libraries not already provided by the system" 337 echo 338 echo "This is only needed to build a 32-bit Chrome on your 64-bit system." 339 echo 340 echo "While we only need to install a relatively small number of library" 341 echo "files, we temporarily need to download a lot of large *.deb packages" 342 echo "that contain these files. We will create new *.deb packages that" 343 echo "include just the 32bit libraries. These files will then be found on" 344 echo "your system in places like /lib32, /usr/lib32, /usr/lib/debug/lib32," 345 echo "/usr/lib/debug/usr/lib32. If you ever need to uninstall these files," 346 echo "look for packages named *-ia32.deb." 347 echo "Do you want me to download all packages needed to build new 32bit" 348 echo -n "package files (Y/n) " 349 if yes_no 0; then 350 do_inst_lib32=1 351 fi 352 fi 353 if test "$do_inst_lib32" != "1" 354 then 355 echo "Exiting without installing any 32bit libraries." 356 exit 0 357 fi 358 359 # Standard 32bit compatibility libraries 360 echo "First, installing the limited existing 32-bit support..." 361 cmp_list="ia32-libs lib32asound2-dev lib32readline5-dev lib32stdc++6 lib32z1 362 lib32z1-dev libc6-dev-i386 libc6-i386 g++-multilib" 363 sudo apt-get install $cmp_list 364 365 tmp=/tmp/install-32bit.$$ 366 trap 'rm -rf "${tmp}"' EXIT INT TERM QUIT 367 mkdir -p "${tmp}/apt/lists/partial" "${tmp}/cache" "${tmp}/partial" 368 touch "${tmp}/status" 369 370 [ -r /etc/apt/apt.conf ] && cp /etc/apt/apt.conf "${tmp}/apt/" 371 cat >>"${tmp}/apt/apt.conf" <<EOF 372 Apt::Architecture "i386"; 373 Dir::Cache "${tmp}/cache"; 374 Dir::Cache::Archives "${tmp}/"; 375 Dir::State::Lists "${tmp}/apt/lists/"; 376 Dir::State::status "${tmp}/status"; 377 EOF 378 379 # Download 32bit packages 380 echo "Computing list of available 32bit packages..." 381 sudo apt-get -c="${tmp}/apt/apt.conf" update 382 383 echo "Downloading available 32bit packages..." 384 sudo apt-get -c="${tmp}/apt/apt.conf" \ 385 --yes --download-only --force-yes --reinstall install \ 386 ${lib_list} ${dbg_list} 387 388 # Open packages, remove everything that is not a library, move the 389 # library to a lib32 directory and package everything as a *.deb file. 390 echo "Repackaging and installing 32bit packages for use on 64bit systems..." 391 for i in ${lib_list} ${dbg_list}; do 392 orig="$(echo "${tmp}/${i}"_*_i386.deb)" 393 compat="$(echo "${orig}" | 394 sed -e 's,\(_[^_/]*_\)i386\(.deb\),-ia32\1amd64\2,')" 395 rm -rf "${tmp}/staging" 396 msg="$(fakeroot -u sh -exc ' 397 # Unpack 32bit Debian archive 398 umask 022 399 mkdir -p "'"${tmp}"'/staging/dpkg/DEBIAN" 400 cd "'"${tmp}"'/staging" 401 ar x "'${orig}'" 402 tar zCfx dpkg data.tar.gz 403 tar zCfx dpkg/DEBIAN control.tar.gz 404 405 # Create a posix extended regular expression fragment that will 406 # recognize the includes which have changed. Should be rare, 407 # will almost always be empty. 408 includes=`sed -n -e "s/^[0-9a-z]* //g" \ 409 -e "\,usr/include/,p" dpkg/DEBIAN/md5sums | 410 xargs -n 1 -I FILE /bin/sh -c \ 411 "cmp -s dpkg/FILE /FILE || echo FILE" | 412 tr "\n" "|" | 413 sed -e "s,|$,,"` 414 415 # If empty, set it to not match anything. 416 test -z "$includes" && includes="^//" 417 418 # Turn the conflicts into an extended RE for removal from the 419 # Provides line. 420 conflicts=`sed -n -e "/Conflicts/s/Conflicts: *//;T;s/, */|/g;p" \ 421 dpkg/DEBIAN/control` 422 423 # Rename package, change architecture, remove conflicts and dependencies 424 sed -r -i \ 425 -e "/Package/s/$/-ia32/" \ 426 -e "/Architecture/s/:.*$/: amd64/" \ 427 -e "/Depends/s/:.*/: ia32-libs/" \ 428 -e "/Provides/s/($conflicts)(, *)?//g;T1;s/, *$//;:1" \ 429 -e "/Recommends/d" \ 430 -e "/Conflicts/d" \ 431 dpkg/DEBIAN/control 432 433 # Only keep files that live in "lib" directories or the includes 434 # that have changed. 435 sed -r -i \ 436 -e "/\/lib64\//d" -e "/\/.?bin\//d" \ 437 -e "\,$includes,s,[ /]include/,&32/,g;s,include/32/,include32/,g" \ 438 -e "s, lib/, lib32/,g" \ 439 -e "s,/lib/,/lib32/,g" \ 440 -e "t;d" \ 441 -e "\,^/usr/lib32/debug\(.*/lib32\),s,^/usr/lib32/debug,/usr/lib/debug," \ 442 dpkg/DEBIAN/md5sums 443 444 # Re-run ldconfig after installation/removal 445 { echo "#!/bin/sh"; echo "[ \"x\$1\" = xconfigure ]&&ldconfig||:"; } \ 446 >dpkg/DEBIAN/postinst 447 { echo "#!/bin/sh"; echo "[ \"x\$1\" = xremove ]&&ldconfig||:"; } \ 448 >dpkg/DEBIAN/postrm 449 chmod 755 dpkg/DEBIAN/postinst dpkg/DEBIAN/postrm 450 451 # Remove any other control files 452 find dpkg/DEBIAN -mindepth 1 "(" -name control -o -name md5sums -o \ 453 -name postinst -o -name postrm ")" -o -print | 454 xargs -r rm -rf 455 456 # Remove any files/dirs that live outside of "lib" directories, 457 # or are not in our list of changed includes. 458 find dpkg -mindepth 1 -regextype posix-extended \ 459 "(" -name DEBIAN -o -name lib -o -regex "dpkg/($includes)" ")" \ 460 -prune -o -print | tac | 461 xargs -r -n 1 sh -c "rm \$0 2>/dev/null || rmdir \$0 2>/dev/null || : " 462 find dpkg -name lib64 -o -name bin -o -name "?bin" | 463 tac | xargs -r rm -rf 464 465 # Remove any symbolic links that were broken by the above steps. 466 find -L dpkg -type l -print | tac | xargs -r rm -rf 467 468 # Rename lib to lib32, but keep debug symbols in /usr/lib/debug/usr/lib32 469 # That is where gdb looks for them. 470 find dpkg -type d -o -path "*/lib/*" -print | 471 xargs -r -n 1 sh -c " 472 i=\$(echo \"\${0}\" | 473 sed -e s,/lib/,/lib32/,g \ 474 -e s,/usr/lib32/debug\\\\\(.*/lib32\\\\\),/usr/lib/debug\\\\1,); 475 mkdir -p \"\${i%/*}\"; 476 mv \"\${0}\" \"\${i}\"" 477 478 # Rename include to include32. 479 [ -d "dpkg/usr/include" ] && mv "dpkg/usr/include" "dpkg/usr/include32" 480 481 # Prune any empty directories 482 find dpkg -type d | tac | xargs -r -n 1 rmdir 2>/dev/null || : 483 484 # Create our own Debian package 485 cd .. 486 dpkg --build staging/dpkg .' 2>&1)" 487 compat="$(eval echo $(echo "${compat}" | 488 sed -e 's,_[^_/]*_amd64.deb,_*_amd64.deb,'))" 489 [ -r "${compat}" ] || { 490 echo "${msg}" >&2 491 echo "Failed to build new Debian archive!" >&2 492 exit 1 493 } 494 495 msg="$(sudo dpkg -i "${compat}" 2>&1)" && { 496 echo "Installed ${compat##*/}" 497 } || { 498 # echo "${msg}" >&2 499 echo "Skipped ${compat##*/}" 500 } 501 done 502 503 # Add symbolic links for developing 32bit code 504 echo "Adding missing symbolic links, enabling 32bit code development..." 505 for i in $(find /lib32 /usr/lib32 -maxdepth 1 -name \*.so.\* | 506 sed -e 's/[.]so[.][0-9].*/.so/' | 507 sort -u); do 508 [ "x${i##*/}" = "xld-linux.so" ] && continue 509 [ -r "$i" ] && continue 510 j="$(ls "$i."* | sed -e 's/.*[.]so[.]\([^.]*\)$/\1/;t;d' | 511 sort -n | tail -n 1)" 512 [ -r "$i.$j" ] || continue 513 sudo ln -s "${i##*/}.$j" "$i" 514 done 515 fi 516