#!/bin/bash # # Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # TODO(mmoss) This currently only works with official builds, since non-official # builds don't add the "${BUILDDIR}/installer/" files needed for packaging. set -e if [ "$VERBOSE" ]; then set -x fi set -u gen_spec() { rm -f "${SPEC}" # Trunk packages need to install to a custom path so they don't conflict with # release channel packages. local PACKAGE_FILENAME="${PACKAGE}" if [ "$CHANNEL" != "stable" ]; then local INSTALLDIR="${INSTALLDIR}-${CHANNEL}" PACKAGE_FILENAME="${PACKAGE}-${CHANNEL}" local MENUNAME="${MENUNAME} (${CHANNEL})" fi process_template "${SCRIPTDIR}/chrome.spec.template" "${SPEC}" } # Setup the installation directory hierachy in the package staging area. prep_staging_rpm() { prep_staging_common install -m 755 -d "${STAGEDIR}/etc/cron.daily" } # Put the package contents in the staging area. stage_install_rpm() { # TODO(phajdan.jr): Deduplicate this and debian/build.sh . # For now duplication is going to help us avoid merge conflicts # as changes are frequently merged to older branches related to SxS effort. if [ "$CHANNEL" != "stable" ]; then # This would ideally be compiled into the app, but that's a bit too # intrusive of a change for these limited use channels, so we'll just hack # it into the wrapper script. The user can still override since it seems to # work to specify --user-data-dir multiple times on the command line, with # the last occurrence winning. local SXS_USER_DATA_DIR="\${XDG_CONFIG_HOME:-\${HOME}/.config}/${PACKAGE}-${CHANNEL}" local DEFAULT_FLAGS="--user-data-dir=\"${SXS_USER_DATA_DIR}\"" # Avoid file collisions between channels. local PACKAGE="${PACKAGE}-${CHANNEL}" local INSTALLDIR="${INSTALLDIR}-${CHANNEL}" # Make it possible to distinguish between menu entries # for different channels. local MENUNAME="${MENUNAME} (${CHANNEL})" fi prep_staging_rpm stage_install_common echo "Staging RPM install files in '${STAGEDIR}'..." process_template "${BUILDDIR}/installer/common/rpmrepo.cron" \ "${STAGEDIR}/etc/cron.daily/${PACKAGE}" chmod 755 "${STAGEDIR}/etc/cron.daily/${PACKAGE}" } # Actually generate the package file. do_package() { echo "Packaging ${ARCHITECTURE}..." PROVIDES="${PACKAGE}" local REPS="$REPLACES" REPLACES="" for rep in $REPS; do if [ -z "$REPLACES" ]; then REPLACES="$PACKAGE-$rep" else REPLACES="$REPLACES $PACKAGE-$rep" fi done # The symbols in libX11.so are not versioned, so when a newer version has new # symbols like _XGetRequest, RPM's find-requires tool does not detect it, and # there is no way to specify a libX11.so version number to prevent # installation on affected distros like OpenSUSE 12.1 and Fedora 16. # Thus there has to be distro-specific conflict here. # TODO(thestig) Remove these in the future when other requirements prevent # installation on affected distros. ADDITIONAL_CONFLICTS="xorg-x11-libX11 < 7.6_1 libX11 < 1.4.99" REPLACES="$REPLACES $ADDITIONAL_CONFLICTS" # If we specify a dependecy of foo.so below, we would depend on both the # 32 and 64-bit versions on a 64-bit machine. The current version of RPM # we use is too old and doesn't provide %{_isa}, so we do this manually. if [ "$ARCHITECTURE" = "x86_64" ] ; then local EMPTY_VERSION="()" local PKG_ARCH="(64bit)" elif [ "$ARCHITECTURE" = "i386" ] ; then local EMPTY_VERSION="" local PKG_ARCH="" fi # Use find-requires script to make sure the dependencies are complete # (especially libc and libstdc++ versions). # - Filter out udev to avoid libudev.so.0 vs. libudev.so.1 mismatches. DETECTED_DEPENDS="$(echo "${BUILDDIR}/chrome" | /usr/lib/rpm/find-requires | grep -v udev)" # Compare the expected dependency list to the generated list. BAD_DIFF=0 diff "$SCRIPTDIR/expected_deps_$ARCHITECTURE" \ <(echo "${DETECTED_DEPENDS}") || BAD_DIFF=1 if [ $BAD_DIFF -ne 0 ] && [ -z "${IGNORE_DEPS_CHANGES:-}" ]; then echo echo "ERROR: Shared library dependencies changed!" echo "If this is intentional, please update:" echo "chrome/installer/linux/rpm/expected_deps_i386" echo "chrome/installer/linux/rpm/expected_deps_x86_64" echo exit $BAD_DIFF fi # libgdk_pixbuf is added in LSB 3.2 and no longer explicitly required. # libcairo, libpangocairo, libasound are in LSB 4. and no longer explicitly # required. # xdg-utils is still optional in LSB 4.0. # nss (bundled) is optional in LSB 4.0. # # We want to depend on the system SSL certs so wget can upload crash reports # securely, but there's no common capability between the distros. Bugs filed: # https://qa.mandriva.com/show_bug.cgi?id=55714 # https://bugzilla.redhat.com/show_bug.cgi?id=538158 # https://bugzilla.novell.com/show_bug.cgi?id=556248 DEPENDS="lsb >= 4.0, \ libcurl.so.4${EMPTY_VERSION}${PKG_ARCH}, \ libnss3.so(NSS_3.14.3)${PKG_ARCH}, \ wget, \ xdg-utils, \ zlib, \ $(echo "${DETECTED_DEPENDS}" | tr '\n' ',')" gen_spec # Create temporary rpmbuild dirs. RPMBUILD_DIR=$(mktemp -d -t rpmbuild.XXXXXX) || exit 1 mkdir -p "$RPMBUILD_DIR/BUILD" mkdir -p "$RPMBUILD_DIR/RPMS" # '__os_install_post ${nil}' disables a bunch of automatic post-processing # (brp-compress, etc.), which by default appears to only be enabled on 32-bit, # and which doesn't gain us anything since we already explicitly do all the # compression, symbol stripping, etc. that we want. fakeroot rpmbuild -bb --target="$ARCHITECTURE" --rmspec \ --define "_topdir $RPMBUILD_DIR" \ --define "_binary_payload w9.bzdio" \ --define "__os_install_post %{nil}" \ "${SPEC}" PKGNAME="${PACKAGE}-${CHANNEL}-${VERSION}-${PACKAGE_RELEASE}" mv "$RPMBUILD_DIR/RPMS/$ARCHITECTURE/${PKGNAME}.${ARCHITECTURE}.rpm" \ "${OUTPUTDIR}" # Make sure the package is world-readable, otherwise it causes problems when # copied to share drive. chmod a+r "${OUTPUTDIR}/${PKGNAME}.$ARCHITECTURE.rpm" rm -rf "$RPMBUILD_DIR" } # Remove temporary files and unwanted packaging output. cleanup() { rm -rf "${STAGEDIR}" rm -rf "${TMPFILEDIR}" } usage() { echo "usage: $(basename $0) [-c channel] [-a target_arch] [-o 'dir']" echo " [-b 'dir']" echo "-c channel the package channel (trunk, asan, unstable, beta, stable)" echo "-a arch package architecture (ia32 or x64)" echo "-o dir package output directory [${OUTPUTDIR}]" echo "-b dir build input directory [${BUILDDIR}]" echo "-h this help message" } # Check that the channel name is one of the allowable ones. verify_channel() { case $CHANNEL in stable ) CHANNEL=stable # TODO(phajdan.jr): Remove REPLACES completely. REPLACES="dummy" ;; unstable|dev|alpha ) CHANNEL=unstable # TODO(phajdan.jr): Remove REPLACES completely. REPLACES="dummy" ;; testing|beta ) CHANNEL=beta # TODO(phajdan.jr): Remove REPLACES completely. REPLACES="dummy" ;; trunk|asan ) # This is a special package, mostly for development testing, so don't make # it replace any installed release packages. # TODO(phajdan.jr): Remove REPLACES completely. REPLACES="dummy" # Setting this to empty will prevent it from updating any existing configs # from release packages. REPOCONFIG="" ;; * ) echo echo "ERROR: '$CHANNEL' is not a valid channel type." echo exit 1 ;; esac } process_opts() { while getopts ":o:b:c:a:h" OPTNAME do case $OPTNAME in o ) OUTPUTDIR=$(readlink -f "${OPTARG}") mkdir -p "${OUTPUTDIR}" ;; b ) BUILDDIR=$(readlink -f "${OPTARG}") ;; c ) CHANNEL="$OPTARG" verify_channel ;; a ) TARGETARCH="$OPTARG" ;; h ) usage exit 0 ;; \: ) echo "'-$OPTARG' needs an argument." usage exit 1 ;; * ) echo "invalid command-line option: $OPTARG" usage exit 1 ;; esac done } #========= # MAIN #========= SCRIPTDIR=$(readlink -f "$(dirname "$0")") OUTPUTDIR="${PWD}" STAGEDIR=$(mktemp -d -t rpm.build.XXXXXX) || exit 1 TMPFILEDIR=$(mktemp -d -t rpm.tmp.XXXXXX) || exit 1 CHANNEL="trunk" # Default target architecture to same as build host. if [ "$(uname -m)" = "x86_64" ]; then TARGETARCH="x64" else TARGETARCH="ia32" fi SPEC="${TMPFILEDIR}/chrome.spec" # call cleanup() on exit trap cleanup 0 process_opts "$@" if [ ! "$BUILDDIR" ]; then BUILDDIR=$(readlink -f "${SCRIPTDIR}/../../../../../out/Release") fi source ${BUILDDIR}/installer/common/installer.include get_version_info if [ "$CHROMIUM_BUILD" = "_google_chrome" ]; then source "${BUILDDIR}/installer/common/google-chrome.info" else source "${BUILDDIR}/installer/common/chromium-browser.info" fi eval $(sed -e "s/^\([^=]\+\)=\(.*\)$/export \1='\2'/" \ "${BUILDDIR}/installer/theme/BRANDING") REPOCONFIG="http://dl.google.com/linux/${PACKAGE#google-}/rpm/stable" verify_channel export USR_BIN_SYMLINK_NAME="${PACKAGE}-${CHANNEL}" # Make everything happen in the OUTPUTDIR. cd "${OUTPUTDIR}" case "$TARGETARCH" in ia32 ) export ARCHITECTURE="i386" stage_install_rpm ;; x64 ) export ARCHITECTURE="x86_64" stage_install_rpm ;; * ) echo echo "ERROR: Don't know how to build RPMs for '$TARGETARCH'." echo exit 1 ;; esac do_package