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