build.sh revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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 16# Create the Debian changelog file needed by dpkg-gencontrol. This just adds a 17# placeholder change, indicating it is the result of an automatic build. 18# TODO(mmoss) Release packages should create something meaningful for a 19# changelog, but simply grabbing the actual 'svn log' is way too verbose. Do we 20# have any type of "significant/visible changes" log that we could use for this? 21gen_changelog() { 22 rm -f "${DEB_CHANGELOG}" 23 process_template "${SCRIPTDIR}/changelog.template" "${DEB_CHANGELOG}" 24 debchange -a --nomultimaint -m --changelog "${DEB_CHANGELOG}" \ 25 "Release Notes: ${RELEASENOTES}" 26 GZLOG="${STAGEDIR}/usr/share/doc/${PACKAGE}-${CHANNEL}/changelog.gz" 27 mkdir -p "$(dirname "${GZLOG}")" 28 gzip -9 -c "${DEB_CHANGELOG}" > "${GZLOG}" 29 chmod 644 "${GZLOG}" 30} 31 32# Create the Debian control file needed by dpkg-deb. 33gen_control() { 34 dpkg-gencontrol -v"${VERSIONFULL}" -c"${DEB_CONTROL}" -l"${DEB_CHANGELOG}" \ 35 -f"${DEB_FILES}" -p"${PACKAGE}-${CHANNEL}" -P"${STAGEDIR}" \ 36 -O > "${STAGEDIR}/DEBIAN/control" 37 rm -f "${DEB_CONTROL}" 38} 39 40# Setup the installation directory hierachy in the package staging area. 41prep_staging_debian() { 42 prep_staging_common 43 install -m 755 -d "${STAGEDIR}/DEBIAN" \ 44 "${STAGEDIR}/etc/cron.daily" \ 45 "${STAGEDIR}/usr/share/menu" \ 46 "${STAGEDIR}/usr/share/doc/${PACKAGE}" 47} 48 49# Put the package contents in the staging area. 50stage_install_debian() { 51 if [ "$CHANNEL" != "stable" ]; then 52 # Avoid file collisions between channels. 53 local PACKAGE="${PACKAGE}-${CHANNEL}" 54 local INSTALLDIR="${INSTALLDIR}-${CHANNEL}" 55 56 # Make it possible to distinguish between menu entries 57 # for different channels. 58 local MENUNAME="${MENUNAME} (${CHANNEL})" 59 60 # This would ideally be compiled into the app, but that's a bit too 61 # intrusive of a change for these limited use channels, so we'll just hack 62 # it into the wrapper script. The user can still override since it seems to 63 # work to specify --user-data-dir multiple times on the command line, with 64 # the last occurrence winning. 65 local SXS_USER_DATA_DIR="\${XDG_CONFIG_HOME:-\${HOME}/.config}/${PACKAGE}" 66 local DEFAULT_FLAGS="--user-data-dir=\"${SXS_USER_DATA_DIR}\"" 67 fi 68 prep_staging_debian 69 stage_install_common 70 echo "Staging Debian install files in '${STAGEDIR}'..." 71 install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/cron" 72 process_template "${BUILDDIR}/installer/common/repo.cron" \ 73 "${STAGEDIR}/${INSTALLDIR}/cron/${PACKAGE}" 74 chmod 755 "${STAGEDIR}/${INSTALLDIR}/cron/${PACKAGE}" 75 pushd "${STAGEDIR}/etc/cron.daily/" 76 ln -snf "${INSTALLDIR}/cron/${PACKAGE}" "${PACKAGE}" 77 popd 78 process_template "${BUILDDIR}/installer/debian/debian.menu" \ 79 "${STAGEDIR}/usr/share/menu/${PACKAGE}.menu" 80 chmod 644 "${STAGEDIR}/usr/share/menu/${PACKAGE}.menu" 81 process_template "${BUILDDIR}/installer/debian/postinst" \ 82 "${STAGEDIR}/DEBIAN/postinst" 83 chmod 755 "${STAGEDIR}/DEBIAN/postinst" 84 process_template "${BUILDDIR}/installer/debian/prerm" \ 85 "${STAGEDIR}/DEBIAN/prerm" 86 chmod 755 "${STAGEDIR}/DEBIAN/prerm" 87 process_template "${BUILDDIR}/installer/debian/postrm" \ 88 "${STAGEDIR}/DEBIAN/postrm" 89 chmod 755 "${STAGEDIR}/DEBIAN/postrm" 90} 91 92# Actually generate the package file. 93do_package() { 94 echo "Packaging ${ARCHITECTURE}..." 95 PREDEPENDS="$COMMON_PREDEPS" 96 DEPENDS="${COMMON_DEPS}" 97 # Trunk is a special package, mostly for development testing, so don't make 98 # it replace any installed release packages. 99 if [ "$CHANNEL" != "trunk" ] && [ "$CHANNEL" != "asan" ]; then 100 REPLACES="${PACKAGE}" 101 CONFLICTS="${PACKAGE}" 102 PROVIDES="${PACKAGE}, www-browser" 103 fi 104 gen_changelog 105 process_template "${SCRIPTDIR}/control.template" "${DEB_CONTROL}" 106 export DEB_HOST_ARCH="${ARCHITECTURE}" 107 if [ -f "${DEB_CONTROL}" ]; then 108 gen_control 109 fi 110 fakeroot dpkg-deb -Zlzma -b "${STAGEDIR}" . 111} 112 113# Remove temporary files and unwanted packaging output. 114cleanup() { 115 echo "Cleaning..." 116 rm -rf "${STAGEDIR}" 117 rm -rf "${TMPFILEDIR}" 118} 119 120usage() { 121 echo "usage: $(basename $0) [-c channel] [-a target_arch] [-o 'dir'] " 122 echo " [-b 'dir']" 123 echo "-c channel the package channel (trunk, asan, unstable, beta, stable)" 124 echo "-a arch package architecture (ia32 or x64)" 125 echo "-o dir package output directory [${OUTPUTDIR}]" 126 echo "-b dir build input directory [${BUILDDIR}]" 127 echo "-h this help message" 128} 129 130# Check that the channel name is one of the allowable ones. 131verify_channel() { 132 case $CHANNEL in 133 stable ) 134 CHANNEL=stable 135 RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Stable%20updates" 136 ;; 137 unstable|dev|alpha ) 138 CHANNEL=unstable 139 RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Dev%20updates" 140 ;; 141 testing|beta ) 142 CHANNEL=beta 143 RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Beta%20updates" 144 ;; 145 trunk|asan ) 146 # Setting this to empty will prevent it from updating any existing configs 147 # from release packages. 148 REPOCONFIG="" 149 RELEASENOTES="http://googlechromereleases.blogspot.com/" 150 ;; 151 * ) 152 echo 153 echo "ERROR: '$CHANNEL' is not a valid channel type." 154 echo 155 exit 1 156 ;; 157 esac 158} 159 160process_opts() { 161 while getopts ":o:b:c:a:h" OPTNAME 162 do 163 case $OPTNAME in 164 o ) 165 OUTPUTDIR=$(readlink -f "${OPTARG}") 166 mkdir -p "${OUTPUTDIR}" 167 ;; 168 b ) 169 BUILDDIR=$(readlink -f "${OPTARG}") 170 ;; 171 c ) 172 CHANNEL="$OPTARG" 173 ;; 174 a ) 175 TARGETARCH="$OPTARG" 176 ;; 177 h ) 178 usage 179 exit 0 180 ;; 181 \: ) 182 echo "'-$OPTARG' needs an argument." 183 usage 184 exit 1 185 ;; 186 * ) 187 echo "invalid command-line option: $OPTARG" 188 usage 189 exit 1 190 ;; 191 esac 192 done 193} 194 195#========= 196# MAIN 197#========= 198 199SCRIPTDIR=$(readlink -f "$(dirname "$0")") 200OUTPUTDIR="${PWD}" 201STAGEDIR=$(mktemp -d -t deb.build.XXXXXX) || exit 1 202TMPFILEDIR=$(mktemp -d -t deb.tmp.XXXXXX) || exit 1 203DEB_CHANGELOG="${TMPFILEDIR}/changelog" 204DEB_FILES="${TMPFILEDIR}/files" 205DEB_CONTROL="${TMPFILEDIR}/control" 206CHANNEL="trunk" 207# Default target architecture to same as build host. 208if [ "$(uname -m)" = "x86_64" ]; then 209 TARGETARCH="x64" 210else 211 TARGETARCH="ia32" 212fi 213 214# call cleanup() on exit 215trap cleanup 0 216process_opts "$@" 217if [ ! "$BUILDDIR" ]; then 218 BUILDDIR=$(readlink -f "${SCRIPTDIR}/../../../../../out/Release") 219fi 220 221source ${BUILDDIR}/installer/common/installer.include 222 223get_version_info 224VERSIONFULL="${VERSION}-${PACKAGE_RELEASE}" 225 226if [ "$CHROMIUM_BUILD" = "_google_chrome" ]; then 227 source "${BUILDDIR}/installer/common/google-chrome.info" 228else 229 source "${BUILDDIR}/installer/common/chromium-browser.info" 230fi 231eval $(sed -e "s/^\([^=]\+\)=\(.*\)$/export \1='\2'/" \ 232 "${BUILDDIR}/installer/theme/BRANDING") 233 234REPOCONFIG="deb http://dl.google.com/linux/chrome/deb/ stable main" 235verify_channel 236 237# Some Debian packaging tools want these set. 238export DEBFULLNAME="${MAINTNAME}" 239export DEBEMAIL="${MAINTMAIL}" 240 241# We'd like to eliminate more of these deps by relying on the 'lsb' package, but 242# that brings in tons of unnecessary stuff, like an mta and rpm. Until that full 243# 'lsb' package is installed by default on DEB distros, we'll have to stick with 244# the LSB sub-packages, to avoid pulling in all that stuff that's not installed 245# by default. 246 247# Need a dummy debian/control file for dpkg-shlibdeps. 248DUMMY_STAGING_DIR="${TMPFILEDIR}/dummy_staging" 249mkdir "$DUMMY_STAGING_DIR" 250cd "$DUMMY_STAGING_DIR" 251mkdir debian 252touch debian/control 253 254# Generate the dependencies, 255# TODO(mmoss): This is a workaround for a problem where dpkg-shlibdeps was 256# resolving deps using some of our build output shlibs (i.e. 257# out/Release/lib.target/libfreetype.so.6), and was then failing with: 258# dpkg-shlibdeps: error: no dependency information found for ... 259# It's not clear if we ever want to look in LD_LIBRARY_PATH to resolve deps, 260# but it seems that we don't currently, so this is the most expediant fix. 261SAVE_LDLP=${LD_LIBRARY_PATH:-} 262unset LD_LIBRARY_PATH 263DPKG_SHLIB_DEPS=$(dpkg-shlibdeps -O "$BUILDDIR/chrome" 2> /dev/null | \ 264 sed 's/^shlibs:Depends=//') 265if [ -n "$SAVE_LDLP" ]; then 266 LD_LIBRARY_PATH=$SAVE_LDLP 267fi 268 269# Format it nicely and save it for comparison. 270# The grep -v is for a duplicate libc6 dep caused by Lucid glibc silliness. 271echo "$DPKG_SHLIB_DEPS" | sed 's/, /\n/g' | \ 272 grep -v '^libc6 (>= 2.3.6-6~)$' > actual 273 274# Compare the expected dependency list to the generate list. 275BAD_DIFF=0 276diff "$SCRIPTDIR/expected_deps" actual || BAD_DIFF=1 277if [ $BAD_DIFF -ne 0 ] && [ -z "${IGNORE_DEPS_CHANGES:-}" ]; then 278 echo 279 echo "ERROR: Shared library dependencies changed!" 280 echo "If this is intentional, please update:" 281 echo "chrome/installer/linux/debian/expected_deps" 282 echo 283 exit $BAD_DIFF 284fi 285rm -rf "$DUMMY_STAGING_DIR" 286 287# Additional dependencies not in the dpkg-shlibdeps output. 288# Pull a more recent version of NSS than required by runtime linking, for 289# security and stability updates in NSS. 290ADDITION_DEPS="ca-certificates, libcurl3, libnss3 (>= 3.14.3), \ 291 lsb-base (>=3.2), xdg-utils (>= 1.0.2), wget" 292 293# Fix-up libnspr dependency due to renaming in Ubuntu (the old package still 294# exists, but it was moved to "universe" repository, which isn't installed by 295# default). 296DPKG_SHLIB_DEPS=$(sed \ 297 's/\(libnspr4-0d ([^)]*)\), /\1 | libnspr4 (>= 4.9.5-0ubuntu0), /g' \ 298 <<< $DPKG_SHLIB_DEPS) 299 300# Fix-up libudev dependency because Ubuntu 13.04 has libudev1 instead of 301# libudev0. 302DPKG_SHLIB_DEPS=$(sed 's/\(libudev0 ([^)]*)\), /\1 | libudev1 (>= 198), /g' \ 303 <<< $DPKG_SHLIB_DEPS) 304 305COMMON_DEPS="${DPKG_SHLIB_DEPS}, ${ADDITION_DEPS}" 306COMMON_PREDEPS="dpkg (>= 1.14.0)" 307 308 309# Make everything happen in the OUTPUTDIR. 310cd "${OUTPUTDIR}" 311 312case "$TARGETARCH" in 313 ia32 ) 314 export ARCHITECTURE="i386" 315 stage_install_debian 316 ;; 317 x64 ) 318 export ARCHITECTURE="amd64" 319 stage_install_debian 320 ;; 321 * ) 322 echo 323 echo "ERROR: Don't know how to build DEBs for '$TARGETARCH'." 324 echo 325 exit 1 326 ;; 327esac 328 329do_package 330