Home | History | Annotate | Line # | Download | only in maintainer-scripts
      1 #! /bin/sh
      2 
      3 ########################################################################
      4 #
      5 # File:   gcc_release
      6 # Author: Jeffrey Law, Bernd Schmidt, Mark Mitchell
      7 # Date:   2001-05-25
      8 #
      9 # Contents:
     10 #   Script to create a GCC release.
     11 #
     12 # Copyright (c) 2001-2020 Free Software Foundation.
     13 #
     14 # This file is part of GCC.
     15 #
     16 # GCC is free software; you can redistribute it and/or modify
     17 # it under the terms of the GNU General Public License as published by
     18 # the Free Software Foundation; either version 3, or (at your option)
     19 # any later version.
     20 #
     21 # GCC is distributed in the hope that it will be useful,
     22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     24 # GNU General Public License for more details.
     25 #
     26 # You should have received a copy of the GNU General Public License
     27 # along with GCC; see the file COPYING3.  If not see
     28 # <https://www.gnu.org/licenses/>.
     29 #
     30 ########################################################################
     31 
     32 ########################################################################
     33 # Notes
     34 ########################################################################
     35 
     36 # Here is an example usage of this script, to create a GCC 3.0.2
     37 # prerelease:
     38 #
     39 #   gcc_release -r 3.0.2
     40 #
     41 # This script will automatically use the head of the release branch
     42 # to generate the release.
     43 
     44 ########################################################################
     45 # Functions
     46 ########################################################################
     47 
     48 # Issue the error message given by $@ and exit with a non-zero
     49 # exit code.
     50 
     51 error() {
     52     echo "gcc_release: error: $@"
     53     exit 1
     54 }
     55 
     56 # Issue the informational message given by $@.
     57 
     58 inform() {
     59     echo "gcc_release: $@"
     60 }
     61 
     62 # Issue a usage message explaining how to use this script.
     63 
     64 usage() {
     65 cat <<EOF
     66 gcc_release -r release [-f] [further options]
     67 gcc_release -s name:gitbranch [further options]
     68 
     69 Options:
     70 
     71   -r release           Version of the form X.Y or X.Y.Z.
     72   -s name:gitbranch    Create a snapshot, not a real release.
     73 
     74   -d destination       Local working directory where we will build the release
     75                        (default=${HOME}).
     76   -f                   Create a final release (and update ChangeLogs,...).
     77   -l                   Indicate that we are running on gcc.gnu.org.
     78   -p previous-tarball  Location of a previous tarball (to generate diff files).
     79   -t tag               Tag to mark the release in git.
     80   -u username          Username for upload operations.
     81   -b local-git-repo    Local git repository to speed up cloning.
     82 EOF
     83     exit 1
     84 }
     85 
     86 # Change to the directory given by $1.
     87 
     88 changedir() {
     89   cd $1 || \
     90     error "Could not change directory to $1"
     91 }
     92 
     93 # Build the source tree that will be the basis for the release
     94 # in ${WORKING_DIRECTORY}/gcc-${RELEASE}.
     95 
     96 build_sources() {
     97   # If the WORKING_DIRECTORY already exists, do not risk destroying it.
     98   if [ -r ${WORKING_DIRECTORY} ]; then
     99     error "\`${WORKING_DIRECTORY}' already exists"
    100   fi
    101   # Create the WORKING_DIRECTORY.
    102   mkdir "${WORKING_DIRECTORY}" \
    103     || error "Could not create \`${WORKING_DIRECTORY}'"
    104   changedir "${WORKING_DIRECTORY}"
    105 
    106   # Check out the sources.
    107   if [ -n "${GIT_REFERENCE}" ]; then
    108     ${GIT} clone -q --dissociate --reference "${GIT_REFERENCE}" \
    109 		 -b "${GITBRANCH}" "${GITROOT}" "`basename ${SOURCE_DIRECTORY}`" || \
    110         error "Could not check out release sources"
    111   else
    112     ${GIT} clone -q -b "${GITBRANCH}" "${GITROOT}" "`basename ${SOURCE_DIRECTORY}`" || \
    113         error "Could not check out release sources"
    114   fi
    115 
    116   # If this is a final release, make sure that the ChangeLogs
    117   # and version strings are updated.
    118   if [ ${FINAL} -ne 0 ]; then
    119     inform "Updating ChangeLogs and version files"
    120 
    121     grep -q "gcc-${RELEASE_MAJOR}/index.html gcc-${RELEASE_MAJOR}/changes.html" \
    122 	 ${SOURCE_DIRECTORY}/contrib/gennews ||\
    123 	   error "New release not listed in contrib/gennews"
    124 
    125     ${SOURCE_DIRECTORY}/contrib/gennews > NEWS ||\
    126 	   error "Could not regenerate NEWS files"
    127 
    128     grep -q "no releases of GCC ${RELEASE_MAJOR} have yet been made" NEWS &&\
    129 	   error "gcc-${RELEASE_MAJOR}/index.html has not been updated yet"
    130 
    131     grep -q "GCC ${RELEASE_MAJOR} has not been released yet" NEWS &&\
    132 	   error "gcc-${RELEASE_MAJOR}/changes.html has not been updated yet"
    133 
    134     thisindex="http:\/\/gcc.gnu.org\/gcc-${RELEASE_MAJOR}\/index.html"
    135     thischanges="http:\/\/gcc.gnu.org\/gcc-${RELEASE_MAJOR}\/changes.html"
    136     previndex="http:\/\/gcc.gnu.org\/gcc-`expr ${RELEASE_MAJOR} - 1`\/index.html"
    137     sed -n -e "/^${thisindex}/,/^${thischanges}/p" NEWS |\
    138 	   sed -n -e "/Release History/,/References and Acknowledgments/p" |\
    139 	   grep -q "^[[:blank:]]*GCC ${RELEASE_MAJOR}.${RELEASE_MINOR}" ||\
    140 	   error "GCC ${RELEASE_MAJOR}.${RELEASE_MINOR} not mentioned "\
    141 		 "in gcc-${RELEASE_MAJOR}/index.html"
    142 
    143     sed -n -e "/^${thischanges}/,/^${previndex}/p" NEWS |\
    144 	   grep -q "^[[:blank:]]*GCC ${RELEASE_MAJOR}.${RELEASE_MINOR}" ||\
    145 	   error "GCC ${RELEASE_MAJOR}.${RELEASE_MINOR} not mentioned "\
    146 		 "in gcc-${RELEASE_MAJOR}/changes.html"
    147 
    148     rm -f NEWS
    149 
    150     commit_files=""
    151     for x in `changedir ${SOURCE_DIRECTORY} && \
    152 	      find . -name ChangeLog`; do
    153       # Update this ChangeLog file only if it does not yet contain the
    154       # entry we are going to add.  (This is a safety net for repeated
    155       # runs of this script for the same release.)
    156       if ! grep "GCC ${RELEASE} released." ${SOURCE_DIRECTORY}/${x} > /dev/null ; then
    157 	cat - ${SOURCE_DIRECTORY}/${x} > ${SOURCE_DIRECTORY}/${x}.new <<EOF
    158 ${LONG_DATE}  Release Manager
    159 
    160 	* GCC ${RELEASE} released.
    161 
    162 EOF
    163 	mv ${SOURCE_DIRECTORY}/${x}.new ${SOURCE_DIRECTORY}/${x} \
    164 	  || error "Could not update ${x}"
    165 	commit_files="${commit_files} ${x}"
    166       fi
    167     done
    168 
    169     # Update gcc/DEV-PHASE.
    170 
    171     if [ `cat ${SOURCE_DIRECTORY}/gcc/BASE-VER` != ${RELEASE} ]; then
    172       [ ${RELEASE_MAJOR} -lt 5 ] && \
    173 	error "Release number ${RELEASE} does not match BASE-VER"
    174       if [ `cat ${SOURCE_DIRECTORY}/gcc/BASE-VER` \
    175 	   = ${RELEASE_MAJOR}.`expr ${RELEASE_MINOR} - 1`.1 \
    176 	   -a x${RELEASE_REVISION} = x0 ]; then
    177 	(changedir ${SOURCE_DIRECTORY}/gcc && \
    178 	 echo ${RELEASE} > BASE-VER) || \
    179 	error "Could not update BASE-VER"
    180 	commit_files="${commit_files} gcc/BASE-VER"
    181       else
    182 	error "Release number ${RELEASE} does not immediately follow BASE-VER"
    183       fi
    184     fi
    185     (changedir ${SOURCE_DIRECTORY}/gcc && \
    186      : > DEV-PHASE) || \
    187     error "Could not update DEV-PHASE"
    188     commit_files="${commit_files} gcc/DEV-PHASE"
    189 
    190     (changedir ${SOURCE_DIRECTORY} && \
    191      ${GIT} commit -q -m 'Update ChangeLog and version files for release' ${commit_files} && \
    192      ${GIT} push) || \
    193     error "Could not commit ChangeLog and version file updates"
    194 
    195     # Make sure we tag the sources for a final release.
    196     TAG="releases/gcc-${RELEASE}"
    197   fi
    198 
    199   # Tag the sources.
    200   if [ -n "${TAG}" ]; then
    201     inform "Tagging sources as ${TAG}"
    202     # We don't want to overwrite an existing tag.  So, if the tag
    203     # already exists, issue an error message; the release manager can
    204     # manually remove the tag if appropriate.
    205     if (changedir ${SOURCE_DIRECTORY} && \
    206 	${GIT} rev-parse "refs/tags/${TAG}" > /dev/null 2>&1); then
    207       error "Tag ${TAG} already exists"
    208     fi
    209     (changedir ${SOURCE_DIRECTORY} && \
    210      ${GIT} tag -s -m "GCC ${RELEASE} release" "${TAG}" && \
    211      ${GIT} push origin tag "${TAG}") || \
    212       error "Could not tag sources"
    213     GITBRANCH=${TAG}
    214   fi
    215 
    216   GITREV=`cd ${SOURCE_DIRECTORY} && ${GIT} rev-parse HEAD`
    217   inform "Sources are commit ${GITREV}"
    218 
    219   # Make sure there are no uncommitted changes in the sources.
    220   status=${WORKING_DIRECTORY}/gitstatus.$$
    221   (changedir ${SOURCE_DIRECTORY} && \
    222    ${GIT} status --porcelain --ignored > "$status") || \
    223     error "Could not get source directory status"
    224   if [ -s "$status" ]; then
    225     cat "$status"
    226     error "Source directory has unexpected changes"
    227   fi
    228   rm "$status"
    229 
    230   # Remove .git from the sources.
    231   rm -rf "${SOURCE_DIRECTORY}/.git" || \
    232     error "Could not remove .git from sources"
    233 
    234   # Run gcc_update on them to set up the timestamps nicely, and (re)write
    235   # the LAST_UPDATED file containing the git tag/revision used.
    236   changedir "gcc-${RELEASE}"
    237   contrib/gcc_update --touch
    238   echo "Obtained from git: ${GITBRANCH} revision ${GITREV}" > LAST_UPDATED
    239 
    240   # For a prerelease or real release, we need to generate additional
    241   # files not present in git.
    242   changedir "${SOURCE_DIRECTORY}"
    243   if [ $SNAPSHOT -ne 1 ]; then
    244     # Generate the documentation.
    245     inform "Building install docs"
    246     SOURCEDIR=${SOURCE_DIRECTORY}/gcc/doc
    247     DESTDIR=${SOURCE_DIRECTORY}/INSTALL
    248     export SOURCEDIR
    249     export DESTDIR
    250     ${SOURCE_DIRECTORY}/gcc/doc/install.texi2html
    251 
    252     # Regenerate the NEWS file.
    253     contrib/gennews > NEWS || \
    254       error "Could not regenerate NEWS files"
    255 
    256     # Now, we must build the compiler in order to create any generated
    257     # files that are supposed to go in the source directory.  This is
    258     # also a good sanity check to make sure that the release builds
    259     # on at least one platform.
    260     inform "Building compiler"
    261     OBJECT_DIRECTORY=../objdir
    262     num_cpus=1
    263     if type -p getconf 2>/dev/null; then
    264       num_cpus=`getconf _NPROCESSORS_ONLN 2>/dev/null`
    265       case "$num_cpus" in
    266 	'' | 0* | *[!0-9]*) num_cpus=1;;
    267       esac
    268     fi
    269     contrib/gcc_build -d ${SOURCE_DIRECTORY} -o ${OBJECT_DIRECTORY} \
    270       -c "--enable-generated-files-in-srcdir --disable-multilib" \
    271       -m "-j$num_cpus" build || \
    272       error "Could not rebuild GCC"
    273   fi
    274 
    275   # Move message catalogs to source directory.
    276   mv ../objdir/gcc/po/*.gmo gcc/po/
    277   [ -f libcpp/po/cpplib.pot ] && mv ../objdir/libcpp/po/*.gmo libcpp/po/
    278 
    279   # Create a "MD5SUMS" file to use for checking the validity of the release.
    280   echo \
    281 "# This file contains the MD5 checksums of the files in the
    282 # gcc-"${RELEASE}".tar.xz tarball.
    283 #
    284 # Besides verifying that all files in the tarball were correctly expanded,
    285 # it also can be used to determine if any files have changed since the
    286 # tarball was expanded or to verify that a patchfile was correctly applied.
    287 #
    288 # Suggested usage:
    289 # md5sum -c MD5SUMS | grep -v \"OK$\"
    290 #" > MD5SUMS
    291 
    292   find . -type f |
    293   sed -e 's:^\./::' -e '/MD5SUMS/d' |
    294   sort |
    295   xargs md5sum >>MD5SUMS
    296 }
    297 
    298 # Build a single tarfile.  The first argument is the name of the tarfile
    299 # to build, without any suffixes.  They will be added automatically.  The
    300 # rest of the arguments are files or directories to include, and possibly
    301 # other arguments to tar.
    302 
    303 build_tarfile() {
    304   # Get the name of the destination tar file.
    305   TARFILE="$1.tar.xz"
    306   shift
    307 
    308   # Build the tar file itself.
    309   (${TAR} cf - "$@" | ${XZ} > ${TARFILE}) || \
    310     error "Could not build tarfile"
    311   FILE_LIST="${FILE_LIST} ${TARFILE}"
    312 }
    313 
    314 # Build the various tar files for the release.
    315 
    316 build_tarfiles() {
    317   inform "Building tarfiles"
    318 
    319   changedir "${WORKING_DIRECTORY}"
    320 
    321   # The GNU Coding Standards specify that all files should
    322   # world readable.
    323   chmod -R a+r ${SOURCE_DIRECTORY}
    324   # And that all directories have mode 755.
    325   find ${SOURCE_DIRECTORY} -type d -exec chmod 755 {} \;
    326 
    327   # Build one huge tarfile for the entire distribution.
    328   build_tarfile gcc-${RELEASE} `basename ${SOURCE_DIRECTORY}`
    329 }
    330 
    331 # Build .gz files.
    332 build_gzip() {
    333   for f in ${FILE_LIST}; do
    334     target=${f%.xz}.gz
    335     (${XZ} -d -c $f | ${GZIP} > ${target}) || error "Could not create ${target}"
    336   done
    337 }
    338 
    339 # Build diffs against an old release.
    340 build_diffs() {
    341   old_dir=${1%/*}
    342   old_file=${1##*/}
    343   case "$old_file" in
    344     *.tar.xz) old_vers=${old_file%.tar.xz};;
    345     *) old_vers=${old_file%.tar.bz2};;
    346   esac
    347   old_vers=${old_vers#gcc-}
    348   inform "Building diffs against version $old_vers"
    349   for f in gcc; do
    350     if [ -e ${old_dir}/${f}-${old_vers}.tar.xz ]; then
    351       old_tar=${old_dir}/${f}-${old_vers}.tar.xz
    352     else
    353       old_tar=${old_dir}/${f}-${old_vers}.tar.bz2
    354     fi
    355     new_tar=${WORKING_DIRECTORY}/${f}-${RELEASE}.tar.xz
    356     if [ ! -e $old_tar ]; then
    357       inform "$old_tar not found; not generating diff file"
    358     elif [ ! -e $new_tar ]; then
    359       inform "$new_tar not found; not generating diff file"
    360     else
    361       build_diff $old_tar gcc-${old_vers} $new_tar gcc-${RELEASE} \
    362         ${f}-${old_vers}-${RELEASE}.diff.xz
    363     fi
    364   done
    365 }
    366 
    367 # Build an individual diff.
    368 build_diff() {
    369   changedir "${WORKING_DIRECTORY}"
    370   tmpdir=gccdiff.$$
    371   mkdir $tmpdir || error "Could not create directory $tmpdir"
    372   changedir $tmpdir
    373   case "$1" in
    374     *.tar.bz2)
    375       (${BZIP2} -d -c $1 | ${TAR} xf - ) || error "Could not unpack $1 for diffs"
    376       ;;
    377     *.tar.xz)
    378       (${XZ} -d -c $1 | ${TAR} xf - ) || error "Could not unpack $1 for diffs"
    379       ;;
    380   esac
    381   (${XZ} -d -c $3 | ${TAR} xf - ) || error "Could not unpack $3 for diffs"
    382   ${DIFF} $2 $4 > ../${5%.xz}
    383   if [ $? -eq 2 ]; then
    384     error "Trouble making diffs from $1 to $3"
    385   fi
    386   ${XZ} ../${5%.xz} || error "Could not generate ../$5"
    387   changedir ..
    388   rm -rf $tmpdir
    389   FILE_LIST="${FILE_LIST} $5"
    390 }
    391 
    392 # Upload the files to the FTP server.
    393 upload_files() {
    394   inform "Uploading files"
    395 
    396   changedir "${WORKING_DIRECTORY}"
    397 
    398   # Make sure the directory exists on the server.
    399   if [ $LOCAL -eq 0 ]; then
    400     ${SSH} -l ${GCC_USERNAME} ${GCC_HOSTNAME} \
    401       mkdir -m 755 -p "${FTP_PATH}/diffs"
    402     UPLOAD_PATH="${GCC_USERNAME}@${GCC_HOSTNAME}:${FTP_PATH}"
    403   else
    404     mkdir -p "${FTP_PATH}/diffs" \
    405       || error "Could not create \`${FTP_PATH}'"
    406     UPLOAD_PATH=${FTP_PATH}
    407   fi
    408 
    409   # Then copy files to their respective (sub)directories.
    410   for x in gcc*.gz gcc*.xz; do
    411     if [ -e ${x} ]; then
    412       # Make sure the file will be readable on the server.
    413       chmod a+r ${x}
    414       # Copy it.
    415       case ${x} in
    416         *.diff.*)
    417           SUBDIR="diffs/";
    418           ;;
    419         *)
    420           SUBDIR="";
    421       esac
    422       ${SCP} ${x} ${UPLOAD_PATH}/${SUBDIR} \
    423         || error "Could not upload ${x}"
    424     fi
    425   done
    426 }
    427 
    428 # Print description if snapshot exists.
    429 snapshot_print() {
    430   if [ -e ${RELEASE}/$1 ]; then
    431     hash=`openssl  sha256  ${RELEASE}/$1 | sed -e 's#(.*)##' -e 's# *= *#=#'`
    432     hash2=`openssl sha1 ${RELEASE}/$1 | sed -e 's#(.*)##' -e 's# *= *#=#'`
    433 
    434     printf " %-37s%s\n\n  %s\n  %s\n\n" "$1" "$2" "$hash" "$hash2" \
    435       >> ${SNAPSHOT_README}
    436 
    437      echo "  <tr><td><a href=\"$1\">$1</a></td>" >> ${SNAPSHOT_INDEX}
    438      echo "      <td>$2</td></tr>" >> ${SNAPSHOT_INDEX}
    439   fi
    440 }
    441 
    442 # Announce a snapshot, both on the web and via mail.
    443 announce_snapshot() {
    444   inform "Updating links and READMEs on the FTP server"
    445 
    446   TEXT_DATE=`date --date=$DATE +%B\ %d,\ %Y`
    447   SNAPSHOT_README=${RELEASE}/README
    448   SNAPSHOT_INDEX=${RELEASE}/index.html
    449 
    450   changedir "${SNAPSHOTS_DIR}"
    451   echo \
    452 "Snapshot gcc-"${RELEASE}" is now available on
    453   https://gcc.gnu.org/pub/gcc/snapshots/"${RELEASE}"/
    454 and on various mirrors, see https://gcc.gnu.org/mirrors.html for details.
    455 
    456 This snapshot has been generated from the GCC "${BRANCH}" git branch
    457 with the following options: "git://gcc.gnu.org/git/gcc.git branch ${GITBRANCH} revision ${GITREV}"
    458 
    459 You'll find:
    460 " > ${SNAPSHOT_README}
    461 
    462   echo \
    463 "<html>
    464 
    465 <head>
    466 <title>GCC "${RELEASE}" Snapshot</title>
    467 </head>
    468 
    469 <body>
    470 <h1>GCC "${RELEASE}" Snapshot</h1>
    471 
    472 <p>The <a href =\"https://gcc.gnu.org/\">GCC Project</a> makes
    473 periodic snapshots of the GCC source tree available to the public
    474 for testing purposes.</p>
    475 
    476 <p>If you are planning to download and use one of our snapshots, then
    477 we highly recommend you join the GCC developers list.  Details for
    478 how to sign up can be found on the GCC project home page.</p>
    479 
    480 <p>This snapshot has been generated from the GCC "${BRANCH}" git branch
    481 with the following options: <code>"git://gcc.gnu.org/git/gcc.git branch ${GITBRANCH} revision ${GITREV}"</code></p>
    482 
    483 <table>" > ${SNAPSHOT_INDEX}
    484 
    485   snapshot_print gcc-${RELEASE}.tar.xz "Complete GCC"
    486 
    487   echo \
    488 "Diffs from "${BRANCH}"-"${LAST_DATE}" are available in the diffs/ subdirectory.
    489 
    490 When a particular snapshot is ready for public consumption the LATEST-"${BRANCH}"
    491 link is updated and a message is sent to the gcc list.  Please do not use
    492 a snapshot before it has been announced that way." >> ${SNAPSHOT_README}
    493 
    494   echo \
    495 "</table>
    496 <p>Diffs from "${BRANCH}"-"${LAST_DATE}" are available in the
    497 <a href=\"diffs/\">diffs/ subdirectory</a>.</p>
    498 
    499 <p>When a particular snapshot is ready for public consumption the LATEST-"${BRANCH}"
    500 link is updated and a message is sent to the gcc list.  Please do not use
    501 a snapshot before it has been announced that way.</p>
    502 
    503 <hr />
    504 
    505 <address>
    506 <a href=\"mailto:gcc (at] gcc.gnu.org\">gcc (at] gcc.gnu.org</a>
    507 <br />
    508 Last modified "${TEXT_DATE}"
    509 </address>
    510 </body>
    511 
    512 </html>" >> ${SNAPSHOT_INDEX}
    513 
    514   rm -f LATEST-${BRANCH}
    515   ln -s ${RELEASE} LATEST-${BRANCH}
    516 
    517   inform "Sending mail"
    518 
    519   export QMAILHOST=gcc.gnu.org
    520   mail -s "gcc-${RELEASE} is now available" gcc@gcc.gnu.org < ${SNAPSHOT_README}
    521 }
    522 
    523 ########################################################################
    524 # Initialization
    525 ########################################################################
    526 
    527 LC_ALL=C
    528 export LC_ALL
    529 
    530 # Today's date.
    531 DATE=`date "+%Y%m%d"`
    532 LONG_DATE=`date "+%Y-%m-%d"`
    533 
    534 GIT=${GIT:-git}
    535 # The server containing the GCC repository.
    536 GIT_SERVER="gcc.gnu.org"
    537 # The path to the repository on that server.
    538 GIT_REPOSITORY="/git/gcc.git"
    539 # The username to use when connecting to the server.
    540 GIT_USERNAME="${USER}"
    541 
    542 # The machine to which files will be uploaded.
    543 GCC_HOSTNAME="gcc.gnu.org"
    544 # The name of the account on the machine to which files are uploaded.
    545 GCC_USERNAME="gccadmin"
    546 # The directory in which the files will be placed (do not use ~user syntax).
    547 FTP_PATH=/var/ftp/pub/gcc
    548 # The directory in which snapshots will be placed.
    549 SNAPSHOTS_DIR=${FTP_PATH}/snapshots
    550 
    551 # The major number for the release.  For release `3.0.2' this would be
    552 # `3'
    553 RELEASE_MAJOR=""
    554 # The minor number for the release.  For release `3.0.2' this would be
    555 # `0'.
    556 RELEASE_MINOR=""
    557 # The revision number for the release.  For release `3.0.2' this would
    558 # be `2'.
    559 RELEASE_REVISION=""
    560 # The complete name of the release.
    561 RELEASE=""
    562 
    563 # The name of the branch from which the release should be made, in a
    564 # user-friendly form.
    565 BRANCH=""
    566 
    567 # The name of the branch from which the release should be made, as used
    568 # for our version control system.
    569 GITBRANCH=""
    570 
    571 # The tag to apply to the sources used for the release.
    572 TAG=""
    573 
    574 # The old tarballs from which to generate diffs.
    575 OLD_TARS=""
    576 
    577 # Local gcc git checkout to speed up git cloning.
    578 GIT_REFERENCE=""
    579 
    580 # The directory that will be used to construct the release.  The
    581 # release itself will be placed in a subdirectory of this directory.
    582 DESTINATION=${HOME}
    583 # The subdirectory.
    584 WORKING_DIRECTORY=""
    585 # The directory that will contain the GCC sources.
    586 SOURCE_DIRECTORY=""
    587 
    588 # Non-zero if this is the final release, rather than a prerelease.
    589 FINAL=0
    590 
    591 # Non-zero if we are building a snapshot, and don't build gcc or
    592 # include generated files.
    593 SNAPSHOT=0
    594 
    595 # Non-zero if we are running locally on gcc.gnu.org, and use local CVS
    596 # and copy directly to the FTP directory.
    597 LOCAL=0
    598 
    599 # Major operation modes.
    600 MODE_GZIP=0
    601 MODE_DIFFS=0
    602 MODE_SOURCES=0
    603 MODE_TARFILES=0
    604 MODE_UPLOAD=0
    605 
    606 # List of archive files generated; used to create .gz files from .xz.
    607 FILE_LIST=""
    608 
    609 # Programs we use.
    610 
    611 BZIP2="${BZIP2:-bzip2}"
    612 XZ="${XZ:-xz -T0 --best}"
    613 CVS="${CVS:-cvs -f -Q -z9}"
    614 DIFF="${DIFF:-diff -Nrcpad}"
    615 ENV="${ENV:-env}"
    616 GZIP="${GZIP:-gzip --best}"
    617 SCP="${SCP:-scp -p}"
    618 SSH="${SSH:-ssh}"
    619 TAR="${TAR:-tar}"
    620 
    621 ########################################################################
    622 # Command Line Processing
    623 ########################################################################
    624 
    625 # Parse the options.
    626 while getopts "d:fr:u:t:p:s:lb:" ARG; do
    627     case $ARG in
    628     d)    DESTINATION="${OPTARG}";;
    629     r)    RELEASE="${OPTARG}";;
    630     t)    TAG="${OPTARG}";;
    631     u)    GIT_USERNAME="${OPTARG}";;
    632     f)    FINAL=1;;
    633     s)    SNAPSHOT=1
    634           BRANCH=${OPTARG%:*}
    635           GITBRANCH=${OPTARG#*:}
    636           ;;
    637     l)    LOCAL=1
    638 	  SCP=cp
    639 	  PATH=~:/usr/local/bin:$PATH;;
    640     p)    OLD_TARS="${OLD_TARS} ${OPTARG}"
    641           if [ ! -f ${OPTARG} ]; then
    642 	    error "-p argument must name a tarball"
    643 	  fi;;
    644     b)    GIT_REFERENCE="${OPTARG}";;
    645     \?)   usage;;
    646     esac
    647 done
    648 shift `expr ${OPTIND} - 1`
    649 
    650 # Handle the major modes.
    651 while [ $# -ne 0 ]; do
    652     case $1 in
    653     diffs)    MODE_DIFFS=1;;
    654     gzip)     MODE_GZIP=1;;
    655     sources)  MODE_SOURCES=1;;
    656     tarfiles) MODE_TARFILES=1;;
    657     upload)   MODE_UPLOAD=1;;
    658     all)      MODE_SOURCES=1; MODE_TARFILES=1; MODE_DIFFS=1; MODE_UPLOAD=1;
    659               if [ $SNAPSHOT -ne 1 ]; then
    660                 # Only for releases and pre-releases.
    661                 MODE_GZIP=1;
    662               fi
    663               ;;
    664     *)        error "Unknown mode $1";;
    665     esac
    666     shift
    667 done
    668 
    669 # Perform consistency checking.
    670 if [ ${LOCAL} -eq 0 ] && [ -z ${GIT_USERNAME} ]; then
    671   error "No username specified"
    672 fi
    673 
    674 if [ ! -d ${DESTINATION} ]; then
    675   error "\`${DESTINATION}' is not a directory"
    676 fi
    677 
    678 if [ $SNAPSHOT -eq 0 ]; then
    679   if [ -z ${RELEASE} ]; then
    680     error "No release number specified"
    681   fi
    682 
    683   # Compute the major and minor release numbers.
    684   RELEASE_MAJOR=`echo $RELEASE | awk --assign FS=. '{ print $1; }'`
    685   RELEASE_MINOR=`echo $RELEASE | awk --assign FS=. '{ print $2; }'`
    686   RELEASE_REVISION=`echo $RELEASE | awk --assign FS=. '{ print $3; }'`
    687 
    688   if [ -z "${RELEASE_MAJOR}" ] || [ -z "${RELEASE_MINOR}" ]; then
    689     error "Release number \`${RELEASE}' is invalid"
    690   fi
    691 
    692   # Compute the full name of the release.
    693   if [ -z "${RELEASE_REVISION}" ]; then
    694     RELEASE="${RELEASE_MAJOR}.${RELEASE_MINOR}"
    695   else
    696     RELEASE="${RELEASE_MAJOR}.${RELEASE_MINOR}.${RELEASE_REVISION}"
    697   fi
    698 
    699   # Compute the name of the branch, which is based solely on the major
    700   # release number.
    701   GITBRANCH="releases/gcc-${RELEASE_MAJOR}"
    702 
    703   # If this is not a final release, set various parameters accordingly.
    704   if [ ${FINAL} -ne 1 ]; then
    705     RELEASE="${RELEASE}-RC-${DATE}"
    706     FTP_PATH="${SNAPSHOTS_DIR}/${RELEASE}"
    707   else
    708     FTP_PATH="${FTP_PATH}/releases/gcc-${RELEASE}/"
    709   fi
    710 else
    711   RELEASE=${BRANCH}-${DATE}
    712   FTP_PATH="${FTP_PATH}/snapshots/${RELEASE}"
    713 
    714   # If diffs are requested when building locally on gcc.gnu.org, we (usually)
    715   # know what the last snapshot date was and take the corresponding tarballs,
    716   # unless the user specified tarballs explicitly.
    717   if [ $MODE_DIFFS -ne 0 ] && [ $LOCAL -ne 0 ] && [ -z "${OLD_TARS}" ]; then
    718     LAST_DATE=`cat ~/.snapshot_date-${BRANCH}`
    719     OLD_TARS=${SNAPSHOTS_DIR}/${BRANCH}-${LAST_DATE}/gcc-${BRANCH}-${LAST_DATE}.tar.bz2
    720     if [ ! -e $OLD_TARS ]; then
    721       OLD_TARS=${SNAPSHOTS_DIR}/${BRANCH}-${LAST_DATE}/gcc-${BRANCH}-${LAST_DATE}.tar.xz
    722     fi
    723   fi
    724 fi
    725 
    726 # Compute the name of the WORKING_DIRECTORY and the SOURCE_DIRECTORY.
    727 WORKING_DIRECTORY="${DESTINATION}/gcc-${RELEASE}"
    728 SOURCE_DIRECTORY="${WORKING_DIRECTORY}/gcc-${RELEASE}"
    729 
    730 # Set up GITROOT.
    731 if [ $LOCAL -eq 0 ]; then
    732     GITROOT="git+ssh://${GIT_USERNAME}@${GIT_SERVER}${GIT_REPOSITORY}"
    733 else
    734     GITROOT="/git/gcc.git"
    735 fi
    736 export GITROOT
    737 
    738 ########################################################################
    739 # Main Program
    740 ########################################################################
    741 
    742 # Set the timezone to UTC
    743 TZ="UTC0"
    744 export TZ
    745 
    746 # Build the source directory.
    747 
    748 if [ $MODE_SOURCES -ne 0 ]; then
    749   build_sources
    750 fi
    751 
    752 # Build the tar files.
    753 
    754 if [ $MODE_TARFILES -ne 0 ]; then
    755   build_tarfiles
    756 fi
    757 
    758 # Build diffs
    759 
    760 if [ $MODE_DIFFS -ne 0 ]; then
    761   # Possibly build diffs.
    762   if [ -n "$OLD_TARS" ]; then
    763     for old_tar in $OLD_TARS; do
    764       build_diffs $old_tar
    765     done
    766   fi
    767 fi
    768 
    769 # Build gzip files
    770 if [ $MODE_GZIP -ne 0 ]; then
    771   build_gzip
    772 fi
    773 
    774 # Upload them to the FTP server.
    775 if [ $MODE_UPLOAD -ne 0 ]; then
    776   upload_files
    777 
    778   # For snapshots, make some further updates.
    779   if [ $SNAPSHOT -ne 0 ] && [ $LOCAL -ne 0 ]; then
    780     announce_snapshot
    781 
    782     # Update snapshot date file.
    783     changedir ~
    784     echo $DATE > .snapshot_date-${BRANCH}
    785 
    786     # Remove working directory
    787     rm -rf ${WORKING_DIRECTORY}
    788   fi
    789 fi
    790