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 10 set -e 11 if [ "$VERBOSE" ]; then 12 set -x 13 fi 14 set -u 15 16 gen_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. 30 prep_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. 36 stage_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. 73 do_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). Filter out udev to avoid 109 # 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. 171 cleanup() { 172 rm -rf "${STAGEDIR}" 173 rm -rf "${TMPFILEDIR}" 174 } 175 176 usage() { 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. 187 verify_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 218 process_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 258 SCRIPTDIR=$(readlink -f "$(dirname "$0")") 259 OUTPUTDIR="${PWD}" 260 STAGEDIR=$(mktemp -d -t rpm.build.XXXXXX) || exit 1 261 TMPFILEDIR=$(mktemp -d -t rpm.tmp.XXXXXX) || exit 1 262 CHANNEL="trunk" 263 # Default target architecture to same as build host. 264 if [ "$(uname -m)" = "x86_64" ]; then 265 TARGETARCH="x64" 266 else 267 TARGETARCH="ia32" 268 fi 269 SPEC="${TMPFILEDIR}/chrome.spec" 270 271 # call cleanup() on exit 272 trap cleanup 0 273 process_opts "$@" 274 if [ ! "$BUILDDIR" ]; then 275 BUILDDIR=$(readlink -f "${SCRIPTDIR}/../../../../../out/Release") 276 fi 277 278 source ${BUILDDIR}/installer/common/installer.include 279 280 get_version_info 281 282 if [ "$CHROMIUM_BUILD" = "_google_chrome" ]; then 283 source "${BUILDDIR}/installer/common/google-chrome.info" 284 else 285 source "${BUILDDIR}/installer/common/chromium-browser.info" 286 fi 287 eval $(sed -e "s/^\([^=]\+\)=\(.*\)$/export \1='\2'/" \ 288 "${BUILDDIR}/installer/theme/BRANDING") 289 290 REPOCONFIG="http://dl.google.com/linux/${PACKAGE#google-}/rpm/stable" 291 verify_channel 292 export USR_BIN_SYMLINK_NAME="${PACKAGE}-${CHANNEL}" 293 294 # Make everything happen in the OUTPUTDIR. 295 cd "${OUTPUTDIR}" 296 297 case "$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 ;; 312 esac 313 314 do_package 315