build.sh revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#!/bin/bash
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner# Copyright (c) 2012 The Chromium Authors. All rights reserved.
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner# Use of this source code is governed by a BSD-style license that can be
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner# found in the LICENSE file.
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner# TODO(mmoss) This currently only works with official builds, since non-official
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner# builds don't add the "${BUILDDIR}/installer/" files needed for packaging.
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerset -e
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerif [ "$VERBOSE" ]; then
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  set -x
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerfi
14a408326b499c3ffdfed2378738598c4ad0cf745fEli Friedmanset -u
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnergen_spec() {
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  rm -f "${SPEC}"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # Trunk packages need to install to a custom path so they don't conflict with
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # release channel packages.
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  local PACKAGE_FILENAME="${PACKAGE}"
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  if [ "$CHANNEL" != "stable" ]; then
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    local INSTALLDIR="${INSTALLDIR}-${CHANNEL}"
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PACKAGE_FILENAME="${PACKAGE}-${CHANNEL}"
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    local MENUNAME="${MENUNAME} (${CHANNEL})"
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  fi
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  process_template "${SCRIPTDIR}/chrome.spec.template" "${SPEC}"
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner# Setup the installation directory hierachy in the package staging area.
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprep_staging_rpm() {
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  prep_staging_common
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  install -m 755 -d "${STAGEDIR}/etc/cron.daily"
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner# Put the package contents in the staging area.
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstage_install_rpm() {
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # TODO(phajdan.jr): Deduplicate this and debian/build.sh .
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # For now duplication is going to help us avoid merge conflicts
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # as changes are frequently merged to older branches related to SxS effort.
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  if [ "$CHANNEL" != "stable" ]; then
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    # This would ideally be compiled into the app, but that's a bit too
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    # intrusive of a change for these limited use channels, so we'll just hack
4336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton    # it into the wrapper script. The user can still override since it seems to
4433ed170599d41fe407a4dcf5f0875c75e1ad1375Greg Clayton    # work to specify --user-data-dir multiple times on the command line, with
4533ed170599d41fe407a4dcf5f0875c75e1ad1375Greg Clayton    # the last occurrence winning.
4633ed170599d41fe407a4dcf5f0875c75e1ad1375Greg Clayton    local SXS_USER_DATA_DIR="\${XDG_CONFIG_HOME:-\${HOME}/.config}/${PACKAGE}-${CHANNEL}"
4733ed170599d41fe407a4dcf5f0875c75e1ad1375Greg Clayton    local DEFAULT_FLAGS="--user-data-dir=\"${SXS_USER_DATA_DIR}\""
4833ed170599d41fe407a4dcf5f0875c75e1ad1375Greg Clayton
4933ed170599d41fe407a4dcf5f0875c75e1ad1375Greg Clayton    # Avoid file collisions between channels.
5033ed170599d41fe407a4dcf5f0875c75e1ad1375Greg Clayton    local PACKAGE="${PACKAGE}-${CHANNEL}"
5133ed170599d41fe407a4dcf5f0875c75e1ad1375Greg Clayton    local INSTALLDIR="${INSTALLDIR}-${CHANNEL}"
5233ed170599d41fe407a4dcf5f0875c75e1ad1375Greg Clayton
5333ed170599d41fe407a4dcf5f0875c75e1ad1375Greg Clayton    # Make it possible to distinguish between menu entries
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    # for different channels.
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    local MENUNAME="${MENUNAME} (${CHANNEL})"
5612bec71b323dc520f0e985a86e09c4712559e115Greg Clayton  fi
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  prep_staging_rpm
5812bec71b323dc520f0e985a86e09c4712559e115Greg Clayton  stage_install_common
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  echo "Staging RPM install files in '${STAGEDIR}'..."
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  process_template "${BUILDDIR}/installer/common/rpmrepo.cron" \
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    "${STAGEDIR}/etc/cron.daily/${PACKAGE}"
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  chmod 755 "${STAGEDIR}/etc/cron.daily/${PACKAGE}"
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner# Actually generate the package file.
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerdo_package() {
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  echo "Packaging ${ARCHITECTURE}..."
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  PROVIDES="${PACKAGE}"
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  local REPS="$REPLACES"
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  REPLACES=""
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  for rep in $REPS; do
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if [ -z "$REPLACES" ]; then
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner      REPLACES="$PACKAGE-$rep"
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner      REPLACES="$REPLACES $PACKAGE-$rep"
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    fi
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  done
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # The symbols in libX11.so are not versioned, so when a newer version has new
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # symbols like _XGetRequest, RPM's find-requires tool does not detect it, and
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # there is no way to specify a libX11.so version number to prevent
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # installation on affected distros like OpenSUSE 12.1 and Fedora 16.
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # Thus there has to be distro-specific conflict here.
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # TODO(thestig) Remove these in the future when other requirements prevent
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # installation on affected distros.
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  ADDITIONAL_CONFLICTS="xorg-x11-libX11 < 7.6_1 libX11 < 1.4.99"
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  REPLACES="$REPLACES $ADDITIONAL_CONFLICTS"
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # If we specify a dependecy of foo.so below, we would depend on both the
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # 32 and 64-bit versions on a 64-bit machine. The current version of RPM
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # we use is too old and doesn't provide %{_isa}, so we do this manually.
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  if [ "$ARCHITECTURE" = "x86_64" ] ; then
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    local EMPTY_VERSION="()"
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    local PKG_ARCH="(64bit)"
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  elif [ "$ARCHITECTURE" = "i386" ] ; then
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    local EMPTY_VERSION=""
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    local PKG_ARCH=""
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  fi
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # Use find-requires script to make sure the dependencies are complete
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # (especially libc and libstdc++ versions).
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # - Filter out udev to avoid libudev.so.0 vs. libudev.so.1 mismatches.
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  DETECTED_DEPENDS="$(echo "${BUILDDIR}/chrome" | /usr/lib/rpm/find-requires |
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner      grep -v udev)"
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  # Compare the expected dependency list to the generated list.
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  BAD_DIFF=0
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  diff "$SCRIPTDIR/expected_deps_$ARCHITECTURE" \
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner      <(echo "${DETECTED_DEPENDS}") || BAD_DIFF=1
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner  if [ $BAD_DIFF -ne 0 ] && [ -z "${IGNORE_DEPS_CHANGES:-}" ]; then
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    echo
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    echo "ERROR: Shared library dependencies changed!"
113    echo "If this is intentional, please update:"
114    echo "chrome/installer/linux/rpm/expected_deps_i386"
115    echo "chrome/installer/linux/rpm/expected_deps_x86_64"
116    echo
117    exit $BAD_DIFF
118  fi
119
120  # libgdk_pixbuf is added in LSB 3.2 and no longer explicitly required.
121  # libcairo, libpangocairo, libasound are in LSB 4. and no longer explicitly
122  # required.
123  # xdg-utils is still optional in LSB 4.0.
124  # nss (bundled) is optional in LSB 4.0.
125  #
126  # We want to depend on the system SSL certs so wget can upload crash reports
127  # securely, but there's no common capability between the distros. Bugs filed:
128  # https://qa.mandriva.com/show_bug.cgi?id=55714
129  # https://bugzilla.redhat.com/show_bug.cgi?id=538158
130  # https://bugzilla.novell.com/show_bug.cgi?id=556248
131  DEPENDS="lsb >= 4.0, \
132  libcurl.so.4${EMPTY_VERSION}${PKG_ARCH}, \
133  libnss3.so(NSS_3.14.3)${PKG_ARCH}, \
134  wget, \
135  xdg-utils, \
136  zlib, \
137  $(echo "${DETECTED_DEPENDS}" | tr '\n' ',')"
138  gen_spec
139
140  # Create temporary rpmbuild dirs.
141  RPMBUILD_DIR=$(mktemp -d -t rpmbuild.XXXXXX) || exit 1
142  mkdir -p "$RPMBUILD_DIR/BUILD"
143  mkdir -p "$RPMBUILD_DIR/RPMS"
144
145  # '__os_install_post ${nil}' disables a bunch of automatic post-processing
146  # (brp-compress, etc.), which by default appears to only be enabled on 32-bit,
147  # and which doesn't gain us anything since we already explicitly do all the
148  # compression, symbol stripping, etc. that we want.
149  fakeroot rpmbuild -bb --target="$ARCHITECTURE" --rmspec \
150    --define "_topdir $RPMBUILD_DIR" \
151    --define "_binary_payload w9.bzdio" \
152    --define "__os_install_post  %{nil}" \
153    "${SPEC}"
154  PKGNAME="${PACKAGE}-${CHANNEL}-${VERSION}-${PACKAGE_RELEASE}"
155  mv "$RPMBUILD_DIR/RPMS/$ARCHITECTURE/${PKGNAME}.${ARCHITECTURE}.rpm" \
156     "${OUTPUTDIR}"
157  # Make sure the package is world-readable, otherwise it causes problems when
158  # copied to share drive.
159  chmod a+r "${OUTPUTDIR}/${PKGNAME}.$ARCHITECTURE.rpm"
160  rm -rf "$RPMBUILD_DIR"
161}
162
163# Remove temporary files and unwanted packaging output.
164cleanup() {
165  rm -rf "${STAGEDIR}"
166  rm -rf "${TMPFILEDIR}"
167}
168
169usage() {
170  echo "usage: $(basename $0) [-c channel] [-a target_arch] [-o 'dir']"
171  echo "                      [-b 'dir']"
172  echo "-c channel the package channel (trunk, asan, unstable, beta, stable)"
173  echo "-a arch    package architecture (ia32 or x64)"
174  echo "-o dir     package output directory [${OUTPUTDIR}]"
175  echo "-b dir     build input directory    [${BUILDDIR}]"
176  echo "-h         this help message"
177}
178
179# Check that the channel name is one of the allowable ones.
180verify_channel() {
181  case $CHANNEL in
182    stable )
183      CHANNEL=stable
184      # TODO(phajdan.jr): Remove REPLACES completely.
185      REPLACES="dummy"
186      ;;
187    unstable|dev|alpha )
188      CHANNEL=unstable
189      # TODO(phajdan.jr): Remove REPLACES completely.
190      REPLACES="dummy"
191      ;;
192    testing|beta )
193      CHANNEL=beta
194      # TODO(phajdan.jr): Remove REPLACES completely.
195      REPLACES="dummy"
196      ;;
197    trunk|asan )
198      # This is a special package, mostly for development testing, so don't make
199      # it replace any installed release packages.
200      # TODO(phajdan.jr): Remove REPLACES completely.
201      REPLACES="dummy"
202      # Setting this to empty will prevent it from updating any existing configs
203      # from release packages.
204      REPOCONFIG=""
205      ;;
206    * )
207      echo
208      echo "ERROR: '$CHANNEL' is not a valid channel type."
209      echo
210      exit 1
211      ;;
212  esac
213}
214
215process_opts() {
216  while getopts ":o:b:c:a:h" OPTNAME
217  do
218    case $OPTNAME in
219      o )
220        OUTPUTDIR=$(readlink -f "${OPTARG}")
221        mkdir -p "${OUTPUTDIR}"
222        ;;
223      b )
224        BUILDDIR=$(readlink -f "${OPTARG}")
225        ;;
226      c )
227        CHANNEL="$OPTARG"
228        verify_channel
229        ;;
230      a )
231        TARGETARCH="$OPTARG"
232        ;;
233      h )
234        usage
235        exit 0
236        ;;
237      \: )
238        echo "'-$OPTARG' needs an argument."
239        usage
240        exit 1
241        ;;
242      * )
243        echo "invalid command-line option: $OPTARG"
244        usage
245        exit 1
246        ;;
247    esac
248  done
249}
250
251#=========
252# MAIN
253#=========
254
255SCRIPTDIR=$(readlink -f "$(dirname "$0")")
256OUTPUTDIR="${PWD}"
257STAGEDIR=$(mktemp -d -t rpm.build.XXXXXX) || exit 1
258TMPFILEDIR=$(mktemp -d -t rpm.tmp.XXXXXX) || exit 1
259CHANNEL="trunk"
260# Default target architecture to same as build host.
261if [ "$(uname -m)" = "x86_64" ]; then
262  TARGETARCH="x64"
263else
264  TARGETARCH="ia32"
265fi
266SPEC="${TMPFILEDIR}/chrome.spec"
267
268# call cleanup() on exit
269trap cleanup 0
270process_opts "$@"
271if [ ! "$BUILDDIR" ]; then
272  BUILDDIR=$(readlink -f "${SCRIPTDIR}/../../../../../out/Release")
273fi
274
275source ${BUILDDIR}/installer/common/installer.include
276
277get_version_info
278
279if [ "$CHROMIUM_BUILD" = "_google_chrome" ]; then
280  source "${BUILDDIR}/installer/common/google-chrome.info"
281else
282  source "${BUILDDIR}/installer/common/chromium-browser.info"
283fi
284eval $(sed -e "s/^\([^=]\+\)=\(.*\)$/export \1='\2'/" \
285  "${BUILDDIR}/installer/theme/BRANDING")
286
287REPOCONFIG="http://dl.google.com/linux/${PACKAGE#google-}/rpm/stable"
288verify_channel
289export USR_BIN_SYMLINK_NAME="${PACKAGE}-${CHANNEL}"
290
291# Make everything happen in the OUTPUTDIR.
292cd "${OUTPUTDIR}"
293
294case "$TARGETARCH" in
295  ia32 )
296    export ARCHITECTURE="i386"
297    stage_install_rpm
298    ;;
299  x64 )
300    export ARCHITECTURE="x86_64"
301    stage_install_rpm
302    ;;
303  * )
304    echo
305    echo "ERROR: Don't know how to build RPMs for '$TARGETARCH'."
306    echo
307    exit 1
308    ;;
309esac
310
311do_package
312