build.sh revision 868fa2fe829687343ffae624259930155e16dbd8
1#!/bin/bash 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# TODO(mmoss) This currently only works with official builds, since non-official 8# builds don't add the "${BUILDDIR}/installer/" files needed for packaging. 9 10set -e 11if [ "$VERBOSE" ]; then 12 set -x 13fi 14set -u 15 16gen_spec() { 17 rm -f "${SPEC}" 18 # Trunk packages need to install to a custom path so they don't conflict with 19 # release channel packages. 20 local PACKAGE_FILENAME="${PACKAGE}" 21 if [ "$CHANNEL" = "trunk" ] || [ "$CHANNEL" = "asan" ]; then 22 local INSTALLDIR="${INSTALLDIR}-${CHANNEL}" 23 PACKAGE_FILENAME="${PACKAGE}-${CHANNEL}" 24 local MENUNAME="${MENUNAME} (${CHANNEL})" 25 fi 26 process_template "${SCRIPTDIR}/chrome.spec.template" "${SPEC}" 27} 28 29# Setup the installation directory hierachy in the package staging area. 30prep_staging_rpm() { 31 prep_staging_common 32 install -m 755 -d "${STAGEDIR}/etc/cron.daily" 33} 34 35# Put the package contents in the staging area. 36stage_install_rpm() { 37 # Trunk packages need to install to a custom path and with custom filenames 38 # (e.g. not /usr/bin/google-chrome) so they don't conflict with release 39 # channel packages. 40 if [ "$CHANNEL" = "trunk" ] || [ "$CHANNEL" = "asan" ]; then 41 local PACKAGE="${PACKAGE}-${CHANNEL}" 42 local INSTALLDIR="${INSTALLDIR}-${CHANNEL}" 43 # This would ideally be compiled into the app, but that's a bit too 44 # intrusive of a change for these limited use channels, so we'll just hack 45 # it into the wrapper script. The user can still override since it seems to 46 # work to specify --user-data-dir multiple times on the command line, with 47 # the last occurrence winning. 48 local DEFAULT_FLAGS="--user-data-dir=\"\${HOME}/.config/${PACKAGE}\"" 49 local MENUNAME="${MENUNAME} (${CHANNEL})" 50 fi 51 prep_staging_rpm 52 stage_install_common 53 echo "Staging RPM install files in '${STAGEDIR}'..." 54 process_template "${BUILDDIR}/installer/common/rpmrepo.cron" \ 55 "${STAGEDIR}/etc/cron.daily/${PACKAGE}" 56 chmod 755 "${STAGEDIR}/etc/cron.daily/${PACKAGE}" 57} 58 59# Actually generate the package file. 60do_package() { 61 echo "Packaging ${ARCHITECTURE}..." 62 PROVIDES="${PACKAGE}" 63 local REPS="$REPLACES" 64 REPLACES="" 65 for rep in $REPS; do 66 if [ -z "$REPLACES" ]; then 67 REPLACES="$PACKAGE-$rep" 68 else 69 REPLACES="$REPLACES $PACKAGE-$rep" 70 fi 71 done 72 73 # The symbols in libX11.so are not versioned, so when a newer version has new 74 # symbols like _XGetRequest, RPM's find-requires tool does not detect it, and 75 # there is no way to specify a libX11.so version number to prevent 76 # installation on affected distros like OpenSUSE 12.1 and Fedora 16. 77 # Thus there has to be distro-specific conflict here. 78 # TODO(thestig) Remove these in the future when other requirements prevent 79 # installation on affected distros. 80 ADDITIONAL_CONFLICTS="xorg-x11-libX11 < 7.6_1 libX11 < 1.4.99" 81 REPLACES="$REPLACES $ADDITIONAL_CONFLICTS" 82 83 # If we specify a dependecy of foo.so below, we would depend on both the 84 # 32 and 64-bit versions on a 64-bit machine. The current version of RPM 85 # we use is too old and doesn't provide %{_isa}, so we do this manually. 86 if [ "$ARCHITECTURE" = "x86_64" ] ; then 87 local EMPTY_VERSION="()" 88 local PKG_ARCH="(64bit)" 89 elif [ "$ARCHITECTURE" = "i386" ] ; then 90 local EMPTY_VERSION="" 91 local PKG_ARCH="" 92 fi 93 94 # Use find-requires script to make sure the dependencies are complete 95 # (especially libc and libstdc++ versions). Filter out udev to avoid 96 # libudev.so.0 vs. libudev.so.1 mismatches. 97 DETECTED_DEPENDS="$(echo "${BUILDDIR}/chrome" | /usr/lib/rpm/find-requires | 98 grep -v udev)" 99 100 # Compare the expected dependency list to the generated list. 101 BAD_DIFF=0 102 diff "$SCRIPTDIR/expected_deps_$ARCHITECTURE" \ 103 <(echo "${DETECTED_DEPENDS}") || BAD_DIFF=1 104 if [ $BAD_DIFF -ne 0 ] && [ -z "${IGNORE_DEPS_CHANGES:-}" ]; then 105 echo 106 echo "ERROR: Shared library dependencies changed!" 107 echo "If this is intentional, please update:" 108 echo "chrome/installer/linux/rpm/expected_deps_i686" 109 echo "chrome/installer/linux/rpm/expected_deps_x86_64" 110 echo 111 exit $BAD_DIFF 112 fi 113 114 # libgdk_pixbuf is added in LSB 3.2 and no longer explicitly required. 115 # libcairo, libpangocairo, libasound are in LSB 4. and no longer explicitly 116 # required. 117 # xdg-utils is still optional in LSB 4.0. 118 # nss (bundled) is optional in LSB 4.0. 119 # 120 # We want to depend on the system SSL certs so wget can upload crash reports 121 # securely, but there's no common capability between the distros. Bugs filed: 122 # https://qa.mandriva.com/show_bug.cgi?id=55714 123 # https://bugzilla.redhat.com/show_bug.cgi?id=538158 124 # https://bugzilla.novell.com/show_bug.cgi?id=556248 125 DEPENDS="lsb >= 4.0, \ 126 libcurl.so.4${EMPTY_VERSION}${PKG_ARCH}, \ 127 libnss3.so(NSS_3.12.3)${PKG_ARCH}, \ 128 wget, \ 129 xdg-utils, \ 130 zlib, \ 131 $(echo "${DETECTED_DEPENDS}" | tr '\n' ',')" 132 gen_spec 133 134 # Create temporary rpmbuild dirs. 135 RPMBUILD_DIR=$(mktemp -d -t rpmbuild.XXXXXX) || exit 1 136 mkdir -p "$RPMBUILD_DIR/BUILD" 137 mkdir -p "$RPMBUILD_DIR/RPMS" 138 139 # '__os_install_post ${nil}' disables a bunch of automatic post-processing 140 # (brp-compress, etc.), which by default appears to only be enabled on 32-bit, 141 # and which doesn't gain us anything since we already explicitly do all the 142 # compression, symbol stripping, etc. that we want. 143 fakeroot rpmbuild -bb --target="$ARCHITECTURE" --rmspec \ 144 --define "_topdir $RPMBUILD_DIR" \ 145 --define "_binary_payload w9.bzdio" \ 146 --define "__os_install_post %{nil}" \ 147 "${SPEC}" 148 PKGNAME="${PACKAGE}-${CHANNEL}-${VERSION}-${REVISION}" 149 mv "$RPMBUILD_DIR/RPMS/$ARCHITECTURE/${PKGNAME}.${ARCHITECTURE}.rpm" \ 150 "${OUTPUTDIR}" 151 # Make sure the package is world-readable, otherwise it causes problems when 152 # copied to share drive. 153 chmod a+r "${OUTPUTDIR}/${PKGNAME}.$ARCHITECTURE.rpm" 154 rm -rf "$RPMBUILD_DIR" 155} 156 157# Remove temporary files and unwanted packaging output. 158cleanup() { 159 rm -rf "${STAGEDIR}" 160 rm -rf "${TMPFILEDIR}" 161} 162 163usage() { 164 echo "usage: $(basename $0) [-c channel] [-a target_arch] [-o 'dir']" 165 echo " [-b 'dir']" 166 echo "-c channel the package channel (trunk, asan, unstable, beta, stable)" 167 echo "-a arch package architecture (ia32 or x64)" 168 echo "-o dir package output directory [${OUTPUTDIR}]" 169 echo "-b dir build input directory [${BUILDDIR}]" 170 echo "-h this help message" 171} 172 173# Check that the channel name is one of the allowable ones. 174verify_channel() { 175 case $CHANNEL in 176 stable ) 177 CHANNEL=stable 178 REPLACES="unstable beta" 179 ;; 180 unstable|dev|alpha ) 181 CHANNEL=unstable 182 REPLACES="stable beta" 183 ;; 184 testing|beta ) 185 CHANNEL=beta 186 REPLACES="unstable stable" 187 ;; 188 trunk|asan ) 189 # This is a special package, mostly for development testing, so don't make 190 # it replace any installed release packages. 191 REPLACES="dummy" 192 # Setting this to empty will prevent it from updating any existing configs 193 # from release packages. 194 REPOCONFIG="" 195 ;; 196 * ) 197 echo 198 echo "ERROR: '$CHANNEL' is not a valid channel type." 199 echo 200 exit 1 201 ;; 202 esac 203} 204 205process_opts() { 206 while getopts ":o:b:c:a:h" OPTNAME 207 do 208 case $OPTNAME in 209 o ) 210 OUTPUTDIR=$(readlink -f "${OPTARG}") 211 mkdir -p "${OUTPUTDIR}" 212 ;; 213 b ) 214 BUILDDIR=$(readlink -f "${OPTARG}") 215 ;; 216 c ) 217 CHANNEL="$OPTARG" 218 verify_channel 219 ;; 220 a ) 221 TARGETARCH="$OPTARG" 222 ;; 223 h ) 224 usage 225 exit 0 226 ;; 227 \: ) 228 echo "'-$OPTARG' needs an argument." 229 usage 230 exit 1 231 ;; 232 * ) 233 echo "invalid command-line option: $OPTARG" 234 usage 235 exit 1 236 ;; 237 esac 238 done 239} 240 241#========= 242# MAIN 243#========= 244 245SCRIPTDIR=$(readlink -f "$(dirname "$0")") 246OUTPUTDIR="${PWD}" 247STAGEDIR=$(mktemp -d -t rpm.build.XXXXXX) || exit 1 248TMPFILEDIR=$(mktemp -d -t rpm.tmp.XXXXXX) || exit 1 249CHANNEL="trunk" 250# Default target architecture to same as build host. 251if [ "$(uname -m)" = "x86_64" ]; then 252 TARGETARCH="x64" 253else 254 TARGETARCH="ia32" 255fi 256SPEC="${TMPFILEDIR}/chrome.spec" 257 258# call cleanup() on exit 259trap cleanup 0 260process_opts "$@" 261if [ ! "$BUILDDIR" ]; then 262 BUILDDIR=$(readlink -f "${SCRIPTDIR}/../../../../../out/Release") 263fi 264 265source ${BUILDDIR}/installer/common/installer.include 266 267get_version_info 268 269if [ "$CHROMIUM_BUILD" = "_google_chrome" ]; then 270 source "${BUILDDIR}/installer/common/google-chrome.info" 271else 272 source "${BUILDDIR}/installer/common/chromium-browser.info" 273fi 274eval $(sed -e "s/^\([^=]\+\)=\(.*\)$/export \1='\2'/" \ 275 "${BUILDDIR}/installer/theme/BRANDING") 276 277REPOCONFIG="http://dl.google.com/linux/${PACKAGE#google-}/rpm/stable" 278verify_channel 279 280# Make everything happen in the OUTPUTDIR. 281cd "${OUTPUTDIR}" 282 283case "$TARGETARCH" in 284 ia32 ) 285 export ARCHITECTURE="i386" 286 stage_install_rpm 287 ;; 288 x64 ) 289 export ARCHITECTURE="x86_64" 290 stage_install_rpm 291 ;; 292 * ) 293 echo 294 echo "ERROR: Don't know how to build RPMs for '$TARGETARCH'." 295 echo 296 exit 1 297 ;; 298esac 299 300do_package 301