build.sh revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
18483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita#!/bin/bash 28483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# 38483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# Copyright (c) 2012 The Chromium Authors. All rights reserved. 48483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# Use of this source code is governed by a BSD-style license that can be 58483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# found in the LICENSE file. 68483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita 78483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# TODO(mmoss) This currently only works with official builds, since non-official 88483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# builds don't add the "${BUILDDIR}/installer/" files needed for packaging. 98483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita 108483326704eff3b6a5fcce3f36d857a9779a4dd2fmalitaset -e 118483326704eff3b6a5fcce3f36d857a9779a4dd2fmalitaif [ "$VERBOSE" ]; then 128483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita set -x 138483326704eff3b6a5fcce3f36d857a9779a4dd2fmalitafi 148483326704eff3b6a5fcce3f36d857a9779a4dd2fmalitaset -u 158483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita 168483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# Create the Debian changelog file needed by dpkg-gencontrol. This just adds a 178483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# placeholder change, indicating it is the result of an automatic build. 188483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# TODO(mmoss) Release packages should create something meaningful for a 198483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# changelog, but simply grabbing the actual 'svn log' is way too verbose. Do we 208483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# have any type of "significant/visible changes" log that we could use for this? 218483326704eff3b6a5fcce3f36d857a9779a4dd2fmalitagen_changelog() { 228483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita rm -f "${DEB_CHANGELOG}" 238483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita process_template "${SCRIPTDIR}/changelog.template" "${DEB_CHANGELOG}" 248483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita debchange -a --nomultimaint -m --changelog "${DEB_CHANGELOG}" \ 258483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita "Release Notes: ${RELEASENOTES}" 268483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # Trunk packages need to install to a custom path and with custom filenames 278483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # (e.g. not /usr/bin/google-chrome) so they don't conflict with release 288483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # channel packages. 298483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita if [ "$CHANNEL" = "trunk" ] || [ "$CHANNEL" = "asan" ]; then 308483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita local PACKAGE="${PACKAGE}-${CHANNEL}" 318483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita fi 328483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita GZLOG="${STAGEDIR}/usr/share/doc/${PACKAGE}/changelog.gz" 338483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita mkdir -p "$(dirname "${GZLOG}")" 348483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita gzip -9 -c "${DEB_CHANGELOG}" > "${GZLOG}" 358483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita chmod 644 "${GZLOG}" 368483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita} 378483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita 388483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# Create the Debian control file needed by dpkg-deb. 398483326704eff3b6a5fcce3f36d857a9779a4dd2fmalitagen_control() { 408483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita dpkg-gencontrol -v"${VERSIONFULL}" -c"${DEB_CONTROL}" -l"${DEB_CHANGELOG}" \ 418483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita -f"${DEB_FILES}" -p"${PACKAGE}-${CHANNEL}" -P"${STAGEDIR}" \ 428483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita -O > "${STAGEDIR}/DEBIAN/control" 438483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita rm -f "${DEB_CONTROL}" 448483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita} 458483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita 468483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# Setup the installation directory hierachy in the package staging area. 478483326704eff3b6a5fcce3f36d857a9779a4dd2fmalitaprep_staging_debian() { 488483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita prep_staging_common 498483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita install -m 755 -d "${STAGEDIR}/DEBIAN" \ 508483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita "${STAGEDIR}/etc/cron.daily" \ 518483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita "${STAGEDIR}/usr/share/menu" \ 528483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita "${STAGEDIR}/usr/share/doc/${PACKAGE}" 538483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita} 548483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita 558483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# Put the package contents in the staging area. 568483326704eff3b6a5fcce3f36d857a9779a4dd2fmalitastage_install_debian() { 578483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # Trunk packages need to install to a custom path and with custom filenames 588483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # (e.g. not /usr/bin/google-chrome) so they don't conflict with release 598483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # channel packages. 608483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita if [ "$CHANNEL" = "trunk" ] || [ "$CHANNEL" = "asan" ]; then 618483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita local PACKAGE="${PACKAGE}-${CHANNEL}" 628483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita local INSTALLDIR="${INSTALLDIR}-${CHANNEL}" 638483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # This would ideally be compiled into the app, but that's a bit too 648483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # intrusive of a change for these limited use channels, so we'll just hack 658483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # it into the wrapper script. The user can still override since it seems to 668483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # work to specify --user-data-dir multiple times on the command line, with 678483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # the last occurrence winning. 688483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita local DEFAULT_FLAGS="--user-data-dir=\"\${HOME}/.config/${PACKAGE}\"" 698483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita local MENUNAME="${MENUNAME} (${CHANNEL})" 708483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita fi 718483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita prep_staging_debian 728483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita stage_install_common 738483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita echo "Staging Debian install files in '${STAGEDIR}'..." 748483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/cron" 758483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita process_template "${BUILDDIR}/installer/common/repo.cron" \ 768483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita "${STAGEDIR}/${INSTALLDIR}/cron/${PACKAGE}" 778483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita chmod 755 "${STAGEDIR}/${INSTALLDIR}/cron/${PACKAGE}" 788483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita pushd "${STAGEDIR}/etc/cron.daily/" 798483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita ln -snf "${INSTALLDIR}/cron/${PACKAGE}" "${PACKAGE}" 808483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita popd 818483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita process_template "${BUILDDIR}/installer/debian/debian.menu" \ 828483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita "${STAGEDIR}/usr/share/menu/${PACKAGE}.menu" 838483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita chmod 644 "${STAGEDIR}/usr/share/menu/${PACKAGE}.menu" 848483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita process_template "${BUILDDIR}/installer/debian/postinst" \ 858483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita "${STAGEDIR}/DEBIAN/postinst" 868483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita chmod 755 "${STAGEDIR}/DEBIAN/postinst" 878483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita process_template "${BUILDDIR}/installer/debian/prerm" \ 888483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita "${STAGEDIR}/DEBIAN/prerm" 898483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita chmod 755 "${STAGEDIR}/DEBIAN/prerm" 908483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita process_template "${BUILDDIR}/installer/debian/postrm" \ 918483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita "${STAGEDIR}/DEBIAN/postrm" 928483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita chmod 755 "${STAGEDIR}/DEBIAN/postrm" 938483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita} 948483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita 958483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita# Actually generate the package file. 968483326704eff3b6a5fcce3f36d857a9779a4dd2fmalitado_package() { 978483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita echo "Packaging ${ARCHITECTURE}..." 988483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita PREDEPENDS="$COMMON_PREDEPS" 998483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita DEPENDS="${COMMON_DEPS}" 1008483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # Trunk is a special package, mostly for development testing, so don't make 1018483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita # it replace any installed release packages. 1028483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita if [ "$CHANNEL" != "trunk" ] && [ "$CHANNEL" != "asan" ]; then 1038483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita REPLACES="${PACKAGE}" 1048483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita CONFLICTS="${PACKAGE}" 1058483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita PROVIDES="${PACKAGE}, www-browser" 1068483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita fi 1078483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita gen_changelog 1088483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita process_template "${SCRIPTDIR}/control.template" "${DEB_CONTROL}" 1098483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita export DEB_HOST_ARCH="${ARCHITECTURE}" 1108483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita if [ -f "${DEB_CONTROL}" ]; then 1118483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita gen_control 1128483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita fi 1138483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita fakeroot dpkg-deb -Zlzma -b "${STAGEDIR}" . 1148483326704eff3b6a5fcce3f36d857a9779a4dd2fmalita} 115 116# Remove temporary files and unwanted packaging output. 117cleanup() { 118 echo "Cleaning..." 119 rm -rf "${STAGEDIR}" 120 rm -rf "${TMPFILEDIR}" 121} 122 123usage() { 124 echo "usage: $(basename $0) [-c channel] [-a target_arch] [-o 'dir'] " 125 echo " [-b 'dir']" 126 echo "-c channel the package channel (trunk, asan, unstable, beta, stable)" 127 echo "-a arch package architecture (ia32 or x64)" 128 echo "-o dir package output directory [${OUTPUTDIR}]" 129 echo "-b dir build input directory [${BUILDDIR}]" 130 echo "-h this help message" 131} 132 133# Check that the channel name is one of the allowable ones. 134verify_channel() { 135 case $CHANNEL in 136 stable ) 137 CHANNEL=stable 138 RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Stable%20updates" 139 ;; 140 unstable|dev|alpha ) 141 CHANNEL=unstable 142 RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Dev%20updates" 143 ;; 144 testing|beta ) 145 CHANNEL=beta 146 RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Beta%20updates" 147 ;; 148 trunk|asan ) 149 # Setting this to empty will prevent it from updating any existing configs 150 # from release packages. 151 REPOCONFIG="" 152 RELEASENOTES="http://googlechromereleases.blogspot.com/" 153 ;; 154 * ) 155 echo 156 echo "ERROR: '$CHANNEL' is not a valid channel type." 157 echo 158 exit 1 159 ;; 160 esac 161} 162 163process_opts() { 164 while getopts ":o:b:c:a:h" OPTNAME 165 do 166 case $OPTNAME in 167 o ) 168 OUTPUTDIR=$(readlink -f "${OPTARG}") 169 mkdir -p "${OUTPUTDIR}" 170 ;; 171 b ) 172 BUILDDIR=$(readlink -f "${OPTARG}") 173 ;; 174 c ) 175 CHANNEL="$OPTARG" 176 ;; 177 a ) 178 TARGETARCH="$OPTARG" 179 ;; 180 h ) 181 usage 182 exit 0 183 ;; 184 \: ) 185 echo "'-$OPTARG' needs an argument." 186 usage 187 exit 1 188 ;; 189 * ) 190 echo "invalid command-line option: $OPTARG" 191 usage 192 exit 1 193 ;; 194 esac 195 done 196} 197 198#========= 199# MAIN 200#========= 201 202SCRIPTDIR=$(readlink -f "$(dirname "$0")") 203OUTPUTDIR="${PWD}" 204STAGEDIR=$(mktemp -d -t deb.build.XXXXXX) || exit 1 205TMPFILEDIR=$(mktemp -d -t deb.tmp.XXXXXX) || exit 1 206DEB_CHANGELOG="${TMPFILEDIR}/changelog" 207DEB_FILES="${TMPFILEDIR}/files" 208DEB_CONTROL="${TMPFILEDIR}/control" 209CHANNEL="trunk" 210# Default target architecture to same as build host. 211if [ "$(uname -m)" = "x86_64" ]; then 212 TARGETARCH="x64" 213else 214 TARGETARCH="ia32" 215fi 216 217# call cleanup() on exit 218trap cleanup 0 219process_opts "$@" 220if [ ! "$BUILDDIR" ]; then 221 BUILDDIR=$(readlink -f "${SCRIPTDIR}/../../../../../out/Release") 222fi 223 224source ${BUILDDIR}/installer/common/installer.include 225 226get_version_info 227VERSIONFULL="${VERSION}-${PACKAGE_RELEASE}" 228 229if [ "$CHROMIUM_BUILD" = "_google_chrome" ]; then 230 source "${BUILDDIR}/installer/common/google-chrome.info" 231else 232 source "${BUILDDIR}/installer/common/chromium-browser.info" 233fi 234eval $(sed -e "s/^\([^=]\+\)=\(.*\)$/export \1='\2'/" \ 235 "${BUILDDIR}/installer/theme/BRANDING") 236 237REPOCONFIG="deb http://dl.google.com/linux/${PACKAGE#google-}/deb/ stable main" 238verify_channel 239 240# Some Debian packaging tools want these set. 241export DEBFULLNAME="${MAINTNAME}" 242export DEBEMAIL="${MAINTMAIL}" 243 244# We'd like to eliminate more of these deps by relying on the 'lsb' package, but 245# that brings in tons of unnecessary stuff, like an mta and rpm. Until that full 246# 'lsb' package is installed by default on DEB distros, we'll have to stick with 247# the LSB sub-packages, to avoid pulling in all that stuff that's not installed 248# by default. 249 250# Need a dummy debian/control file for dpkg-shlibdeps. 251DUMMY_STAGING_DIR="${TMPFILEDIR}/dummy_staging" 252mkdir "$DUMMY_STAGING_DIR" 253cd "$DUMMY_STAGING_DIR" 254mkdir debian 255touch debian/control 256 257# Generate the dependencies, 258# TODO(mmoss): This is a workaround for a problem where dpkg-shlibdeps was 259# resolving deps using some of our build output shlibs (i.e. 260# out/Release/lib.target/libfreetype.so.6), and was then failing with: 261# dpkg-shlibdeps: error: no dependency information found for ... 262# It's not clear if we ever want to look in LD_LIBRARY_PATH to resolve deps, 263# but it seems that we don't currently, so this is the most expediant fix. 264SAVE_LDLP=${LD_LIBRARY_PATH:-} 265unset LD_LIBRARY_PATH 266DPKG_SHLIB_DEPS=$(dpkg-shlibdeps -O "$BUILDDIR/chrome" 2> /dev/null | \ 267 sed 's/^shlibs:Depends=//') 268if [ -n "$SAVE_LDLP" ]; then 269 LD_LIBRARY_PATH=$SAVE_LDLP 270fi 271 272# Format it nicely and save it for comparison. 273# The grep -v is for a duplicate libc6 dep caused by Lucid glibc silliness. 274echo "$DPKG_SHLIB_DEPS" | sed 's/, /\n/g' | \ 275 grep -v '^libc6 (>= 2.3.6-6~)$' > actual 276 277# Compare the expected dependency list to the generate list. 278BAD_DIFF=0 279diff "$SCRIPTDIR/expected_deps" actual || BAD_DIFF=1 280if [ $BAD_DIFF -ne 0 ] && [ -z "${IGNORE_DEPS_CHANGES:-}" ]; then 281 echo 282 echo "ERROR: Shared library dependencies changed!" 283 echo "If this is intentional, please update:" 284 echo "chrome/installer/linux/debian/expected_deps" 285 echo 286 exit $BAD_DIFF 287fi 288rm -rf "$DUMMY_STAGING_DIR" 289 290# Additional dependencies not in the dpkg-shlibdeps output. 291ADDITION_DEPS="ca-certificates, libcurl3, \ 292 lsb-base (>=3.2), xdg-utils (>= 1.0.2), wget" 293 294# Fix-up libnspr dependency due to renaming in Ubuntu (the old package still 295# exists, but it was moved to "universe" repository, which isn't installed by 296# default). 297DPKG_SHLIB_DEPS=$(sed \ 298 's/\(libnspr4-0d ([^)]*)\), /\1 | libnspr4 (>= 4.8.7-0ubuntu1), /g' \ 299 <<< $DPKG_SHLIB_DEPS) 300 301# Fix-up libudev dependency because Ubuntu 13.04 has libudev1 instead of 302# libudev0. 303DPKG_SHLIB_DEPS=$(sed 's/\(libudev0 ([^)]*)\), /\1 | libudev1 (>= 198), /g' \ 304 <<< $DPKG_SHLIB_DEPS) 305 306COMMON_DEPS="${DPKG_SHLIB_DEPS}, ${ADDITION_DEPS}" 307COMMON_PREDEPS="dpkg (>= 1.14.0)" 308 309 310# Make everything happen in the OUTPUTDIR. 311cd "${OUTPUTDIR}" 312 313case "$TARGETARCH" in 314 ia32 ) 315 export ARCHITECTURE="i386" 316 stage_install_debian 317 ;; 318 x64 ) 319 export ARCHITECTURE="amd64" 320 stage_install_debian 321 ;; 322 * ) 323 echo 324 echo "ERROR: Don't know how to build DEBs for '$TARGETARCH'." 325 echo 326 exit 1 327 ;; 328esac 329 330do_package 331