|  | #! /bin/sh | 
|  |  | 
|  | ######################################################################## | 
|  | # | 
|  | # File:   gcc_release | 
|  | # Author: Jeffrey Law, Bernd Schmidt, Mark Mitchell | 
|  | # Date:   2001-05-25 | 
|  | # | 
|  | # Contents: | 
|  | #   Script to create a GCC release. | 
|  | # | 
|  | # Copyright (c) 2001, 2002, 2006 Free Software Foundation. | 
|  | # | 
|  | # This file is part of GCC. | 
|  | # | 
|  | # GCC is free software; you can redistribute it and/or modify | 
|  | # it under the terms of the GNU General Public License as published by | 
|  | # the Free Software Foundation; either version 2, or (at your option) | 
|  | # any later version. | 
|  | # | 
|  | # GCC is distributed in the hope that it will be useful, | 
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | # GNU General Public License for more details. | 
|  | # | 
|  | # You should have received a copy of the GNU General Public License | 
|  | # along with GCC; see the file COPYING.  If not, write to | 
|  | # the Free Software Foundation, 51 Franklin Street, Fifth Floor, | 
|  | # Boston, MA 02110-1301, USA. | 
|  | # | 
|  | ######################################################################## | 
|  |  | 
|  | ######################################################################## | 
|  | # Notes | 
|  | ######################################################################## | 
|  |  | 
|  | # Here is an example usage of this script, to create a GCC 3.0.2 | 
|  | # prerelease: | 
|  | # | 
|  | #   gcc_release -r 3.0.2 | 
|  | # | 
|  | # This script will automatically use the head of the release branch | 
|  | # to generate the release. | 
|  |  | 
|  | ######################################################################## | 
|  | # Functions | 
|  | ######################################################################## | 
|  |  | 
|  | # Issue the error message given by $1 and exit with a non-zero | 
|  | # exit code. | 
|  |  | 
|  | error() { | 
|  | echo "gcc_release: error: $1" | 
|  | exit 1 | 
|  | } | 
|  |  | 
|  | # Issue the informational message given by $1. | 
|  |  | 
|  | inform() { | 
|  | echo "gcc_release: $1" | 
|  | } | 
|  |  | 
|  | # Issue a usage message explaining how to use this script. | 
|  |  | 
|  | usage() { | 
|  | cat <<EOF | 
|  | gcc_release -r release [-f] [further options] | 
|  | gcc_release -s name:svnbranch [further options] | 
|  |  | 
|  | Options: | 
|  |  | 
|  | -r release           Version of the form X.Y or X.Y.Z. | 
|  | -s name:svnbranch    Create a snapshot, not a real release. | 
|  |  | 
|  | -d destination       Local working directory where we will build the release | 
|  | (default=${HOME}). | 
|  | -f                   Create a final release (and update ChangeLogs,...). | 
|  | -l                   Indicate that we are running on gcc.gnu.org. | 
|  | -p previous-tarball  Location of a previous tarball (to generate diff files). | 
|  | -t tag               Tag to mark the release in SVN. | 
|  | -u username          Username for upload operations. | 
|  | EOF | 
|  | exit 1 | 
|  | } | 
|  |  | 
|  | # Change to the directory given by $1. | 
|  |  | 
|  | changedir() { | 
|  | cd $1 || \ | 
|  | error "Could not change directory to $1" | 
|  | } | 
|  |  | 
|  | # Each of the arguments is a directory name, relative to the top | 
|  | # of the source tree.  Return another name for that directory, relative | 
|  | # to the working directory. | 
|  |  | 
|  | adjust_dirs() { | 
|  | for x in $@; do | 
|  | echo `basename ${SOURCE_DIRECTORY}`/$x | 
|  | done | 
|  | } | 
|  |  | 
|  | # Build the source tree that will be the basis for the release | 
|  | # in ${WORKING_DIRECTORY}/gcc-${RELEASE}. | 
|  |  | 
|  | build_sources() { | 
|  | # If the WORKING_DIRECTORY already exists, do not risk destroying it. | 
|  | if [ -r ${WORKING_DIRECTORY} ]; then | 
|  | error "\`${WORKING_DIRECTORY}' already exists" | 
|  | fi | 
|  | # Create the WORKING_DIRECTORY. | 
|  | mkdir "${WORKING_DIRECTORY}" \ | 
|  | || error "Could not create \`${WORKING_DIRECTORY}'" | 
|  | changedir "${WORKING_DIRECTORY}" | 
|  |  | 
|  | # If this is a final release, make sure that the ChangeLogs | 
|  | # and version strings are updated. | 
|  | if [ ${FINAL} -ne 0 ]; then | 
|  | inform "Updating ChangeLogs and version files" | 
|  |  | 
|  | ${SVN} -q co "${SVNROOT}/${SVNBRANCH}" "`basename ${SOURCE_DIRECTORY}`" ||\ | 
|  | error "Could not check out release sources" | 
|  | for x in `find ${SOURCE_DIRECTORY} -name ChangeLog`; do | 
|  | # Update this ChangeLog file only if it does not yet contain the | 
|  | # entry we are going to add.  (This is a safety net for repeated | 
|  | # runs of this script for the same release.) | 
|  | if ! grep "GCC ${RELEASE} released." ${x} > /dev/null ; then | 
|  | cat - ${x} > ${x}.new <<EOF | 
|  | ${LONG_DATE}  Release Manager | 
|  |  | 
|  | * GCC ${RELEASE} released. | 
|  |  | 
|  | EOF | 
|  | mv ${x}.new ${x} || \ | 
|  | error "Could not update ${x}" | 
|  | (changedir `dirname ${x}` && \ | 
|  | ${SVN} -q ci -m 'Mark ChangeLog' `basename ${x}`) || \ | 
|  | error "Could not commit ${x}" | 
|  | fi | 
|  | done | 
|  |  | 
|  | # Update gcc/DEV-PHASE if it exists, otherwise gcc/version.c. | 
|  |  | 
|  | if [ -f ${SOURCE_DIRECTORY}/gcc/DEV-PHASE ]; then | 
|  | [ `cat ${SOURCE_DIRECTORY}/gcc/BASE-VER` = ${RELEASE} ] || \ | 
|  | error "Release number ${RELEASE} does not match BASE-VER" | 
|  | (changedir ${SOURCE_DIRECTORY}/gcc && \ | 
|  | : > DEV-PHASE && \ | 
|  | ${SVN} -q ci -m 'Mark as release' DEV-PHASE) || \ | 
|  | error "Could not update DEV-PHASE" | 
|  | else | 
|  | for x in gcc/version.c; do | 
|  | y=`basename ${x}` | 
|  | (changedir `dirname ${SOURCE_DIRECTORY}/${x}` && \ | 
|  | sed -e 's|version_string\[\] = \".*\"|version_string\[\] = \"'${RELEASE}'\"|g' < ${y} > ${y}.new && \ | 
|  | mv ${y}.new ${y} && \ | 
|  | ${SVN} -q ci -m 'Update version' ${y}) || \ | 
|  | error "Could not update ${x}" | 
|  | done | 
|  | fi | 
|  |  | 
|  | # Make sure we tag the sources for a final release. | 
|  | TAG="tags/gcc_`echo ${RELEASE} | tr . _`_release" | 
|  |  | 
|  | rm -rf ${SOURCE_DIRECTORY} | 
|  | fi | 
|  |  | 
|  | # Tag the sources. | 
|  | if [ -n "${TAG}" ]; then | 
|  | inform "Tagging sources as ${TAG}" | 
|  | # We don't want to overwrite an existing tag.  So, if the tag | 
|  | # already exists, issue an error message; the release manager can | 
|  | # manually remove the tag if appropriate. | 
|  | echo "${SVN} ls ${SVNROOT}/${TAG}/ChangeLog" | 
|  | if ${SVN} ls "${SVNROOT}/${TAG}/ChangeLog"; then | 
|  | error "Tag ${TAG} already exists" | 
|  | fi | 
|  | ${SVN} -m "Tagging source as ${TAG}" cp "${SVNROOT}/${SVNBRANCH}" "${SVNROOT}/${TAG}" || \ | 
|  | error "Could not tag sources" | 
|  | SVNBRANCH=${TAG} | 
|  | fi | 
|  | SVNREV=`${SVN} info "${SVNROOT}/${SVNBRANCH}"|awk '/Revision:/ {print $2}'` | 
|  |  | 
|  | # Export the current sources. | 
|  | inform "Retrieving sources (svn export -r ${SVNREV} ${SVNROOT}/${SVNBRANCH})" | 
|  |  | 
|  | ${SVN} -q export -r${SVNREV} "${SVNROOT}/${SVNBRANCH}" "`basename ${SOURCE_DIRECTORY}`" ||\ | 
|  | error "Could not retrieve sources" | 
|  |  | 
|  | # Run gcc_update on them to set up the timestamps nicely, and (re)write | 
|  | # the LAST_UPDATED file containing the SVN tag/revision used. | 
|  | changedir "gcc-${RELEASE}" | 
|  | contrib/gcc_update --touch | 
|  | echo "Obtained from SVN: ${SVNBRANCH} revision ${SVNREV}" > LAST_UPDATED | 
|  |  | 
|  | # Obtain some documentation files from the wwwdocs module. | 
|  | inform "Retrieving HTML documentation" | 
|  | changedir "${WORKING_DIRECTORY}" | 
|  | for x in bugs faq; do | 
|  | (${CVS} export -r HEAD wwwdocs/htdocs/${x}.html && \ | 
|  | cp ${WORKING_DIRECTORY}/wwwdocs/htdocs/${x}.html \ | 
|  | ${SOURCE_DIRECTORY}) || \ | 
|  | error "Could not retrieve ${x}.html" | 
|  | done | 
|  |  | 
|  | inform "Generating plain-text documentation from HTML" | 
|  | changedir "${SOURCE_DIRECTORY}" | 
|  | for file in *.html; do | 
|  | newfile=`echo $file | sed -e 's/.html//' | tr "[:lower:]" "[:upper:]"` | 
|  | (${ENV} TERM=vt100 lynx -dump $file \ | 
|  | | sed -e "s#file://localhost`/bin/pwd`\(.*\)#http://gcc.gnu.org\1#g" \ | 
|  | > $newfile) || \ | 
|  | error "Could not generate text-only version of ${file}" | 
|  | done | 
|  |  | 
|  | # For a prerelease or real release, we need to generate additional | 
|  | # files not present in SVN. | 
|  | changedir "${SOURCE_DIRECTORY}" | 
|  | if [ $SNAPSHOT -ne 1 ]; then | 
|  | # Generate the documentation. | 
|  | inform "Building install docs" | 
|  | SOURCEDIR=${SOURCE_DIRECTORY}/gcc/doc | 
|  | DESTDIR=${SOURCE_DIRECTORY}/INSTALL | 
|  | export SOURCEDIR | 
|  | export DESTDIR | 
|  | ${SOURCE_DIRECTORY}/gcc/doc/install.texi2html | 
|  |  | 
|  | # Regenerate the NEWS file. | 
|  | contrib/gennews > NEWS || \ | 
|  | error "Could not regenerate NEWS files" | 
|  |  | 
|  | # Now, we must build the compiler in order to create any generated | 
|  | # files that are supposed to go in the source directory.  This is | 
|  | # also a good sanity check to make sure that the release builds | 
|  | # on at least one platform. | 
|  | inform "Building compiler" | 
|  | OBJECT_DIRECTORY=../objdir | 
|  | contrib/gcc_build -d ${SOURCE_DIRECTORY} -o ${OBJECT_DIRECTORY} \ | 
|  | -c "--enable-generated-files-in-srcdir" build || \ | 
|  | error "Could not rebuild GCC" | 
|  | fi | 
|  |  | 
|  | # Move message catalogs to source directory. | 
|  | mv ../objdir/gcc/po/*.gmo gcc/po/ | 
|  | [ -f libcpp/po/cpplib.pot ] && mv ../objdir/libcpp/po/*.gmo libcpp/po/ | 
|  |  | 
|  | # Create a "MD5SUMS" file to use for checking the validity of the release. | 
|  | echo \ | 
|  | "# This file contains the MD5 checksums of the files in the | 
|  | # gcc-"${RELEASE}".tar.bz2 tarball. | 
|  | # | 
|  | # Besides verifying that all files in the tarball were correctly expanded, | 
|  | # it also can be used to determine if any files have changed since the | 
|  | # tarball was expanded or to verify that a patchfile was correctly applied. | 
|  | # | 
|  | # Suggested usage: | 
|  | # md5sum -c MD5SUMS | grep -v \"OK$\" | 
|  | " > MD5SUMS | 
|  |  | 
|  | find . -type f | | 
|  | sed -e 's:^\./::' -e '/MD5SUMS/d' | | 
|  | sort | | 
|  | xargs md5sum >>MD5SUMS | 
|  | } | 
|  |  | 
|  | # Buid a single tarfile.  The first argument is the name of the name | 
|  | # of the tarfile to build, without any suffixes.  They will be added | 
|  | # automatically.  The rest of the arguments are the files or | 
|  | # directories to include, and possibly other arguments to tar. | 
|  |  | 
|  | build_tarfile() { | 
|  | # Get the name of the destination tar file. | 
|  | TARFILE="$1.tar.bz2" | 
|  | shift | 
|  |  | 
|  | # Build the tar file itself. | 
|  | (${TAR} cf - "$@" | ${BZIP2} > ${TARFILE}) || \ | 
|  | error "Could not build tarfile" | 
|  | FILE_LIST="${FILE_LIST} ${TARFILE}" | 
|  | } | 
|  |  | 
|  | # Build a single tarfile if any of the directories listed exist, | 
|  | # but not if none of them do (because that component doesn't exist | 
|  | # on this branch). | 
|  | maybe_build_tarfile() { | 
|  | dest=$1 | 
|  | shift | 
|  | dir_exists=0 | 
|  | for maybe_dir in "$@"; do | 
|  | if [ -d "$maybe_dir" ]; then | 
|  | dir_exists=1 | 
|  | fi | 
|  | done | 
|  | if [ $dir_exists = 1 ]; then | 
|  | build_tarfile "$dest" "$@" | 
|  | else | 
|  | echo "Not building $dest tarfile" | 
|  | fi | 
|  | } | 
|  |  | 
|  | # Build the various tar files for the release. | 
|  |  | 
|  | build_tarfiles() { | 
|  | inform "Building tarfiles" | 
|  |  | 
|  | changedir "${WORKING_DIRECTORY}" | 
|  |  | 
|  | # The GNU Coding Standards specify that all files should | 
|  | # world readable. | 
|  | chmod -R a+r ${SOURCE_DIRECTORY} | 
|  | # And that all directories have mode 777. | 
|  | find ${SOURCE_DIRECTORY} -type d -exec chmod 777 {} \; | 
|  |  | 
|  | # Build one huge tarfile for the entire distribution. | 
|  | build_tarfile gcc-${RELEASE} `basename ${SOURCE_DIRECTORY}` | 
|  |  | 
|  | # Now, build one for each of the languages. | 
|  | maybe_build_tarfile gcc-ada-${RELEASE} ${ADA_DIRS} | 
|  | maybe_build_tarfile gcc-g++-${RELEASE} ${CPLUSPLUS_DIRS} | 
|  | maybe_build_tarfile gcc-g77-${RELEASE} ${FORTRAN_DIRS} | 
|  | maybe_build_tarfile gcc-fortran-${RELEASE} ${FORTRAN95_DIRS} | 
|  | maybe_build_tarfile gcc-java-${RELEASE} ${JAVA_DIRS} | 
|  | maybe_build_tarfile gcc-objc-${RELEASE} ${OBJECTIVEC_DIRS} | 
|  | maybe_build_tarfile gcc-testsuite-${RELEASE} ${TESTSUITE_DIRS} | 
|  |  | 
|  | # The core is everything else. | 
|  | EXCLUDES="" | 
|  | for x in ${ADA_DIRS} ${CPLUSPLUS_DIRS} ${FORTRAN_DIRS} ${FORTRAN95_DIRS}\ | 
|  | ${JAVA_DIRS} ${OBJECTIVEC_DIRS} ${TESTSUITE_DIRS}; do | 
|  | EXCLUDES="${EXCLUDES} --exclude $x" | 
|  | done | 
|  | build_tarfile gcc-core-${RELEASE} ${EXCLUDES} \ | 
|  | `basename ${SOURCE_DIRECTORY}` | 
|  | } | 
|  |  | 
|  | # Build .gz files. | 
|  | build_gzip() { | 
|  | for f in ${FILE_LIST}; do | 
|  | target=${f%.bz2}.gz | 
|  | (${BZIP2} -d -c $f | ${GZIP} > ${target}) || error "Could not create ${target}" | 
|  | done | 
|  | } | 
|  |  | 
|  | # Build diffs against an old release. | 
|  | build_diffs() { | 
|  | old_dir=${1%/*} | 
|  | old_file=${1##*/} | 
|  | old_vers=${old_file%.tar.bz2} | 
|  | old_vers=${old_vers#gcc-} | 
|  | inform "Building diffs against version $old_vers" | 
|  | for f in gcc gcc-ada gcc-g++ gcc-g77 gcc-fortran gcc-java gcc-objc gcc-testsuite gcc-core; do | 
|  | old_tar=${old_dir}/${f}-${old_vers}.tar.bz2 | 
|  | new_tar=${WORKING_DIRECTORY}/${f}-${RELEASE}.tar.bz2 | 
|  | if [ ! -e $old_tar ]; then | 
|  | inform "$old_tar not found; not generating diff file" | 
|  | elif [ ! -e $new_tar ]; then | 
|  | inform "$new_tar not found; not generating diff file" | 
|  | else | 
|  | build_diff $old_tar gcc-${old_vers} $new_tar gcc-${RELEASE} \ | 
|  | ${f}-${old_vers}-${RELEASE}.diff.bz2 | 
|  | fi | 
|  | done | 
|  | } | 
|  |  | 
|  | # Build an individual diff. | 
|  | build_diff() { | 
|  | changedir "${WORKING_DIRECTORY}" | 
|  | tmpdir=gccdiff.$$ | 
|  | mkdir $tmpdir || error "Could not create directory $tmpdir" | 
|  | changedir $tmpdir | 
|  | (${BZIP2} -d -c $1 | ${TAR} xf - ) || error "Could not unpack $1 for diffs" | 
|  | (${BZIP2} -d -c $3 | ${TAR} xf - ) || error "Could not unpack $3 for diffs" | 
|  | ${DIFF} $2 $4 > ../${5%.bz2} | 
|  | if [ $? -eq 2 ]; then | 
|  | error "Trouble making diffs from $1 to $3" | 
|  | fi | 
|  | ${BZIP2} ../${5%.bz2} || error "Could not generate ../$5" | 
|  | changedir .. | 
|  | rm -rf $tmpdir | 
|  | FILE_LIST="${FILE_LIST} $5" | 
|  | } | 
|  |  | 
|  | # Upload the files to the FTP server. | 
|  | upload_files() { | 
|  | inform "Uploading files" | 
|  |  | 
|  | changedir "${WORKING_DIRECTORY}" | 
|  |  | 
|  | # Make sure the directory exists on the server. | 
|  | if [ $LOCAL -eq 0 ]; then | 
|  | ${SSH} -l ${GCC_USERNAME} ${GCC_HOSTNAME} \ | 
|  | mkdir -p "${FTP_PATH}/diffs" | 
|  | UPLOAD_PATH="${GCC_USERNAME}@${GCC_HOSTNAME}:${FTP_PATH}" | 
|  | else | 
|  | mkdir -p "${FTP_PATH}/diffs" \ | 
|  | || error "Could not create \`${FTP_PATH}'" | 
|  | UPLOAD_PATH=${FTP_PATH} | 
|  | fi | 
|  |  | 
|  | # Then copy files to their respective (sub)directories. | 
|  | for x in gcc*.gz gcc*.bz2; do | 
|  | if [ -e ${x} ]; then | 
|  | # Make sure the file will be readable on the server. | 
|  | chmod a+r ${x} | 
|  | # Copy it. | 
|  | case ${x} in | 
|  | *.diff.*) | 
|  | SUBDIR="diffs/"; | 
|  | ;; | 
|  | *) | 
|  | SUBDIR=""; | 
|  | esac | 
|  | ${SCP} ${x} ${UPLOAD_PATH}/${SUBDIR} \ | 
|  | || error "Could not upload ${x}" | 
|  | fi | 
|  | done | 
|  | } | 
|  |  | 
|  | #Print description if snapshot exists | 
|  | snapshot_print() { | 
|  | if [ -e ${RELEASE}/$1 ]; then | 
|  | printf "%-38s%s\n\n" "$1" "$2" >> ${SNAPSHOT_README} | 
|  | echo "  <tr><td><a href=\"$1\">$1</a></td>" >> ${SNAPSHOT_INDEX} | 
|  | echo "      <td>$2</td></tr>" >> ${SNAPSHOT_INDEX} | 
|  | fi | 
|  | } | 
|  |  | 
|  | # Announce a snapshot, both on the web and via mail. | 
|  | announce_snapshot() { | 
|  | inform "Updating links and READMEs on the FTP server" | 
|  |  | 
|  | TEXT_DATE=`date --date=$DATE +%B\ %d,\ %Y` | 
|  | SNAPSHOT_README=${RELEASE}/README | 
|  | SNAPSHOT_INDEX=${RELEASE}/index.html | 
|  |  | 
|  | changedir "${SNAPSHOTS_DIR}" | 
|  | echo \ | 
|  | "Snapshot gcc-"${RELEASE}" is now available on | 
|  | ftp://gcc.gnu.org/pub/gcc/snapshots/"${RELEASE}"/ | 
|  | and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. | 
|  |  | 
|  | This snapshot has been generated from the GCC "${BRANCH}" SVN branch | 
|  | with the following options: "svn://gcc.gnu.org/svn/gcc/${SVNBRANCH} revision ${SVNREV}" | 
|  |  | 
|  | You'll find: | 
|  | " > ${SNAPSHOT_README} | 
|  |  | 
|  | echo \ | 
|  | "<html> | 
|  |  | 
|  | <head> | 
|  | <title>GCC "${RELEASE}" Snapshot</title> | 
|  | </head> | 
|  |  | 
|  | <body> | 
|  | <h1>GCC "${RELEASE}" Snapshot</h1> | 
|  |  | 
|  | <p>The <a href =\"http://gcc.gnu.org/\">GCC Project</a> makes | 
|  | periodic snapshots of the GCC source tree available to the public | 
|  | for testing purposes.</p> | 
|  |  | 
|  | <p>If you are planning to download and use one of our snapshots, then | 
|  | we highly recommend you join the GCC developers list.  Details for | 
|  | how to sign up can be found on the GCC project home page.</p> | 
|  |  | 
|  | <p>This snapshot has been generated from the GCC "${BRANCH}" SVN branch | 
|  | with the following options: <code>"svn://gcc.gnu.org/svn/gcc/${SVNBRANCH} revision ${SVNREV}"</code></p> | 
|  |  | 
|  | <table>" > ${SNAPSHOT_INDEX} | 
|  |  | 
|  | snapshot_print gcc-${RELEASE}.tar.bz2 "Complete GCC (includes all of below)" | 
|  | snapshot_print gcc-core-${RELEASE}.tar.bz2 "C front end and core compiler" | 
|  | snapshot_print gcc-ada-${RELEASE}.tar.bz2 "Ada front end and runtime" | 
|  | snapshot_print gcc-fortran-${RELEASE}.tar.bz2 "Fortran front end and runtime" | 
|  | snapshot_print gcc-g++-${RELEASE}.tar.bz2 "C++ front end and runtime" | 
|  | snapshot_print gcc-g77-${RELEASE}.tar.bz2 "Fortran 77 front end and runtime" | 
|  | snapshot_print gcc-java-${RELEASE}.tar.bz2 "Java front end and runtime" | 
|  | snapshot_print gcc-objc-${RELEASE}.tar.bz2 "Objective-C front end and runtime" | 
|  | snapshot_print gcc-testsuite-${RELEASE}.tar.bz2 "The GCC testsuite" | 
|  |  | 
|  | echo \ | 
|  | "Diffs from "${BRANCH}"-"${LAST_DATE}" are available in the diffs/ subdirectory. | 
|  |  | 
|  | When a particular snapshot is ready for public consumption the LATEST-"${BRANCH}" | 
|  | link is updated and a message is sent to the gcc list.  Please do not use | 
|  | a snapshot before it has been announced that way." >> ${SNAPSHOT_README} | 
|  |  | 
|  | echo \ | 
|  | "</table> | 
|  | <p>Diffs from "${BRANCH}"-"${LAST_DATE}" are available in the | 
|  | <a href=\"diffs/\">diffs/ subdirectory</a>.</p> | 
|  |  | 
|  | <p>When a particular snapshot is ready for public consumption the LATEST-"${BRANCH}" | 
|  | link is updated and a message is sent to the gcc list.  Please do not use | 
|  | a snapshot before it has been announced that way.</p> | 
|  |  | 
|  | <hr /> | 
|  |  | 
|  | <address> | 
|  | <a href=\"mailto:gcc@gcc.gnu.org\">gcc@gcc.gnu.org</a> | 
|  | <br /> | 
|  | Last modified "${TEXT_DATE}" | 
|  | </address> | 
|  | </body> | 
|  |  | 
|  | </html>" >> ${SNAPSHOT_INDEX} | 
|  |  | 
|  | rm -f LATEST-${BRANCH} | 
|  | ln -s ${RELEASE} LATEST-${BRANCH} | 
|  |  | 
|  | inform "Sending mail" | 
|  |  | 
|  | export QMAILHOST=gcc.gnu.org | 
|  | mail -s "gcc-${RELEASE} is now available" gcc@gcc.gnu.org < ${SNAPSHOT_README} | 
|  | } | 
|  |  | 
|  | ######################################################################## | 
|  | # Initialization | 
|  | ######################################################################## | 
|  |  | 
|  | LC_ALL=C | 
|  | export LC_ALL | 
|  |  | 
|  | # Today's date. | 
|  | DATE=`date "+%Y%m%d"` | 
|  | LONG_DATE=`date "+%Y-%m-%d"` | 
|  |  | 
|  | SVN=${SVN:-/usr/bin/svn} | 
|  | # The CVS server containing the GCC repository. | 
|  | SVN_SERVER="gcc.gnu.org" | 
|  | # The path to the repository on that server. | 
|  | SVN_REPOSITORY="/svn/gcc" | 
|  | # The username to use when connecting to the server. | 
|  | SVN_USERNAME="${USER}" | 
|  |  | 
|  | # The machine to which files will be uploaded. | 
|  | GCC_HOSTNAME="gcc.gnu.org" | 
|  | # The name of the account on the machine to which files are uploaded. | 
|  | GCC_USERNAME="gccadmin" | 
|  | # The directory in which the files will be placed (do not use ~user syntax). | 
|  | FTP_PATH=/var/ftp/pub/gcc | 
|  | # The directory in which snapshots will be placed. | 
|  | SNAPSHOTS_DIR=${FTP_PATH}/snapshots | 
|  |  | 
|  | # The major number for the release.  For release `3.0.2' this would be | 
|  | # `3' | 
|  | RELEASE_MAJOR="" | 
|  | # The minor number for the release.  For release `3.0.2' this would be | 
|  | # `0'. | 
|  | RELEASE_MINOR="" | 
|  | # The revision number for the release.  For release `3.0.2' this would | 
|  | # be `2'. | 
|  | RELEASE_REVISION="" | 
|  | # The complete name of the release. | 
|  | RELEASE="" | 
|  |  | 
|  | # The name of the branch from which the release should be made, in a | 
|  | # user-friendly form. | 
|  | BRANCH="" | 
|  |  | 
|  | # The name of the branch from which the release should be made, as used | 
|  | # for our version control system. | 
|  | SVNBRANCH="" | 
|  |  | 
|  | # The tag to apply to the sources used for the release. | 
|  | TAG="" | 
|  |  | 
|  | # The old tarballs from which to generate diffs. | 
|  | OLD_TARS="" | 
|  |  | 
|  | # The directory that will be used to construct the release.  The | 
|  | # release itself will be placed in a subdirectory of this diretory. | 
|  | DESTINATION=${HOME} | 
|  | # The subdirectory. | 
|  | WORKING_DIRECTORY="" | 
|  | # The directory that will contain the GCC sources. | 
|  | SOURCE_DIRECTORY="" | 
|  |  | 
|  | # The directories that should be part of the various language-specific | 
|  | # tar files.  These are all relative to the top of the source tree. | 
|  | ADA_DIRS="gcc/ada libada gnattools" | 
|  | CPLUSPLUS_DIRS="gcc/cp libstdc++-v3" | 
|  | FORTRAN_DIRS="gcc/f libf2c" | 
|  | FORTRAN95_DIRS="gcc/fortran libgfortran" | 
|  | JAVA_DIRS="gcc/java libjava libffi fastjar zlib boehm-gc" | 
|  | OBJECTIVEC_DIRS="gcc/objc gcc/objcp libobjc" | 
|  | TESTSUITE_DIRS="gcc/testsuite" | 
|  |  | 
|  | # Non-zero if this is the final release, rather than a prerelease. | 
|  | FINAL=0 | 
|  |  | 
|  | # Non-zero if we are building a snapshot, and don't build gcc or | 
|  | # include generated files. | 
|  | SNAPSHOT=0 | 
|  |  | 
|  | # Non-zero if we are running locally on gcc.gnu.org, and use local CVS | 
|  | # and copy directly to the FTP directory. | 
|  | LOCAL=0 | 
|  |  | 
|  | # Major operation modes. | 
|  | MODE_GZIP=0 | 
|  | MODE_DIFFS=0 | 
|  | MODE_SOURCES=0 | 
|  | MODE_TARFILES=0 | 
|  | MODE_UPLOAD=0 | 
|  |  | 
|  | # List of archive files generated; used to create .gz files from .bz2. | 
|  | FILE_LIST="" | 
|  |  | 
|  | # Programs we use. | 
|  |  | 
|  | BZIP2="${BZIP2:-bzip2}" | 
|  | CVS="${CVS:-cvs -f -Q -z9}" | 
|  | DIFF="${DIFF:-diff -Nrcpad}" | 
|  | ENV="${ENV:-env}" | 
|  | GZIP="${GZIP:-gzip --best}" | 
|  | SCP="${SCP:-scp -p}" | 
|  | SSH="${SSH:-ssh}" | 
|  | TAR="${TAR:-tar}" | 
|  |  | 
|  | ######################################################################## | 
|  | # Command Line Processing | 
|  | ######################################################################## | 
|  |  | 
|  | # Parse the options. | 
|  | while getopts "d:fr:u:t:p:s:l" ARG; do | 
|  | case $ARG in | 
|  | d)    DESTINATION="${OPTARG}";; | 
|  | r)    RELEASE="${OPTARG}";; | 
|  | t)    TAG="${OPTARG}";; | 
|  | u)    SVN_USERNAME="${OPTARG}";; | 
|  | f)    FINAL=1;; | 
|  | s)    SNAPSHOT=1 | 
|  | BRANCH=${OPTARG%:*} | 
|  | SVNBRANCH=${OPTARG#*:} | 
|  | ;; | 
|  | l)    LOCAL=1 | 
|  | SCP=cp | 
|  | PATH=~:/usr/local/bin:$PATH;; | 
|  | p)    OLD_TARS="${OLD_TARS} ${OPTARG}" | 
|  | if [ ! -f ${OPTARG} ]; then | 
|  | error "-p argument must name a tarball" | 
|  | fi;; | 
|  | \?)   usage;; | 
|  | esac | 
|  | done | 
|  | shift `expr ${OPTIND} - 1` | 
|  |  | 
|  | # Handle the major modes. | 
|  | while [ $# -ne 0 ]; do | 
|  | case $1 in | 
|  | diffs)    MODE_DIFFS=1;; | 
|  | gzip)     MODE_GZIP=1;; | 
|  | sources)  MODE_SOURCES=1;; | 
|  | tarfiles) MODE_TARFILES=1;; | 
|  | upload)   MODE_UPLOAD=1;; | 
|  | all)      MODE_SOURCES=1; MODE_TARFILES=1; MODE_DIFFS=1; MODE_UPLOAD=1; | 
|  | if [ $SNAPSHOT -ne 1 ]; then | 
|  | # Only for releases and pre-releases. | 
|  | MODE_GZIP=1; | 
|  | fi | 
|  | ;; | 
|  | *)        error "Unknown mode $1";; | 
|  | esac | 
|  | shift | 
|  | done | 
|  |  | 
|  | # Perform consistency checking. | 
|  | if [ ${LOCAL} -eq 0 ] && [ -z ${SVN_USERNAME} ]; then | 
|  | error "No username specified" | 
|  | fi | 
|  |  | 
|  | if [ ! -d ${DESTINATION} ]; then | 
|  | error "\`${DESTINATION}' is not a directory" | 
|  | fi | 
|  |  | 
|  | if [ $SNAPSHOT -eq 0 ]; then | 
|  | if [ -z ${RELEASE} ]; then | 
|  | error "No release number specified" | 
|  | fi | 
|  |  | 
|  | # Compute the major and minor release numbers. | 
|  | RELEASE_MAJOR=`echo $RELEASE | awk --assign FS=. '{ print $1; }'` | 
|  | RELEASE_MINOR=`echo $RELEASE | awk --assign FS=. '{ print $2; }'` | 
|  | RELEASE_REVISION=`echo $RELEASE | awk --assign FS=. '{ print $3; }'` | 
|  |  | 
|  | if [ -z "${RELEASE_MAJOR}" ] || [ -z "${RELEASE_MINOR}" ]; then | 
|  | error "Release number \`${RELEASE}' is invalid" | 
|  | fi | 
|  |  | 
|  | # Compute the full name of the release. | 
|  | if [ -z "${RELEASE_REVISION}" ]; then | 
|  | RELEASE="${RELEASE_MAJOR}.${RELEASE_MINOR}" | 
|  | else | 
|  | RELEASE="${RELEASE_MAJOR}.${RELEASE_MINOR}.${RELEASE_REVISION}" | 
|  | fi | 
|  |  | 
|  | # Compute the name of the branch, which is based solely on the major | 
|  | # and minor release numbers. | 
|  | SVNBRANCH="branches/gcc-${RELEASE_MAJOR}_${RELEASE_MINOR}-branch" | 
|  |  | 
|  | # If this is not a final release, set various parameters accordingly. | 
|  | if [ ${FINAL} -ne 1 ]; then | 
|  | RELEASE="${RELEASE}-RC-${DATE}" | 
|  | FTP_PATH="${SNAPSHOTS_DIR}/${RELEASE}" | 
|  | else | 
|  | FTP_PATH="${FTP_PATH}/releases/gcc-${RELEASE}/" | 
|  | fi | 
|  | else | 
|  | RELEASE=${BRANCH}-${DATE} | 
|  | FTP_PATH="${FTP_PATH}/snapshots/${RELEASE}" | 
|  |  | 
|  | # If diffs are requested when building locally on gcc.gnu.org, we (usually) | 
|  | # know what the last snapshot date was and take the corresponding tarballs, | 
|  | # unless the user specified tarballs explictly. | 
|  | if [ $MODE_DIFFS -ne 0 ] && [ $LOCAL -ne 0 ] && [ -z "${OLD_TARS}" ]; then | 
|  | LAST_DATE=`cat ~/.snapshot_date-${BRANCH}` | 
|  | OLD_TARS=${SNAPSHOTS_DIR}/${BRANCH}-${LAST_DATE}/gcc-${BRANCH}-${LAST_DATE}.tar.bz2 | 
|  | fi | 
|  | fi | 
|  |  | 
|  | # Compute the name of the WORKING_DIRECTORY and the SOURCE_DIRECTORY. | 
|  | WORKING_DIRECTORY="${DESTINATION}/gcc-${RELEASE}" | 
|  | SOURCE_DIRECTORY="${WORKING_DIRECTORY}/gcc-${RELEASE}" | 
|  |  | 
|  | # Recompute the names of all the language-specific directories, | 
|  | # relative to the WORKING_DIRECTORY. | 
|  | ADA_DIRS=`adjust_dirs ${ADA_DIRS}` | 
|  | CPLUSPLUS_DIRS=`adjust_dirs ${CPLUSPLUS_DIRS}` | 
|  | FORTRAN_DIRS=`adjust_dirs ${FORTRAN_DIRS}` | 
|  | FORTRAN95_DIRS=`adjust_dirs ${FORTRAN95_DIRS}` | 
|  | JAVA_DIRS=`adjust_dirs ${JAVA_DIRS}` | 
|  | OBJECTIVEC_DIRS=`adjust_dirs ${OBJECTIVEC_DIRS}` | 
|  | TESTSUITE_DIRS=`adjust_dirs ${TESTSUITE_DIRS}` | 
|  |  | 
|  | # Set up SVNROOT. | 
|  | if [ $LOCAL -eq 0 ]; then | 
|  | SVNROOT="svn+ssh://${SVN_USERNAME}@${SVN_SERVER}${SVN_REPOSITORY}" | 
|  | CVSROOT=":ext:${SVN_USERNAME}@gcc.gnu.org/cvs/gcc" | 
|  | else | 
|  | SVNROOT="file:///svn/gcc" | 
|  | CVSROOT="/cvs/gcc" | 
|  | fi | 
|  | export SVNROOT | 
|  | export CVSROOT | 
|  |  | 
|  | ######################################################################## | 
|  | # Main Program | 
|  | ######################################################################## | 
|  |  | 
|  | # Set the timezone to UTC | 
|  | TZ="UTC0" | 
|  | export TZ | 
|  |  | 
|  | # Build the source directory. | 
|  |  | 
|  | if [ $MODE_SOURCES -ne 0 ]; then | 
|  | build_sources | 
|  | fi | 
|  |  | 
|  | # Build the tar files. | 
|  |  | 
|  | if [ $MODE_TARFILES -ne 0 ]; then | 
|  | build_tarfiles | 
|  | fi | 
|  |  | 
|  | # Build diffs | 
|  |  | 
|  | if [ $MODE_DIFFS -ne 0 ]; then | 
|  | # Possibly build diffs. | 
|  | if [ -n "$OLD_TARS" ]; then | 
|  | for old_tar in $OLD_TARS; do | 
|  | build_diffs $old_tar | 
|  | done | 
|  | fi | 
|  | fi | 
|  |  | 
|  | # Build gzip files | 
|  | if [ $MODE_GZIP -ne 0 ]; then | 
|  | build_gzip | 
|  | fi | 
|  |  | 
|  | # Upload them to the FTP server. | 
|  | if [ $MODE_UPLOAD -ne 0 ]; then | 
|  | upload_files | 
|  |  | 
|  | # For snapshots, make some further updates. | 
|  | if [ $SNAPSHOT -ne 0 ] && [ $LOCAL -ne 0 ]; then | 
|  | announce_snapshot | 
|  |  | 
|  | # Update snapshot date file. | 
|  | changedir ~ | 
|  | echo $DATE > .snapshot_date-${BRANCH} | 
|  |  | 
|  | # Remove working directory | 
|  | rm -rf ${WORKING_DIRECTORY} | 
|  | fi | 
|  | fi |