Search:  
Gentoo Wiki

HOWTO_Update_a_huge_system_-_hints_and_pitfalls


Please improve it in any way that you see fit, and remove this notice {{Cleanup}} from the article. For tips on cleaning and formatting see Cleanup process


Contents

Update

Someone in discussion gave the following hint, that might solve the problem easily:

Maybe add prominently a pointer to "eselect binutils"? This solved my problem with "C compiler cannot create executables" with minimal hassle; I had gotten into that while attempting something like "emerge -av glibc binutils gcc" during transition to gcc-4.1.1 from gcc-3.4.6 - WK, 2006-09-06

Comment

Script seems to be o.k. --Apos 08:23, 20 September 2006 (UTC)

Comment

Please be aware that I think using this thread without any problems will last until March/April 2006! The most important script part is this script:

The rest is rather confusing in the moment - please be patient with me ;)

1. Prerequisites

In any case, I recommend reading the following HOWTOs first

1. This HOWTO assumes, that you know the meaning of and how to handle

2. This HOWTO assumes we are aware that we are going to do a huge recompile the safe way. This means, we will copy the system - and this requires that we do not to copy the home directories ... and no reboot is required - to a separate harddrive / external drive / partition or pc. We will use the chroot environment for this.

3. Don't Panic ;) - such a task will - if you like this or not - take many days, weekends or even weeks, depending on your system. If you keep this in mind you won't stress yourself or your family ;)

2. Introduction

Over the years, linux systems grow and grow, then the day comes, you want to update your whole system. This HowTo describes, how to handle a huge recompile of the whole GENTOO system, which is necessary e.g.

Depending on your system (mine has over 1200 packages) and your machine, this could be a huge task, lasting days or even weeks.

When I last updated from gentoo profile 2005.0 to 2005.1 I only did one major recompile of my system before. That was when I wanted to put my laptop GENTOO to another computer. I remember, how problematic and time consuming this was. So I decided to write some handy scripts to make life easier.

To have the full control, the following bases on some main aspects, from which the most important is: Don't Panic ;) - A world emerge is and will ever be a very time consuming task. So be aware, that this could last a few days or even weeks.

First we will need mainly two scripts

  1. fix_gcc_comiler_issues.sh
  2. create_emerge_system_and_world_scripts.sh
    1. emerge.mySystem
    2. emerge.myWorld

The first is just for gcc problems after update. It gives us informations about our GENTOO system concerning gcc, binutils , the c++ libraries and the used include paths of your system. It sums up users experiences and solutions I found in forums.

The second provides us with two executable scripts, each contains the emerge commands that represent your actual installed packages.

GENTOO gives you a lot of possibilities to have a real unique linux system. Portage provides you with everything you need to really fix a problem or to avoid it. That also could mean, that a package is not installable by you.

So let's start.

3. GCC Compiler Issues

If you are not updating to a new compiler or you know how to fix it and you know why an emerge failed, a package would not compile or how to handle per package cflags, use and features you can skip this section.

The reason for an ebuild to fail could lead into a lot of questions:

The next section assumes, that you have a working compiler. If not, run fix_gcc_comiler_issues.sh (you'll find it at the end of this HowTo) in your bash shell, read Gentoo documentation - Upgrade-3.3-to-3.4 and other related stuff and then come back here.

3.1 Google for the right error message

It is sometimes difficult to sort out the important part of an error message. In addition, many programmers don't write informative error messages. That makes it often difficult to watch out for the real problem behind it.

The reason I am writing this was the wonderful gcc error:

"C compiler cannot create executables"

You'll find a lot of INFORMATION out there if you google around for that errror. But does this really fit to your particular problem? You are on your own and have to figure that out by yourself. Don't hesitate, there always will be a solution. It took me a few hour to really find out the reason and how to solve it. It was a CFLAGS problem with that package, that didn't want to compile with moderate option "-O2". I also had this message in competely different context: something was missing in the toolchain after a compiler upgrade and I had to fix some directories in the deep of /etc/ by myself.

Always remember: You are using a highly configurable system mostly for people who know or want to use packages right from the plain source, they mostly are developers and need a bleeding edge system, a very special or an experimental environment.

How to find a solution in the web (specially gcc errors)?

Then google arround for your exact compile error - locking for the topmost error, not the last message:

snip

##This is the topmost error in an english ...
ffh263codec.cxx:629: error: »struct AVCodecContext« has no memnber named »frame_rate«

## and in a german shell environment
ffh263codec.cxx:629: Fehler: »struct AVCodecContext« hat kein Element namens »frame_rate«

[...] 

## This is not the compile error, but of emerge.
!!! ERROR: net-libs/openh323-1.13.2-r2 failed.

snip

And since emerge is just a compiler wrapper, it is not primarily responsible for the compile failure (here a c compiler and the utility make). So the emerge error comes AFTER the make error.

Check the comments, emerge tells you before and after the emerge process. Yellow stars tell you, what the maintainer of the ebuild wanted to inform you about:

snip
>>> md5 src_uri ;-) yourPackage.tar.gz
   * This is our apologies you should read ....
>>>Unpacking source ...
snip

With time you probably won't need the help of an editor, but its always wise to use one.

3.2. Check you compiler settings

In GENTOO you can set your cflags globally in make.conf. Some packages are known to compile with


BE AWARE - most of the problems are CFLAG-probs. Please, please, please go away for a walk, relax, come back again, drink a cup of tea and prove twice each(!) single(!) of your CFLAGS if it is according to

STOP - did you really REALIZE the last points? If not go away, take a walk ... drink a tea/coffee ... come back think again about the problem.


3.3 Avoid that glibc gcc and gcc-config are emerged again

When you upgraded your compiler, you should remerge your toolchain. The easiest way to do this is to emerge glibc, gcc and in some cases, libstd-c++ again. After that, some problems you may encounter with `emerge system' may be gone.

If gcc and g++ are working, do something like

# This is part of the fix_gcc_comiler_issues.sh script
# provided at the end of this howto 
for prog in ${myGLIBC} ${myGCC} ${myGCC_CONFIG} ${myLIBSTDCPP};do echo \${prog} >> /etc/portage/profile/package.provided;done; ${myEDITOR} /etc/portage/profile/package.provided

This prevents emerging it again. Check this with

# This is part of the fix_gcc_comiler_issues.sh script
# provided at the end of this howto 
if (for prog in ${myPROVIDED_FILES}; do emerge -e -p system | grep \${prog}; done); then echo NOT OK; else echo OK; fi
      

This should give the result OK. If NOT OK, check ${myEDITOR} /etc/portage/profile/package.provided if you really avoided to emerge these program versions!

Now you can savely emerge -e system.

The fix_gcc_comiler_issues.sh-script gives you some more hints... just run it in a shell and read the whole output.

4. Don't fear emerge system/world

To shorten the update I wrote another script: First it creates two files with an emerge system and emerge world commandline by package(!).

Second it filters all duplicate emerges out of the world-emerge that had been already emerged by emerge system.

The problem with such huge updates always is, that your daily work is going on and it is most likely, that you won't recognize, when the emerge failed. The update of a real big system could last from days to week(s). That's the reason you need a structured approach. I am doing my updates with a simple shell script. Emerge provides me to everything I need. The script also gives me the possibility to add extra emerges, delete already emerged packages, test something and write down everything that happened during the update, including bookmarks from solving a problem.

It is also wise to backup you system to an external disk and doing the update in a chroot environment, probably on another computer.

It is really worth the $70-$100 for an external drive. Consider it will take a long time and your system is not really avaiable for that time.

If you use a script, you can lean back and watch the update go. If everything is done you can alter your /etc/fstab and make your extra drive bootable and check, if everything went ok. Then, and only then play back your new system - i don't have to tell you, that keeping a backup copy of your already running system is also mandatory!

Just go and get yourself a backup drive, don't bother around with one day or two more or less - it definitly will take a long time!

4.1 Doing some preparation

It is wise do download all distfiles in advance:

emerge --sync
emerge --deep --fetchonly system
emerge --deep --fetchonly world

Because it could take a few days of work to do the system upgrade, this will give you a stable base. Updating one package or another is always possible.

With

emerge -p [ -u | -e ] --verbose --deep system
emerge -p [ -u | -e ] --verbose --deep world

look for packages, that need extra binary downloads, like java and open openoffice. They show a red F.

Check, if you don't want, that some files should be updated, put these packages and their version in /etc/portage/package.mask.

Then test again with emerge -p --deep system/world if you package keeps staying.

It is also wise to recompile your kernel first with the new compiler, because it is most likely that some kernel modules will fail. After you did this put

>sys-kernel/gentoo-sources-yourKernelVersion

in package.mask ( and eventually package.provided) to avoid a recompiling of your kernel.

And please don't reemerge gcc,binutils, glibc or libstdc++ again. this could and could not produce unpredicable issues. Also put them in /etc/portage/profiles/package.provided and /etc/portage/package.mask.

4.2 Create our emerge scripts

Everything what you have to do is edit the first lines to fit everything to your system an run it in a directory. One thing is important: The script opens two files with your favorite editor. These contain the output of the packages, that should be emerged. As it is not possible to do a forecast what emerge's output exactly is, please remove any empty lines or messages that don't match the pattern category/package. I know that there is the emerge --resume command, but my experience is, that the resume information is vanished, when I had to emerge another package and then wanted to start over again. It also gives me not really a control, what I really did.

But lets have a look in detail (please note that I removed everything from the script that does not matter in this context - you'll find the complete version at the end of this HowTo)?

First it puts the output of

emerge -p -u --deep --columns system > aFile

in a file. Emerge -u is the default, but you can change it inside of the script to fit you upgrade needs.

Then it does a little shell acrobatic removing things, I don't want and separating the package names to be emerged. This is put into another file. It contains a list of category/package in each line.

cut -f2 --delimiter=']' anotherFile | cut -f1 --delimiter='[' | cut -f2 --delimiter=' ' >> mySystem


Now it prepares a file called emerge.mySystem for the real emerge commandline and adding some stuff. That's the base for mawk to come to work - a great little shell helper - to process each line and put everything in this file called emerge.mySystem.

mawk '{comd = "echo -n \"+\";echo -n \" \" "$0" >> emerge.mySystem; "; system(comd); }' mySystem

In general, this is what we want. A script with one commandline of our system emerge.

For the world emerge it does a little more. It cut's out any packages, that had been already emerged by emerge.mySystem.

4.3 Run the emerge

Now you can run ./emerge.mySystem and after restarting your PC ./emerge.myWorld. You can open an editor and control the emerge, add packages or remove them. If emerge failes, cut out the already emerged packages**, search for the error, correct your settings in /etc/make.conf, /etc/portage/package.use, /etc/portage/package.cflags or whatever you like. Use the script to unmerge and reemerge things, do notes on your progress, so if you fail again the next time, you know why.

**I didn't like to automate this, because it is always better to have the full control

5. The scripts

All scripts were "wikified" with this little script that adds a space in front of each line ;)

#!/bin/bash
# txtcode2wikicode.sh
#
# Add a single space before each line
#
# USE: txtcode2wikicode.sh file_to_convert file_with_on_space_in_front_of_each_line
echo File with wiki syntax: $2
echo File to convert:       $1
echo "" > $2;
sed s/^/" "/ ${1} >> ${2}

The first is just for troubleshooting gcc problems:

The second is for creating the emerge.mySystem and emerge.myWorld bash script that include everything to control the backup process:

The third is a script to portage, adding "per package cflags and features". It has to be named "bashrc", be put into the directory /etc/portage/inHere and made executable (chmod 755 /etc/portage/bashrc).

5.1 fix_gcc_compiler_issues.sh

This script does not change anything on your system. Please edit the script at the beginning to fit your needs.

#!/bin/sh
#
# fix_gcc_compiler_issues.sh
# www.apos.de - 1/2006
#
# 0.6 - added some stuff
# 0.5 - added recommondation to 5a how to emerge toolchain
#       (gcc, glibc, libstc++) again
# 0.4 - a lot of little fixes
# 0.3 - fixed for in do loops
# 0.2 - fixed adding gcc, glibc and gcc-config to package.provided just added
#       empty lines
#
# Fix compiler issues after emerge gcc, emerge system, emerge world ...
# in GENTOO 2005.1
#
# READ FIRST:
#   http://forums.gentoo.org/viewtopic-t-27486-postdays-0-postorder-asc-start-75.html
#
##################################################
## Change the following according to your settings
##################################################
myEDITOR="vi"
myGCC='sys-devel/gcc-3.4.4-r1'                  # according to emerge -p gcc
myGCC_CONFIG="sys-devel/gcc-config-1.3.12-r6"   # according to emerge -p gcc-config
myGLIBC="sys-libs/glibc-2.3.5-r2"               # according to emerge -p glibc
myLIBSTDCPP="sys-libs/libstdc++-v3-3.3.4"       # according to emerge -p libstdc++-v3
myGCC_CONFIG_L="i686-pc-linux-gnu-3.4.4"        # according to gcc-config  --get-current-profile
myBINUTILS_CONFIG_L="i686-pc-linux-gnu-2.16.1"  # according to binutils-config -l
myPROVIDED_FILES="gcc gcc-config glibc libstdc++-v3" # files that should not be recompiled again
# the last does not show the versions, that is for portage to avoid
# emerging of other versions
##################################################

## Lets GO...
echo GENTOO GCC QUICK update-fix
echo ...no garantee - Licence GPL.
echo lets go

echo --------------------------------------;
echo My current gcc profile
echo gcc-config --get-current-profile
gcc-config --get-current-profile

for file in gcc-config binutils-config;
do echo --------------------------------------;
   echo This is output of: ${file} -l;
   ${file} -l;
   emerge -pv ${file};
   echo Does these two match;
   echo Does the installed version match;
   echo the entries in the next;
   echo /etc/ld.so.conf;
   echo /etc/profile.env;
   echo /etc/env.d/05gcc;
   echo /etc/env.d/05binutils;
done;


for conf in /etc/ld.so.conf /etc/profile.env;
do echo --------------------------------------;
   echo This is part of ${conf} with gcc concern:;
   grep gcc ${conf};
done;

for conf in /etc/env.d/05gcc /etc/env.d/05binutils;
do echo --------------------------------------;
   echo This is whole ${conf}:;
   cat ${conf};
done;

## The following does binutils-config for us
#rm -rf /usr/i686-pc-linux-gnu/bin/*
#for file in /usr/i686-pc-linux-gnu/binutils-bin/2.16.1/*; do ln -s $file /usr/i686-pc-linux-gnu/bin/; done
##

echo --------------------------------------
echo ls /usr/lib/gcc/i686-pc-linux-gnu/
echo "This should show your installed gcc versions..."
ls /usr/lib/gcc/i686-pc-linux-gnu/
echo ...something...the right

echo --------------------------------------
echo ls /usr/lib/gcc-lib/i686-pc-linux-gnu/
echo "This should show your installed gcc versions..."
ls /usr/lib/gcc-lib/i686-pc-linux-gnu/
echo ...something...the right

echo --------------------------------------
cat<<EOF
=============================================================
Things you might do, if 1.-4. did not work for you.
=============================================================

A. Check these files by running this script again or by

       ${myEDITOR} /etc/ld.so.conf
       ${myEDITOR} /etc/profile.env
       ${myEDITOR} /etc/env.d/05gcc
       ${myEDITOR} /etc/env.d/05binutils

B. Just try

       export CFLAGS=""

   Try then to emerge e.g. patch for testing purpose

       emerge patch

   Try again with B. and a new shell...

C. Some files are not there - TIME CONSUMING

       FEATURES="-distcc -ccache -sandbox" USE="bootstrap" emerge -av system

D. System is totally broken, programs won't run any more. And look at D.

       fix_libtool_files.sh ${myGCC_CONFIG_L}

   Eplanation:
   How do i get ${myGCC_CONFIG_L}?

       gcc-config --get-current-profile

   or add the output of

       ls /usr/lib/gcc/i686-pc-linux-gnu/  ENTER
       3.4.4                               THIS IS-ARE YOUR VERSION-S

   after "i686-pc-linux-gnu-" and you get your gcc libtool files
   for fix_libtool_files.sh.


E. ...switched to new compiler

FIRST READ "3. Upgrading from GCC-3.3 to 3.4" IN

      http://www.gentoo.org/doc/en/gcc-upgrading.xml#upgrade-3.3-to-3.4

      This tolds you to do

      1. Secure way:
         BE AWARE this STOPS after certain steps (remove -av to let it run through)
         and TAKES a VERY VERY VERY LONG time:

        emerge -uav gcc && gcc-config i686-pc-linux-gnu-3.4.4 && source /etc/profile && emerge --oneshot -av libtool
&& emerge --oneshot sys-libs/libstdc++-v3 && FEATURES="-distcc -ccache -sandbox" USE="bootstrap" emerge -e system &&
emerge -e world && emerge -aC =sys-devel/gcc-3.3*

        This is in any case the secure way have everything
        compiled with new compiler and settings, because it first
        compiles the whole toolchain again and then the world dependencies.

      2. Not secure but "faster way" - also takes a VERY long time.
         BE AWARE this STOPS after certain steps (remove -av to let it run through)
         and takes a VERY LONG time:

        emerge -an gentoolkit && emerge -uav gcc && gcc-config i686-pc-linux-gnu-3.4.4 && emerge -an gentoolkit &&
emerge --oneshot -av libtool && revdep-rebuild --library libstdc++.so.5 -- -p -v && revdep-rebuild --library
libstdc++.so.5 && emerge --oneshot sys-libs/libstdc++-v3 && emerge -aC =sys-devel/gcc-3.3*

E. Compile your KERNEL again with new compiler.
   Helps, wenn modules won't start, Xorg, sound, net ...


=============================================================
NOW ITS YOUR TURN: 4 Steps could save you a lot of time...
=============================================================


4. Test with an emerge e.g.

       emerge patch

3. Change compiler, binutils and reset CFLAGS to "" - the last is important.
   See also http://bugs.gentoo.org/show_bug.cgi?id=68395.

       gcc-config ${myGCC_CONFIG_L} && binutils-config ${myBINUTILS_CONFIG_L} && export CFLAGS=""

   The bug advises to do furthermore:

       unset GCC_SPECS

2. a. This is just, if everything works. To prevent that glibc gcc gcc-config and other (binutils, libstdc++-v3 ...)
are emerged again do:

       for prog in ${myGLIBC} ${myGCC} ${myGCC_CONFIG} ${myLIBSTDCPP});do echo \${prog} >>
/etc/portage/profile/package.provided;done; ${myEDITOR} /etc/portage/profile/package.provided

   b. Check furthermore with

       if (for prog in ${myPROVIDED_FILES}; do emerge -e -p system | grep \${prog}; done); then echo NOT OK; else
echo OK; fi

      This should give the result OK, if not it means, that these packages
      will be emerged again.
      If NOT OK, check with
        ${myEDITOR} /etc/portage/profile/package.provided
      if you did really prevent tht emerge of these program versions!

      Probably it might me necessary to check with
         emerge -pv  gcc gcc-config glibc libstdc++-v3 binutils
      if something is missing and emerge it again.

      If everything is o.k., you can savely emerge -e system
      without recompiling these packages again (always check twice).

1.B. Check your cflags options for your compiler. Specially for typos.
   Some options changed their names in gcc-3.4.4 an above
   - e.g. march=athlon-xp is now march=athlon.
   Be careful and look at the source, depending to your compilerversion:

   http://gcc.gnu.org/onlinedocs/

   for gcc-3.4.5
          http://gcc.gnu.org/onlinedocs/gcc-3.4.5/gcc/Option-Summary.html#Option-Summary

   for gcc-3.4.5 Harware Models:
          http://gcc.gnu.org/onlinedocs/gcc-3.4.5/gcc/Submodel-Options.html#Submodel-Options


1.A. Check the output of this file at the beginning.

EOF

5.2 create_emerge_system_and_world_scripts.sh

Sorry for a really bas error in the create script. Fixed in 0.6.

#!/bin/sh
#
# create_emerge_system_and_world_scripts.sh
# www.apos.de 2006/1
#
# GENTOO profile update from 2005.0 to 2005.1
# Helperscript
#
# This script produces two files, that contain the huge "emerge world"
# and the "emerge system" commandline for better maintaining.
# The emerge world is thereby shortened by already done system emerges!
#
# v0.8 - first do emerge --fetchonly, before writing to files
# v0.7 - fixed emerge_ok and emerge_failed in emerge.myXXX
# v0.6 - fixing some really ugly fault in getting emerge.myXXXX
# v0.5 - stable, getting rid of empty lines
# v0.5beta - changed a lot, but just for the eye and comfort
# v0.4 - STABLE
# v0.3 - mawk line fixed,
#        emerge sync and --fetchonly commented out by default
# v0.2 - Changed the naming of the files - minor fixes
#
# 
##############################################################
# Your editor
myEDITOR="vi +1 " ## startet vi immer in der ersten Zeile
myMULTIPAGE_EDITOR=gedit

# Emerge command.
# Here you can specify the emerge option, that should be
# used for your update.
# DEFAULT and always used: --deep
#
# E.g. you could specify:
#   -u        - for just updating your system
#   -e        - for recompiling the whole system
#   nothing   - for a normal emerge world/system
myEMERGE_OPTIONS="-u"

# Sound 
mySOUNDPLAYER=aplay
myFAV_SUCCESS_SOUND="/usr/share/sounds/k3b_success1.wav"
myFAV_ERROR_SOUND="/usr/share/sounds/k3b_error1.wav"

## Add an emerge lock to avoid running emerge --fetchonly twice
myEMERGE_LOCKFILE="/tmp/emerge.lock";
##############################################################


##############################################################
# DO NOT ALTER ANYTHING BEOND THIS LINE IF YOU
# DO NOT EXACTLY KNOW WHAT YOU ARE DOING.


##############################################################
# only run as root
if [ $UID != 0 ] ; then
  echo only root my run this
  exit 0
fi

##############################################################
## DONT change this line or put it elsewhere
mySYSTEM="mySystem"
myWORLD="myWorld"
myEMERGE_FILES="emerge.${mySYSTEM} emerge.${myWORLD}"

if test -e ${myEMERGE_LOCKFILE};
then
cat<<EOF
 You already ran this script before.
 Please be aware that 

   emerge sync
   emerge ${myEMERGE_OPTIONS} --deep --fetchonly system
   emerge ${myEMERGE_OPTIONS} --deep --fetchonly world

 will not be run again.
 You can run it manually, if you like or remove
 the lockfile ${myEMERGE_LOCKFILE}.
 
 Lockfiles content: 
EOF
   cat ${myEMERGE_LOCKFILE}
   echo; 
   echo -n "Continuing 10 seconds ... "
   mySleep="1 2 3 4 5 6 7 8 9 10"; 
   for slp in ${mySleep}; do echo -n "${slp} "; sleep 1; done; 
   echo;
else
   echo "Last sync run at `date`"  > ${myEMERGE_LOCKFILE}
   emerge sync
   emerge ${myEMERGE_OPTIONS} --deep --fetchonly system
   emerge ${myEMERGE_OPTIONS} --deep --fetchonly world
fi


##############################################################
# EMERGE IT ...
# get the system emerge tree and store it to a file
echo "Get the system portage tree..."
if emerge -p ${myEMERGE_OPTIONS} --deep --columns system > ${mySYSTEM}.space; 
then echo OK; 
else echo There was an error during emerge; 
     echo Please run manually 
     echo "    emerge -p ${myEMERGE_OPTIONS} --deep --columns system"
     echo and resolv conflicts.
     exit 1; 
fi;

echo "# Please check this file for errors, empty lines." > ${mySYSTEM};
cut -f2 --delimiter=']' ${mySYSTEM}.space | cut -f1 --delimiter='[' | grep -v "These are the packages" | grep -v "Calculating" | grep -v "Please update portage " | grep -v "Failure to do so "| grep -v "A simple " | cut -f2 --delimiter=' ' | sed '/^ *$/d' >> ${mySYSTEM};
${myEDITOR} ${mySYSTEM};

##############################################################
# get the world emerge tree for your system
echo "Get the world portage tree..."
echo "" > ${myWORLD}.space;
if emerge -p ${myEMERGE_OPTIONS} --deep --columns world > ${myWORLD}.space ; 
then echo OK; 
else echo There was an error during emerge; 
     echo Please run manually 
     echo "    emerge -p ${myEMERGE_OPTIONS} --deep --columns world"
     echo and resolv conflicts.
     exit 1; 
fi;
echo "# Please check this file for errors, empty lines." > ${myWORLD};
cut -f2 --delimiter=']' ${myWORLD}.space | cut -f1 --delimiter='[' | grep -v "These are the packages" | grep -v "Calculating" | grep -v "Please update portage " | grep -v "Failure to do so "| grep -v "A simple " | cut -f2 --delimiter=' ' | sed '/^ *$/d' >> ${myWORLD};
${myEDITOR} ${myWORLD};


##############################################################
# lets add everything to the emerge.mySYSTEM file


####### for loop
for emergefile in ${myEMERGE_FILES}; do
##############################################################
echo '#!/bin/sh' > ${emergefile}
echo "#" > ${emergefile}
echo "# This is ${emergefile}" >> ${emergefile}
echo "myEMERGE_OPTIONS=${myEMERGE_OPTIONS}" >> ${emergefile}

cat>>${emergefile}<<END

# Sound 
mySOUNDPLAYER=aplay
myFAV_SUCCESS_SOUND="/usr/share/sounds/k3b_success1.wav"
myFAV_ERROR_SOUND="/usr/share/sounds/k3b_error1.wav"

# First of all sync the portage tree and download everything necessary.
# DO THIS ONLY ONCE, and then not any more until
# your whole system has been compiled.

clean() {
  echo Removing temp files from ...
  DIR="/var/tmp/ccache /var/tmp/portage";
  for dir in \${DIR};
  do
  rm -rf \${dir}\/*
    echo " \${dir}/*... "
  done;
  echo -n done.
  echo;


  echo Removing all backupfiles in ...
  DIR="/etc /etc/portage /etc/portage/profiles";
  for dir in \${DIR};
  do
    rm -rf \${dir}/*~
    echo " \${dir}/*~... "
  done;
  echo -n done.
  echo;
}

##############################################################
# Write in here what should happen, wenn
# feel free to add some more stuff.
# E.g. you could send yourself an email.
emerge_ok() {
   # emerge was ok
   ${mySOUNDPLAYER} ${myFAV_SUCCESS_SOUND}
   echo '++++++++++++++++++++++++++++++++++++++++++++++++++'
   echo Everything compiled successfully
   clean
   exit 1;
}


emerge_failed() {
   # emerge failed
   ${mySOUNDPLAYER} ${myFAV_ERROR_SOUND}
   echo '--------------------------------------------------'
   echo There was en ERROR during emerge.
   clean
   exit 0;

}

clean;

END
##############################################################
done;
##### for loop end

echo create files ...

##############################################################
# Because awk does not like sh vars we have to add the emerge
# commandline for each emergefile 
#
# For emerge.system
echo;
echo Add packages to emerge.${mySYSTEM} ...
echo -n 'if  FEATURES="-distcc -ccache -sandbox" emerge ' >> emerge.${mySYSTEM}
grep -v "Please check this file " ${mySYSTEM} | mawk '{comd = "echo -n \"+\";echo -n \" \" "$0" >> emerge.mySystem; "; system(comd); }';
echo -n ";" >> emerge.${mySYSTEM};

# For emerge.world
echo;
echo Add packages to emerge.${myWORLD} and filter out already emerged progs...
echo -n "if emerge " >> emerge.${myWORLD};
grep -v "Please check this file " ${myWORLD} | mawk '{comd = "if grep "$0" mySystem >> /dev/null; then echo -n \"-\"; else echo -n \"+\"; echo -n \" \""$0" >> emerge.myWorld; fi; "; system(comd); }'
echo -n ";" >> emerge.${myWORLD};


##############################################################
# lets add some sound output for failure
for emergefile in ${myEMERGE_FILES}; do
cat>>${emergefile}<<EOF

then 
   emerge_ok;
else
   emerge_failed;
fi
EOF
done

echo;

##############################################################
# Make the skripts executable
for emergefile in ${myEMERGE_FILES}; do
   chmod 755  ${emergefile}
done

##############################################################
## Open a multipage editor to be able to control the emerge 
# and all related files, if it fails
#${myMULTIPAGE_EDITOR} emerge.${mySYSTEM} emerge.${myWORLD} /etc/portage/profile/package.provided /etc/portage/package.mask /etc/portage/package.unmask /etc/portage/package.keywords /etc/portage/package.use /etc/portage/package.cflags /etc/portage/package.features

## END

5.3 bashrc for portage

I saw this script first on Gentoo-Forum. I added some lines (see ########) to get it work with distcc. Please read the forum post so you can understand how this works.

This is my /etc/portage/package.cflags. I change mainly the -O (Optimize) and the -march (Architecture) CFLAGS:

dev-libs/libusb -O1 -march=i686 -pipe -fomit-frame-pointer -mno-tls-direct-seg-refs
sys-apps/groff -O1 -march=i686 -pipe -fomit-frame-pointer -mno-tls-direct-seg-refs
dev-lang/python -O2 -march=i686 -pipe -fomit-frame-pointer -mno-tls-direct-seg-refs
media-libs/libvisual -O2 -march=i686 -pipe -fomit-frame-pointer -mno-tls-direct-seg-refs

This is my /etc/portage/package.features. To disable a feature simply add a minus sign ("-") in front of the feature.

sys-libs/glibc ccache
app-admin/sudo ccache
sci-mathematics/mupad -confcache

And there comes the file. Save it as /etc/portage/bashrc and make it executable.

## Copyright 1999-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /etc/portage/bashrc$
# Originally written by Ned Ludd (solar_at_gentoo.org)
# modifications by Ryan McIntosh (thebigslide_at_gmail.com)
# See:http://forums.gentoo.org/viewtopic-t-280748-postdays-0-postorder-asc-start-0.html
# V1.0_rc1
# - /etc/portage/bashrc

if [ "$0" = "/usr/lib/portage/bin/ebuild.sh" -o "$0" = "/usr/lib/portage/bin/ebuild-daemon.sh" ]; then

   echo "Warning: file /etc/portage/bashrc is altering CFLAGS, CXXFLAGS, FEATURES.";

   append-cflags() {
        export CFLAGS="${CFLAGS} $*"
   return 0
   } 

   append-cxxflags() {
        export CXXFLAGS="${CXXFLAGS} $*"
   return 0
   }

   append-features() {
      export FEATURES="${FEATURES} $*"
   return 0
   }

   package-cflags() {
           # bail if file does not exist or is not readable.
           [ -r ${ROOT}/etc/portage/package.cflags ] || return 0 

           while read -a target; do
                   if [ "${target}" = "${CATEGORY}" ];   then
                      unset CFLAGS
                        for i in `/bin/seq 20`;    do #linelength
                           if [ "${target[$i]}" = "GLOBALCFLAGS" ]; then
                           append-cflags $GLOBALCFLAGS
                     else
                           if [ "${target[$i]}" = "GLOBALCXXFLAGS" ]; then
                       append-cflags $GLOBALCXXFLAGS
                      else
                              append-cflags ${target[$i]}
               fi
                     fi
                        done
                           export -n CFLAGS
                   else
                   if [ "${target}" = "${CATEGORY}/${PN}" ]; then
                   unset CFLAGS
                        for i in `/bin/seq 20`;    do #linelength
                           if [ "${target[$i]}" = "GLOBALCFLAGS" ]; then
                           append-cflags $GLOBALCFLAGS
                        else
                           if [ "${target[$i]}" = "GLOBALCXXFLAGS" ]; then
                       append-cflags $GLOBALCXXFLAGS
                      else
                              append-cflags ${target[$i]}
               fi
                        fi
                        done
                        export -n CFLAGS
                   fi
                   fi
           done <  ${ROOT}/etc/portage/package.cflags
   }

   package-cxxflags() {
        # bail if file does not exist or is not readable.
        [ -r ${ROOT}/etc/portage/package.cxxflags ] || return 0
           
   while read -a target; do
           if [ "${target}" = "${CATEGORY}" ];   then
                         unset CXXFLAGS
                          for i in `/bin/seq 20`;    do #linelength
                               
            if [ "${target[$i]}" = "GLOBALCXXFLAGS" ]; then
                           append-cxxflags $GLOBALCXXFLAGS
                 else
                           if [ "${target[$i]}" = "GLOBALCFLAGS" ]; then
                       append-cxxflags $GLOBALCFLAGS
                      else
                              append-cxxflags ${target[$i]}
               fi
                 fi
                    done
                     export -n CXXFLAGS
            else 

                 if [ "${target}" = "${CATEGORY}/${PN}" ]; then
                     unset CXXFLAGS
                          for i in `/bin/seq 20`;    do #linelength
                                if [ "${target[$i]}" = "GLOBALCXXFLAGS" ]; then
               append-cxxflags $GLOBALCXXFLAGS
                 else
                       if [ "${target[$i]}" = "GLOBALCFLAGS" ]; then
                         append-cxxflags $GLOBALCFLAGS
                      else
                       append-cxxflags ${target[$i]}
               fi
                 fi
                         done
                         export -n CXXFLAGS
                  fi
             fi
         done <  $ROOT/etc/portage/package.cxxflags
   }

   package-features() {
           # bail if file does not exist or is not readable.
           [ -r ${ROOT}/etc/portage/package.features ] || return 0
           
      while read -a target; do
         if [ "${target}" = "${CATEGORY}" ];   then
            unset FEATURES
            for i in `/bin/seq 20`;    do #linelength
               if [ "${target[$i]}" = "GLOBALFEATURES" ]; then
                  append-features $GLOBALFEATURES
               else
                  append-features ${target[$i]}
               fi
            done
###############################################################
    	  echo Checking features for disstcc ...
	  if echo ${FEATURES} | /bin/grep -v "distcc"; 
	  then	   
             echo Distcc is not used ...	   
             #export `/bin/grep MAKEOPTS /etc/make.conf` 
             export MAKEOPTS="-j2"
	     export OPTIONS="\-distcc"
	     unset DISTCC_HOSTS
	     export WANT_DISTCC="false"
	     export -n FEATURES;
	  else
	     export -n FEATURES;
	  fi;
###############################################################
            #export -n FEATURES ## ORIG
###############################################################
         else
            if [ "${target}" = "${CATEGORY}/${PN}" ]; then
               unset FEATURES
               for i in `/bin/seq 20`;    do #linelength
                  if [ "${target[$i]}" = "GLOBALFEATURES" ]; then
                     append-features $GLOBALFEATURES
                  else
                     append-features ${target[$i]}
                  fi
               done
###############################################################
    	  echo Checking features for disstcc ...
	  if echo ${FEATURES} | /bin/grep -v "distcc"; 
	  then
             echo Distcc is not used ...	   
             #export `/bin/grep MAKEOPTS /etc/make.conf` 
             export MAKEOPTS="-j2"
	     export OPTIONS="\-distcc"
	     unset DISTCC_HOSTS
	     export WANT_DISTCC="false"
	     export -n FEATURES;
	  else
	     export -n FEATURES;
	  fi;
###############################################################
            #export -n FEATURES ## ORIG
###############################################################
             fi
          fi
       done <  $ROOT/etc/portage/package.features
       
   } 

   export GLOBALCFLAGS=$CFLAGS
   export GLOBALCXXFLAGS=$CXXFLAGS
   export GLOBALFEATURES=$FEATURES 

   package-cflags
   package-cxxflags
   package-features
   
   unset GLOBALCFLAGS
   unset GLOBALCXXFLAG
   unset GLOBALFEATURES 

else
###############################################################
   echo "Warning: file /etc/portage/bashrc wanted to alter CFLAGS, CXXFLAGS, FEATURES."; 
   echo "         Nothing was altered. Possible reason:"
   echo "         This bashrc does not know anything about $0"
###############################################################
fi
Retrieved from "http://www.gentoo-wiki.info/HOWTO_Update_a_huge_system_-_hints_and_pitfalls"

Last modified: Sat, 13 Sep 2008 13:29:00 +0000 Hits: 33,882