--- bin/ebuild.sh.orig 2005-08-10 09:43:29.000000000 +0000 +++ bin/ebuild.sh 2005-08-10 09:47:08.000000000 +0000 @@ -65,6 +65,15 @@ export SANDBOX_ON="0" # sandbox support functions; defined prior to profile.bashrc srcing, since the profile might need to add a default exception (/usr/lib64/conftest fex, bug #60147) +addlogread() +{ + if [ "$1" = "1" ]; then + export SANDBOX_LOGREAD="1" + else + unset SANDBOX_LOGREAD + fi +} + addread() { export SANDBOX_READ="$SANDBOX_READ:$1" @@ -399,7 +408,319 @@ fi } +CONFCACHE_DIR=/var/cache/confcache +if [ ! -d "$CONFCACHE_DIR" ]; then + echo ">>> Creating confcache dir $CONFCACHE_DIR" + addwrite ${CONFCACHE_DIR%/*} + mkdir $CONFCACHE_DIR +fi +CONFCACHE_MD5SUM="$CONFCACHE_DIR/configure-$CBUILD-$CHOST-$THOST.md5sums" +CONFCACHE_SETTINGS="$CONFCACHE_DIR/configure-$CBUILD-$CHOST-$THOST.cache" +CONFCACHE_ENV="$CONFCACHE_DIR/configure-$CBUILD-$CHOST-$THOST.env" + +# $1 - name, $2 - value +confcache_set_env () { + temp="`tempfile`" + touch $CONFCACHE_ENV + /bin/grep -v $1 $CONFCACHE_ENV > $temp + echo "$1=$2" >> $temp + mv $temp $CONFCACHE_ENV +} + +# returns 2 if no cache, 1 if changed, 0 if not changed +confcache_checkenv () { + if [ ! -f "$CONFCACHE_ENV" ]; then + return 2 + fi + + while read line; do + var=${line%%=*} + val=${line#*=} + if [ "`eval \"echo $\"$var`" != "$val" ]; then + return 1 + fi + done < $CONFCACHE_ENV + + return 0 +} + +# $1 - file to write the configure cache out to + +confcache_prepare () { + + echo ">>> Preparing configure cache" + +# step 1 - make sure that none of the files in our list of deps +# have changed since we last built something + + addwrite "$CONFCACHE_MD5SUM" + addwrite "$CONFCACHE_ENV" + + confcache_checksums + case "$?" in + 2) + rm -f "$CONFCACHE_ENV" + return + ;; + 1) + echo ">>> Configure deps have changed; using an empty cache" + rm -f "$CONFCACHE_MD5SUM" "$CONFCACHE_ENV" + return + ;; + esac + + confcache_checkenv + case "$?" in + 2) + rm -f "$CONFCACHE_MD5SUM" + return + ;; + 1) + echo ">>> Environment settings have changed; using an empty cache" + rm -f "$CONFCACHE_MD5SUM" "$CONFCACHE_ENV" + return + ;; + esac + +# step 2 - now we copy the existing cache into the temporary file + + cat $CONFCACHE_SETTINGS > $1 +} + +confcache_checksums () { + +# if any of them have changed, we throw the whole cache away +# a future version, written in python, will be able to do +# per config-line deps + + if [ ! -f "$CONFCACHE_MD5SUM" ]; then + echo ">>> You have no md5sum cache file; assuming this is your first time" + return 2 + fi + + while read x ; do + sum="`echo $x | cut -d ' ' -f 1`" + file="`echo $x | cut -d ' ' -f 2-`" + + new_sum="`md5sum $file | awk '{ print $1 }'`" + if [ "$new_sum" != "$sum" ]; then + return 1 + fi + done < $CONFCACHE_MD5SUM + + return 0 +} + +# $1 - file containing the updated configure cache +# $SANDBOX_LOG - file containing the sandbox log + +confcache_update () { + +# special cases + + if [ ! -f "$1" ]; then + echo "confcache_update(): unable to find temporary cache $1" + return + fi + + echo ">>> Updating global configure cache from $1" + + addwrite "$CONFCACHE_SETTINGS" + addwrite "$CONFCACHE_MD5SUM" + +# step 1 - replace our global configure cache + + cp -f "$1" "$CONFCACHE_SETTINGS" + +# step 2 - make a list of files from the sandbox log + + if [ ! -f "$SANDBOX_LOG" ]; then +# nothing we can do - let's bail + echo "confcache_update: sandbox log not found" + return + fi + + echo ">>> Reading list of files used by configure" + if [ -n "$CCACHE_DIR" ]; then + local REMOVE_CCACHE_DIR="$CCACHE_DIR" + else + local REMOVE_CCACHE_DIR="/root/.ccache" + fi + files="`grep open_rd $SANDBOX_LOG | sed -e 's/^open_rd: \+//' | grep -v /tmp | grep -v /var/tmp | grep -v $REMOVE_CCACHE_DIR | grep -v /dev | sort | uniq`" + +# step 3 - add each file to the global md5 cache +# +# yes, this is a bit slow, but relying on egrep to search the file +# is risky. Sooner or later, some spanner package will rely on +# a file that contains spaces. + +# special case - do we *have* a CONFCACHE_MD5SUM file atm? + + if [ ! -f "$CONFCACHE_MD5SUM" ]; then + + echo ">>> No md5sum cache found; populating for first time" + +# create the file + touch $CONFCACHE_MD5SUM + +# populate it + + OLD_IFS="$IFS" + NEW_IFS="^M" +# IFS="$NEW_IFS" + + for x in $files ; do + IFS="$OLD_IFS" + + if [ ! -f "$x" ] ; then + continue + fi + + newsum="`md5sum \"$x\" | awk '{ print $1 }'`" + echo "$newsum $x" >> $CONFCACHE_MD5SUM + +# IFS="$NEW_IFS" + done + IFS="$OLD_IFS" + fi + +# if we don't + + OLD_IFS="$IFS" + NEW_IFS=" +" + + IFS="$NEW_IFS" + + echo ">>> Updating md5sum cache" + + for x in $files ; do + if [ ! -f "$x" ]; then + continue + fi + + infile=0 + while read y < $CONFCACHE_MD5SUM ; do + IFS="$OLD_IFS" + + sum="`echo $x | cut -d ' ' -f 1`" + file="`echo $x | cut -d ' ' -f 2-`" + + if [ "$file" = "$x" ]; then + infile=1 + break + fi + IFS="$NEW_IFS" + done + + IFS="$OLD_IFS" + + if [ "$infile" = "0" ]; then + newsum="`md5sum \"$x\" | awk '{ print $1 }'`" + echo "$newsum $x" >> $CONFCACHE_MD5SUM + fi + + IFS="$NEW_IFS" + done + + IFS="$OLD_IFS" + +# Store env settings which can affect configure + confcache_set_env CFLAGS "$CFLAGS" + confcache_set_env CXXFLAGS "$CXXFLAGS" + confcache_set_env CC "$CC" + confcache_set_env CPPFLAGS "$CPPFLAGS" + confcache_set_env CPP "$CPP" + confcache_set_env F77 "$F77" + confcache_set_env FFLAGS "$FFLAGS" + confcache_set_env LDFLAGS "$LDFLAGS" + confcache_set_env CXX "$CXX" +} + +confcache_start() { +# global configure cache - stuart@gentoo.org +# +# if FEATURES="sandbox confcache" are set, we maintain a global +# cache of results from previous configure statements +# +# this global cache should benefit all machines, but especially +# multi-processor boxes + + if [ "${FEATURES//*confcache*/true}" = "true" -a "${FEATURES//*sandbox*/true}" = "true" -a "${RESTRICT//*noconfcache*/true}" != "true" ]; then + CONF_CACHE="`/bin/tempfile`" + echo ">>> Temporary configure cache file is $CONF_CACHE" + addwrite "$CONF_CACHE" + confcache_prepare "$CONF_CACHE" + EXTRA_ECONF="--cache-file=$CONF_CACHE $EXTRA_ECONF" + addlogread 1 + +# mark these variables read-only, so that they can't be +# changed to, say, /etc/passwd + +# typeset -r CONF_CACHE +# typeset -r READLOG + else + echo "!!! Not using global configure cache" + fi +} + +confcache_stop() { + if [ "${FEATURES//*confcache*/true}" = "true" -a "${FEATURES//*sandbox*/true}" = "true" -a "${RESTRICT//*noconfcache*/true}" != "true" ]; then + addlogread 0 + confcache_update "$CONF_CACHE" + [ -f "$CONF_CACHE" ] && rm -f "$CONF_CACHE" + +# now we need to clean up the log file, otherwise portage +# will have a fit ;-) +# +# here, we remove all the entries that the SANDBOX_LOGREAD +# feature will have added +# +# any entries that we don't remove are sandbox violations +# by definitions + echo ">>> Fixing sandbox log" + if [ -f "$SANDBOX_LOG" ]; then + SANDBOX_DIRS="`echo $SANDBOX_WRITE | tr ':' ' '`" + + sed -i -e "s/^open_rd:.*//" \ + -e "s/^execve:.*//" \ + -e "s/^opendir:.*//" $SANDBOX_LOG + for x in $SANDBOX_DIRS ; do + sed -i \ + -e "s/^open_wr: ${x//\//\\/}.*//" \ + -e "s/^unlink: ${x//\//\\/}.*//" \ + -e "s/^rename: ${x//\//\\/}.*//" \ + -e "s/^chmod: ${x//\//\\/}.*//" \ + -e "s/^chown: ${x//\//\\/}.*//" \ + -e "s/^symlink: ${x//\//\\/}.*//" \ + -e "s/^link: ${x//\//\\/}.*//" \ + -e "s/^creat: ${x//\//\\/}.*//" \ + -e "s/^creat64: ${x//\//\\/}.*//" \ + -e "s/^rmdir: ${x//\//\\/}.*//" \ + -e "s/^mkdir: ${x//\//\\/}.*//" $SANDBOX_LOG + done + +# now we remove the empty lines + + TMPFILE="`tempfile`" + egrep -v '^$' $SANDBOX_LOG > $TMPFILE + cat $TMPFILE > $SANDBOX_LOG + rm $TMPFILE + +# if the file is empty, we can now remove the file +# +# this test may break on arches that do not use GNU ls + + if [ "`ls -l $SANDBOX_LOG | awk '{ print $5 }'`" = "0" ]; then + rm -f $SANDBOX_LOG + fi + fi + fi +} + econf() { + confcache_start + local LOCAL_EXTRA_ECONF="${EXTRA_ECONF}" if [ -z "${ECONF_SOURCE}" ]; then @@ -487,6 +808,8 @@ else die "no configure script found" fi + + confcache_stop } einstall() {