Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Full system rebuild
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo
View previous topic :: View next topic  
Author Message
friesia
Apprentice
Apprentice


Joined: 23 Mar 2007
Posts: 202

PostPosted: Wed Jan 16, 2013 10:44 am    Post subject: Full system rebuild Reply with quote

Do you agree with this command sequence for rebuilding @world when toolchain packages are updated? Maybe something is redundant.
Or maybe there's a better way to avoid re-emerging previously built packages than making binary ones.
I've taken it from gentoo-wiki.com http://goo.gl/Wj08o and translated for you.

Code:

# for safe use of 'emerge -k' you need to clean the directory with
# binary packages (for example, place it inder /tmp/portage-packages)

pkgdir=$(portageq pkgdir)
mv $pkgdir /tmp/portage-packages1
install -d -o portage -g portage -m775 $pkgdir

# First build of toolchain. From here on you should use -1 (--oneshot) switch
# to avoid placing system packages into world file.
emerge -1 sys-kernel/linux-headers sys-libs/glibc sys-devel/binutils sys-devel/gcc-config sys-devel/gcc sys-devel/binutils-config sys-devel/libtool

# select new GCC and (or) binutils if it's placed into a new slot
gcc-config <new_name>
binutils-config <new_name>
source /etc/profile

# Compile toolchain and create binary packages
emerge -1b sys-libs/glibc sys-devel/binutils sys-devel/gcc sys-apps/portage

# Do not compile glibc, binutils и gcc
emerge -1bke system

# Do not compile all previously built packages (including system)
emerge -bke world
Back to top
View user's profile Send private message
Veldrin
Veteran
Veteran


Joined: 27 Jul 2004
Posts: 1945
Location: Zurich, Switzerland

PostPosted: Wed Jan 16, 2013 11:26 am    Post subject: Reply with quote

Quote:
Code:
# for safe use of 'emerge -k' you need to clean the directory with
# binary packages (for example, place it inder /tmp/portage-packages)

pkgdir=$(portageq pkgdir)
mv $pkgdir /tmp/portage-packages1
install -d -o portage -g portage -m775 $pkgdir

I am not exactly sure about that part (especially the install command). what does it try to achieve?
Quote:
Code:
# First build of toolchain. From here on you should use -1 (--oneshot) switch
# to avoid placing system packages into world file.
emerge -1 sys-kernel/linux-headers sys-libs/glibc sys-devel/binutils sys-devel/gcc-config sys-devel/gcc sys-devel/binutils-config sys-devel/libtool

Why not add -b (--buildpkg) to avoid rebuild later on.
Quote:
Code:
# select new GCC and (or) binutils if it's placed into a new slot
gcc-config <new_name>
binutils-config <new_name>
source /etc/profile


Quote:
Code:
# Compile toolchain and create binary packages
emerge -1b sys-libs/glibc sys-devel/binutils sys-devel/gcc sys-apps/portage 

why remerge them again?
just use quickpkg --include-config=y sys-libs/glibc sys-devel/binutils sys-devel/gcc sys-apps/portage to achieve the same in less time - if you use -b with the toolchain rebuild, the step may be omitted.
Quote:
Code:
# Do not compile glibc, binutils и gcc
emerge -1bke system

# Do not compile all previously built packages (including system)
emerge -bke world
There are 2 arguments here: does it help to build system and world one after another while the world set contains the system set. On the other hand, using the -k flag, already built packages are not built again.

Unless you are certain, that rebuilding system before rebuilding world helps, I suggest that you simply run emerge -bke world

just my .02$
V.
_________________
read the portage output!
If my answer is too concise, ask for an explanation.
Back to top
View user's profile Send private message
John R. Graham
Administrator
Administrator


Joined: 08 Mar 2005
Posts: 10587
Location: Somewhere over Atlanta, Georgia

PostPosted: Wed Jan 16, 2013 11:38 am    Post subject: Reply with quote

Veldrin wrote:
Quote:
Code:
# First build of toolchain. From here on you should use -1 (--oneshot) switch
# to avoid placing system packages into world file.
emerge -1 sys-kernel/linux-headers sys-libs/glibc sys-devel/binutils sys-devel/gcc-config sys-devel/gcc sys-devel/binutils-config sys-devel/libtool

Why not add -b (--buildpkg) to avoid rebuild later on.
The intent here is to force the toolchain to be rebuilt against the new gcc (to get whatever better code optimization the new gcc delivers) and --buildpkg / --usepkg prevents that. The first real redundancy I see here is rebuilding gcc: gcc already rebuilds itself with itself as part of the normal build process.

The second redundancy is that, although redundant system set compiling is avoided, redundant installing is not.

This is a somewhat esoteric topic, branded at least lightly with the Ricer stigmata, that has been heavily discussed in the past. See An emerge wrapper for breaking emerges into chunks, and Why multiple "emerge -e world" are actually useless, among many, many others.

- John
_________________
I can confirm that I have received between 0 and 499 National Security Letters.
Back to top
View user's profile Send private message
paulj
Guru
Guru


Joined: 30 Sep 2004
Posts: 507
Location: Wales, UK

PostPosted: Wed Jan 16, 2013 8:29 pm    Post subject: Reply with quote

I use a very nice script from Guenther Brunthaler. It is from 2006, but still works. It also allows you to stop and pick up again where you left off. Here it is:

Code:
#!/usr/bin/perl -w
#
# Generate a script which when run recompiles each and every package
# in the Gentoo system.
# This will typically be required on a major GCC upgrade.
#
# $HeadURL: /caches/xsvn/trunk/usr/local/sbin/recompile-entire-system $
# $Author: root $
# $Date: 2006-09-01T14:15:49.548823Z $
# $Revision: 334 $
#
# Written in 2006 by Guenther Brunthaler


use strict;
use File::Temp ':POSIX';


# Change this to any name you like.
my $script= "recompile-remaining-packages";


my $script_header= << '.';
#!/bin/sh
# Run this script repeatedly (if interrupted)
# until no more packages will be compiled.
#
# $Date: 2006-09-01T14:15:49.548823Z $
# $Revision: 334 $
# Written in 2006 by Guenther Brunthaler

STATE_FILE="$HOME/.recompile-entire-system.state"

die() {
   echo "ERROR: $*" >& 2; exit 1
}

save_progress() {
   { echo "$OURGCC"; echo $PROGRESS; } > "$STATE_FILE"
}

item() {
   test "$PROGRESS" -ge "$1" && return
   echo "Emerging package # $1 ('$2')..."
   emerge --oneshot --nodeps "$2" || {
      die "Emerge failed return code $?!"
   }
   echo "Package # $1 rebuild complete."; echo
   PROGRESS="$1"; save_progress
}

OURGCC="`gcc-config --get-current-profile`" || die "gcc-config failed!"
PROGRESS=; LASTGCC=
{ read LASTGCC; read PROGRESS; } < "$STATE_FILE" 2> /dev/null
if [ "$OURGCC" != "$LASTGCC" -o -z "$PROGRESS" ]; then
   PROGRESS=0; save_progress
fi

.

my $script_tail= << '.';

echo
echo "Success! All packages have been re-compiled."
echo "Your system is now up-to-date with respect to $OURGCC!"
echo
echo "If your want to recompile the whole system again"
echo "for the *same* GCC version, please"
echo "\$ rm \"$STATE_FILE\""
echo "in order to reset the sucessfully-recompiled-packages counter."
.


# Remove the largest common whitespace prefix from all lines
# of the first argument.
# (Empty lines or lines containing only whitespace are skipped
# by this operation and will be replaced by
# completely empty lines.)
# The first argument must either be a reference to a multiline
# string containing newline characters or a reference to an
# array of single line strings (without newline characters).
# Then optionally indent all resulting lines with the prefix
# specified as the argument to the -first option.
# For all indented lines do the same, but use the argument
# to option -indent as the value of the -first option then.
# If option -wrap <number> is specified, contiguous non-empty
# lines of the same indentation depth are considered paragraphs,
# and will be word-wrapped on output, resulting in a maximum
# total line length of <number> characters.
# The word-wrappin will occur on whitespaces, which can be
# protected by a backslash.
sub normalize_indentation {
   my($tref, %opt)= @_;
   my(@t, $t, $p, $pl);
   $opt{-first}||= '';
   $opt{-indent}||= ' ';
   $t= ref($tref) eq 'ARRAY' ? $tref : [split /\n/, $$tref];
   foreach (@$t) {
      s/^\s+$//;
      next if $_ eq '';
      if (defined $pl) {
         for (;;) {
            substr($p, $pl= length)= '' if length() < $pl;
            last if substr($_, 0, $pl) eq $p;
            substr($p, --$pl)= '';
         }
      } else {
         ($p)= /^(\s*)/;
         $pl= length $p;
      }
   }
   substr($_, 0, $pl)= '' foreach grep $_ ne '', @$t;
   if (exists $opt{-wrap}) {
      my $width= $opt{-wrap} - length $opt{-first};
      my $i;
      my $wrap= sub {
         my($tref, $aref, $iref, $w)= @_;
         my $buf;
         my $insert= sub {
            my($tref, $aref, $iref)= @_;#!/usr/bin/perl -w
#
# Generate a script which when run recompiles each and every package
# in the Gentoo system.
# This will typically be required on a major GCC upgrade.
#
# $HeadURL: /caches/xsvn/trunk/usr/local/sbin/recompile-entire-system $
# $Author: root $
# $Date: 2006-09-01T14:15:49.548823Z $
# $Revision: 334 $
#
# Written in 2006 by Guenther Brunthaler


use strict;
use File::Temp ':POSIX';


# Change this to any name you like.
my $script= "recompile-remaining-packages";


my $script_header= << '.';
#!/bin/sh
# Run this script repeatedly (if interrupted)
# until no more packages will be compiled.
#
# $Date: 2006-09-01T14:15:49.548823Z $
# $Revision: 334 $
# Written in 2006 by Guenther Brunthaler

STATE_FILE="$HOME/.recompile-entire-system.state"

die() {
   echo "ERROR: $*" >& 2; exit 1
}

save_progress() {
   { echo "$OURGCC"; echo $PROGRESS; } > "$STATE_FILE"
}

item() {
   test "$PROGRESS" -ge "$1" && return
   echo "Emerging package # $1 ('$2')..."
   emerge --oneshot --nodeps "$2" || {
      die "Emerge failed return code $?!"
   }
   echo "Package # $1 rebuild complete."; echo
   PROGRESS="$1"; save_progress
}

OURGCC="`gcc-config --get-current-profile`" || die "gcc-config failed!"
PROGRESS=; LASTGCC=
{ read LASTGCC; read PROGRESS; } < "$STATE_FILE" 2> /dev/null
if [ "$OURGCC" != "$LASTGCC" -o -z "$PROGRESS" ]; then
   PROGRESS=0; save_progress
fi

.

my $script_tail= << '.';

echo
echo "Success! All packages have been re-compiled."
echo "Your system is now up-to-date with respect to $OURGCC!"
echo
echo "If your want to recompile the whole system again"
echo "for the *same* GCC version, please"
echo "\$ rm \"$STATE_FILE\""
echo "in order to reset the sucessfully-recompiled-packages counter."
.


# Remove the largest common whitespace prefix from all lines
# of the first argument.
# (Empty lines or lines containing only whitespace are skipped
# by this operation and will be replaced by
# completely empty lines.)
# The first argument must either be a reference to a multiline
# string containing newline characters or a reference to an
# array of single line strings (without newline characters).
# Then optionally indent all resulting lines with the prefix
# specified as the argument to the -first option.
# For all indented lines do the same, but use the argument
# to option -indent as the value of the -first option then.
# If option -wrap <number> is specified, contiguous non-empty
# lines of the same indentation depth are considered paragraphs,
# and will be word-wrapped on output, resulting in a maximum
# total line length of <number> characters.
# The word-wrappin will occur on whitespaces, which can be
# protected by a backslash.
sub normalize_indentation {
   my($tref, %opt)= @_;
   my(@t, $t, $p, $pl);
   $opt{-first}||= '';
   $opt{-indent}||= ' ';
   $t= ref($tref) eq 'ARRAY' ? $tref : [split /\n/, $$tref];
   foreach (@$t) {
      s/^\s+$//;
      next if $_ eq '';
      if (defined $pl) {
         for (;;) {
            substr($p, $pl= length)= '' if length() < $pl;
            last if substr($_, 0, $pl) eq $p;
            substr($p, --$pl)= '';
         }
      } else {
         ($p)= /^(\s*)/;
         $pl= length $p;
      }
   }
   substr($_, 0, $pl)= '' foreach grep $_ ne '', @$t;
   if (exists $opt{-wrap}) {
      my $width= $opt{-wrap} - length $opt{-first};
      my $i;
      my $wrap= sub {
         my($tref, $aref, $iref, $w)= @_;
         my $buf;
         my $insert= sub {
            my($tref, $aref, $iref)= @_;
            splice @$aref, $$iref++, 0, $$tref if defined $$tref;
            undef $$tref;
         };
         return unless $$tref;
         foreach (split /(?:(?<!\\)\s)+/, $$tref) {
            s/\\\s/ /gs;
            if (length($buf || '') + length > $w) {
               &$insert(\$buf, $aref, $iref);
            }
            if (defined $buf) {$buf.= " $_"} else {$buf= $_}
         }
         &$insert(\$buf, $aref, $iref);
         undef $$tref;
      };
      $width= 1 if $width < 1;
      undef $p;
      for ($i= 0; $i < @$t; ) {
         if ($t->[$i] =~ /^(?:\s|$)/) {
            &$wrap(\$p, $t, \$i, $width);
            ++$i;
         } else {
            if (defined $p) {$p.= ' '} else {$p= ''}
            $p.= $t->[$i];
            splice @$t, $i, 1;
         }
      }
      &$wrap(\$p, $t, \$i, $width);
   }
   for (my $i= 0; $i < @$t; ) {
      if ($t->[$i] =~ /^\s/) {
         push @t, splice @$t, $i, 1;
         next;
      }
      if (@t) {
         &normalize_indentation(\@t, %opt, -first => $opt{-indent});
         splice @$t, $i, 0, @t;
         $i+= @t;
         @t= ();
      }
      ++$i;
   }
   if (@t) {
      &normalize_indentation(\@t, %opt, -first => $opt{-indent});
      push @$t, @t;
   }
   substr($_, 0, 0)= $opt{-first} foreach grep $_ ne '', @$t;
   $$tref= join '', map "$_\n", @$t if ref($tref) ne 'ARRAY';
}


sub wrap0(@) {
   my $text= join ' ', @_;
   normalize_indentation \$text, -indent => '    ', -wrap => 79;
   return \$text;
}


sub pwrap(@) {
   print ${wrap0 @_};
}


our $step= 0;
our $substep;


sub check {
   my %opt= @_;
   my %a= (y => {qw/name yes/}, n => {qw/name no/}, a => {qw/name abort/});
   my($q, $default, $k, $v, $m, $a, @a);
   die "Missing question" unless $q= $opt{q};
   delete $opt{q};
   while (($k, $v)= each %opt) {
      if (!exists $a{$k} && exists $a{$k= lc $k}) {
         die "Duplicate default answer '$k' in $q" if $default;
         $default= $k;
      } elsif (!exists $a{$k}) {
         die "Unsupported key '$k' in '$q'";
      }
      $a{$k}->{val}= $v;
   }
   unless ($a{y}->{val} && $a{n}->{val}) {
      if ($a{y}->{val} || $a{n}->{val}) {
         # Only one of (yes, no).
         # The other automatically means 'continue'.
         $a{y}->{val}= sub{} unless $a{y}->{val};
         $a{n}->{val}= sub{} unless $a{n}->{val};
      } else {
         # Neither yes nor no available. Only "abort" remains.
         delete $a{y};
         delete $a{n};
      }
   }
   if ($substep) {
      $k= $step . $substep++;
   } else {
      $k= ++$step;
   }
   substr($q, 0, 0)= "Step $k: ";
   $q.=
      "? ["
      . join(
         "/"
         , map {
            my $s= $a{$_}->{name};
            $s =~ s/^(.)/\u$1/ if $_ eq $default;
            $m= length $s if !defined($m) || length($s) > $m;
            $s;
         } keys %a
      )
      . "] "
   ;
   $q.= '#' x ++$m;
   $q= ${wrap0 $q};
   substr($q, -($m + 1))= '';
   for (;;) {
      {
         local $|= 1;
         print $q;
         $a= <STDIN>;
         $a =~ s/^\s*|\s*$//g;
      }
      if ($a) {
         @a= grep {
            length($a) <= length()
            && lc($a) eq substr($_, 0, length)
         } keys %a;
         if (@a == 0) {
            pwrap
               "Sorry, I do not understand your answer '$a'!"
               , "Please select one of the available answers.\n\n"
            ;
            next;
         }
         if (@a > 1) {
            pwrap
               "Sorry, but your answer '$a' is ambiguous!"
               , "Please provide a more specific answer.\n\n"
            ;
            next;
         }
         $a= shift @a;
      } elsif (eof STDIN) {
         # Got EOF. Get the 'abort' equivalent.
         ($a)= grep !defined($a{$_}->{val}), keys %a;
         die unless $a;
      } else {
         # Just an empty string.
         $a= $default;
      }
      last;
   }
   $m= $a{$a}->{val} || sub {
      pwrap
         "OK, then check out the things yourself."
         , "Come back and re-run this script when you are done."
      ;
      exit 0;
   };
   unless (ref $m eq 'CODE') {
      die "Answer '$a' in '$q' has invalid contents";
   }
   $k= $substep;
   local $substep= $k ? $k++ : 'a';
   &$m;
}


sub quote_command(@) {
   return join(
      ' '
      , map {
         /[\s"]|^$/
         ? do {
            my $s= $_;
            $s =~ s/"/\\"/g;
            qq'"$s"';
         }
         : $_
      } @_
   );
}


sub xsystem(@) {
   print "Simulation: ", @_, "\n";
   0;
}


sub run(@) {
   my $self= shift;
   die "No command specified for execution" unless @_;
   if (xsystem(@_) != 0) {
      if ($? == -1) {
         die "Could not launch command: $!";
      } elsif ($? & 127) {
         die sprintf(
            "Child process died with signal %d, %s coredump"
            , $? & 127, $? & 128 ? 'with' : 'without'
         );
      } else {
         die sprintf "Child process exited with value %d", $? >> 8;
      }
   }
}


sub shall_run(@) {
   my $disp= quote_command @_;
   check(
      q => "Shall I run '$disp' for you now"
      , Y => sub {run @_}
   );
}


$_=q<
But only run this script after taking the following steps:
* Do an 'emerge --sync' in order to ensure your portage tree is up to date.
* Run 'emerge --update --deep --newuse world' to ensure all packages are up to
  date (using your old compiler).
* Optionally run 'emerge --ask --depclean' in order to remove any leftover
  old packages (You don't want to recompile those later, don't you?)
* Emerge the new compiler you want>;

$ENV{LC_ALL}= "C";
my $home= $ENV{HOME};
unless ($home && -d $home) {
   die 'Please set $HOME to your home directory';
}
$home =~ s!/*$!/!;
substr($script, 0, 0)= $home;
if (-e $script) {
   die "Please remove the existing '$script'.\nIt is in the way";
}
pwrap "$0 -", << '.';
Recompile Entire System Helper

Script version as of $Date: 2006-09-01T14:15:49.548823Z $

Written in 2006 by Guenther Brunthaler

This script will generate another script to be run by you.
That other script will then recompile each and every package
in the whole system in the correct order.

This will typically be required on a major GCC upgrade.

IMPORTANT: Do not execute this script before all of the following
prerequisites are met:

* Portage tree is up-to-date (emerge --sync)

* Your system is up-to-date (emerge --ask --update --deep --newuse world)

* gentoolkit is available. (The script uses it.) If you are unsure, just
do an 'emerge\ --update\ gentoolkit' and it will be emerged unless it is
already installed.

* The new compiler you want is already *installed*. (No packages need have to
be recompiled with it yet. It also need not be the currently selected default
compiler version yet.) As GCC allows multislot installations, it is not a
problem in Gentoo to have both your current and a new compiler be installed at
the same time.

* If all the above conditions are met, and no more packages need to be
compiled in order to have an up-to-date system, set the new compiler as the
new system default compiler using "gcc-config".

* If you want to change your Gentoo system profile to a new one using
eselect\ profile, it is now also the right time to do it.

* Only then continue running this script!

Press [Ctrl]+[C] now in order to abort processing if some of the above
preconditions are not met. Come back and re-run this script after you have
managed to establish all the preconditions as specified.

Press [Enter] now to continue if you dare.

.
<STDIN>;
#But before the build-script can be generated, there is a check list
#you have to go through, because recompiling an entire system is
#a delicate and highly error-prone task.
#
#So let's start with the check list now!
#.
#print "\n";
#check(
#   q => 'Is your portage tree up to date (have you run "emerge\ --sync" lately)'
#   , N => sub {shall_run 'emerge --sync'}
#);
#exit;
my $tmp= tmpnam or die "No temporary file names left";
print "Collecting list of packages and evaluating installation order...\n";
my @head= qw(
   sys-kernel/linux-headers
   sys-devel/gcc
   sys-libs/glibc
   sys-devel/binutils
);
my $r= join '|', map quotemeta, @head;
$r= qr/ ^ (?: $r ) - \d /x;
open OUT, (
   '| sort -k1,1 | sort -suk3,3 | sort -nk2,2 | sort -sk1,1 '
   . '| cut -d" " -f3 >> "' . $tmp . '"'
) or die "Cannot open output pipe: $!";
my $n= 0;
foreach my $f (qw/system world/) {
   open IN, "emerge -pe $f |" or die "Cannot open input pipe for '$f': $!";
   while (defined($_= <IN>)) {
      if (/]\s+(.*?)\s/) {
         (my $t, $_)= ($f, $1);
         if (/$r/o) {
            for (my $i= @head; $i--; ) {
               my $L= length $head[$i];
               if (length >= $L && substr($_, 0, $L) eq $head[$i]) {
                  print OUT "begin $i";
                  goto field3;
               }
            }
         }
         print OUT "$t ", ++$n;
         field3:
         print OUT " =$_\n";
      }
   }
   close IN or die $!;
}
close OUT or die $!;
open IN, '<', $tmp or die "Cannot open file '$tmp': $!";
open OUT, '>', "$script" || die "Could not create '$script': $!";
print OUT $script_header;
$n= 1;
while (defined($_= <IN>)) {
   next if m!^=sys-devel/gcc!; # It's already up to date!
   print OUT "item $n $_"; ++$n;
}
print OUT $script_tail;
close OUT or die "Could not finish writing '$script': $!";
close IN or die $!;
unlink($tmp) == 1 or warn "Could not remove temorary file '$tmp': $!";
unless (chmod(0755, $script) == 1) {
   die "Could not set permissions for '$script': $!";
}
pwrap << ".";
Done.

Script "$script" has been generated.

Run this script in order to recompile each and every package in the
system!

By the way, the generated script will do this in a recoverable way:
It can be aborted at any time by you, and will continue where it left off
when you re-run it. (The package where the script was interrupted will
have to be compiled again from its beginning, though.)
.

            splice @$aref, $$iref++, 0, $$tref if defined $$tref;
            undef $$tref;
         };
         return unless $$tref;
         foreach (split /(?:(?<!\\)\s)+/, $$tref) {
            s/\\\s/ /gs;
            if (length($buf || '') + length > $w) {
               &$insert(\$buf, $aref, $iref);
            }
            if (defined $buf) {$buf.= " $_"} else {$buf= $_}
         }
         &$insert(\$buf, $aref, $iref);
         undef $$tref;
      };
      $width= 1 if $width < 1;
      undef $p;
      for ($i= 0; $i < @$t; ) {
         if ($t->[$i] =~ /^(?:\s|$)/) {
            &$wrap(\$p, $t, \$i, $width);
            ++$i;
         } else {
            if (defined $p) {$p.= ' '} else {$p= ''}
            $p.= $t->[$i];
            splice @$t, $i, 1;
         }
      }
      &$wrap(\$p, $t, \$i, $width);
   }
   for (my $i= 0; $i < @$t; ) {
      if ($t->[$i] =~ /^\s/) {
         push @t, splice @$t, $i, 1;
         next;
      }
      if (@t) {
         &normalize_indentation(\@t, %opt, -first => $opt{-indent});
         splice @$t, $i, 0, @t;
         $i+= @t;
         @t= ();
      }
      ++$i;
   }
   if (@t) {
      &normalize_indentation(\@t, %opt, -first => $opt{-indent});
      push @$t, @t;
   }
   substr($_, 0, 0)= $opt{-first} foreach grep $_ ne '', @$t;
   $$tref= join '', map "$_\n", @$t if ref($tref) ne 'ARRAY';
}


sub wrap0(@) {
   my $text= join ' ', @_;
   normalize_indentation \$text, -indent => '    ', -wrap => 79;
   return \$text;
}


sub pwrap(@) {
   print ${wrap0 @_};
}


our $step= 0;
our $substep;


sub check {
   my %opt= @_;
   my %a= (y => {qw/name yes/}, n => {qw/name no/}, a => {qw/name abort/});
   my($q, $default, $k, $v, $m, $a, @a);
   die "Missing question" unless $q= $opt{q};
   delete $opt{q};
   while (($k, $v)= each %opt) {
      if (!exists $a{$k} && exists $a{$k= lc $k}) {
         die "Duplicate default answer '$k' in $q" if $default;
         $default= $k;
      } elsif (!exists $a{$k}) {
         die "Unsupported key '$k' in '$q'";
      }
      $a{$k}->{val}= $v;
   }
   unless ($a{y}->{val} && $a{n}->{val}) {
      if ($a{y}->{val} || $a{n}->{val}) {
         # Only one of (yes, no).
         # The other automatically means 'continue'.
         $a{y}->{val}= sub{} unless $a{y}->{val};
         $a{n}->{val}= sub{} unless $a{n}->{val};
      } else {
         # Neither yes nor no available. Only "abort" remains.
         delete $a{y};
         delete $a{n};
      }
   }
   if ($substep) {
      $k= $step . $substep++;
   } else {
      $k= ++$step;
   }
   substr($q, 0, 0)= "Step $k: ";
   $q.=
      "? ["
      . join(
         "/"
         , map {
            my $s= $a{$_}->{name};
            $s =~ s/^(.)/\u$1/ if $_ eq $default;
            $m= length $s if !defined($m) || length($s) > $m;
            $s;
         } keys %a
      )
      . "] "
   ;
   $q.= '#' x ++$m;
   $q= ${wrap0 $q};
   substr($q, -($m + 1))= '';
   for (;;) {
      {
         local $|= 1;
         print $q;
         $a= <STDIN>;
         $a =~ s/^\s*|\s*$//g;
      }
      if ($a) {
         @a= grep {
            length($a) <= length()
            && lc($a) eq substr($_, 0, length)
         } keys %a;
         if (@a == 0) {
            pwrap
               "Sorry, I do not understand your answer '$a'!"
               , "Please select one of the available answers.\n\n"
            ;
            next;
         }
         if (@a > 1) {
            pwrap
               "Sorry, but your answer '$a' is ambiguous!"
               , "Please provide a more specific answer.\n\n"
            ;
            next;
         }
         $a= shift @a;
      } elsif (eof STDIN) {
         # Got EOF. Get the 'abort' equivalent.
         ($a)= grep !defined($a{$_}->{val}), keys %a;
         die unless $a;
      } else {
         # Just an empty string.
         $a= $default;
      }
      last;
   }
   $m= $a{$a}->{val} || sub {
      pwrap
         "OK, then check out the things yourself."
         , "Come back and re-run this script when you are done."
      ;
      exit 0;
   };
   unless (ref $m eq 'CODE') {
      die "Answer '$a' in '$q' has invalid contents";
   }
   $k= $substep;
   local $substep= $k ? $k++ : 'a';
   &$m;
}


sub quote_command(@) {
   return join(
      ' '
      , map {
         /[\s"]|^$/
         ? do {
            my $s= $_;
            $s =~ s/"/\\"/g;
            qq'"$s"';
         }
         : $_
      } @_
   );
}


sub xsystem(@) {
   print "Simulation: ", @_, "\n";
   0;
}


sub run(@) {
   my $self= shift;
   die "No command specified for execution" unless @_;
   if (xsystem(@_) != 0) {
      if ($? == -1) {
         die "Could not launch command: $!";
      } elsif ($? & 127) {
         die sprintf(
            "Child process died with signal %d, %s coredump"
            , $? & 127, $? & 128 ? 'with' : 'without'
         );
      } else {
         die sprintf "Child process exited with value %d", $? >> 8;
      }
   }
}


sub shall_run(@) {
   my $disp= quote_command @_;
   check(
      q => "Shall I run '$disp' for you now"
      , Y => sub {run @_}
   );
}


$_=q<
But only run this script after taking the following steps:
* Do an 'emerge --sync' in order to ensure your portage tree is up to date.
* Run 'emerge --update --deep --newuse world' to ensure all packages are up to
  date (using your old compiler).
* Optionally run 'emerge --ask --depclean' in order to remove any leftover
  old packages (You don't want to recompile those later, don't you?)
* Emerge the new compiler you want>;

$ENV{LC_ALL}= "C";
my $home= $ENV{HOME};
unless ($home && -d $home) {
   die 'Please set $HOME to your home directory';
}
$home =~ s!/*$!/!;
substr($script, 0, 0)= $home;
if (-e $script) {
   die "Please remove the existing '$script'.\nIt is in the way";
}
pwrap "$0 -", << '.';
Recompile Entire System Helper

Script version as of $Date: 2006-09-01T14:15:49.548823Z $

Written in 2006 by Guenther Brunthaler

This script will generate another script to be run by you.
That other script will then recompile each and every package
in the whole system in the correct order.

This will typically be required on a major GCC upgrade.

IMPORTANT: Do not execute this script before all of the following
prerequisites are met:

* Portage tree is up-to-date (emerge --sync)

* Your system is up-to-date (emerge --ask --update --deep --newuse world)

* gentoolkit is available. (The script uses it.) If you are unsure, just
do an 'emerge\ --update\ gentoolkit' and it will be emerged unless it is
already installed.

* The new compiler you want is already *installed*. (No packages need have to
be recompiled with it yet. It also need not be the currently selected default
compiler version yet.) As GCC allows multislot installations, it is not a
problem in Gentoo to have both your current and a new compiler be installed at
the same time.

* If all the above conditions are met, and no more packages need to be
compiled in order to have an up-to-date system, set the new compiler as the
new system default compiler using "gcc-config".

* If you want to change your Gentoo system profile to a new one using
eselect\ profile, it is now also the right time to do it.

* Only then continue running this script!

Press [Ctrl]+[C] now in order to abort processing if some of the above
preconditions are not met. Come back and re-run this script after you have
managed to establish all the preconditions as specified.

Press [Enter] now to continue if you dare.

.
<STDIN>;
#But before the build-script can be generated, there is a check list
#you have to go through, because recompiling an entire system is
#a delicate and highly error-prone task.
#
#So let's start with the check list now!
#.
#print "\n";
#check(
#   q => 'Is your portage tree up to date (have you run "emerge\ --sync" lately)'
#   , N => sub {shall_run 'emerge --sync'}
#);
#exit;
my $tmp= tmpnam or die "No temporary file names left";
print "Collecting list of packages and evaluating installation order...\n";
my @head= qw(
   sys-kernel/linux-headers
   sys-devel/gcc
   sys-libs/glibc
   sys-devel/binutils
);
my $r= join '|', map quotemeta, @head;
$r= qr/ ^ (?: $r ) - \d /x;
open OUT, (
   '| sort -k1,1 | sort -suk3,3 | sort -nk2,2 | sort -sk1,1 '
   . '| cut -d" " -f3 >> "' . $tmp . '"'
) or die "Cannot open output pipe: $!";
my $n= 0;
foreach my $f (qw/system world/) {
   open IN, "emerge -pe $f |" or die "Cannot open input pipe for '$f': $!";
   while (defined($_= <IN>)) {
      if (/]\s+(.*?)\s/) {
         (my $t, $_)= ($f, $1);
         if (/$r/o) {
            for (my $i= @head; $i--; ) {
               my $L= length $head[$i];
               if (length >= $L && substr($_, 0, $L) eq $head[$i]) {
                  print OUT "begin $i";
                  goto field3;
               }
            }
         }
         print OUT "$t ", ++$n;
         field3:
         print OUT " =$_\n";
      }
   }
   close IN or die $!;
}
close OUT or die $!;
open IN, '<', $tmp or die "Cannot open file '$tmp': $!";
open OUT, '>', "$script" || die "Could not create '$script': $!";
print OUT $script_header;
$n= 1;
while (defined($_= <IN>)) {
   next if m!^=sys-devel/gcc!; # It's already up to date!
   print OUT "item $n $_"; ++$n;
}
print OUT $script_tail;
close OUT or die "Could not finish writing '$script': $!";
close IN or die $!;
unlink($tmp) == 1 or warn "Could not remove temorary file '$tmp': $!";
unless (chmod(0755, $script) == 1) {
   die "Could not set permissions for '$script': $!";
}
pwrap << ".";
Done.

Script "$script" has been generated.

Run this script in order to recompile each and every package in the
system!

By the way, the generated script will do this in a recoverable way:
It can be aborted at any time by you, and will continue where it left off
when you re-run it. (The package where the script was interrupted will
have to be compiled again from its beginning, though.)
.


Run it, and follow the instructions! It creates a second script which lists all the installed packages and re-emerges them one by one, maintaining an index into the list to allow the script to restart where it left off.
Back to top
View user's profile Send private message
NeddySeagoon
Administrator
Administrator


Joined: 05 Jul 2003
Posts: 54096
Location: 56N 3W

PostPosted: Wed Jan 16, 2013 9:04 pm    Post subject: Reply with quote

friesia,

On the rare occasions when its needed, I do a stage 1, gcc-config my gcc followed by emerge -e world.
This rebuilds everything in the stage 1 again but its under an hour so I live with that.

Stage 1 is still on your system - its no longer advertised.
_________________
Regards,

NeddySeagoon

Computer users fall into two groups:-
those that do backups
those that have never had a hard drive fail.
Back to top
View user's profile Send private message
friesia
Apprentice
Apprentice


Joined: 23 Mar 2007
Posts: 202

PostPosted: Fri Jan 18, 2013 7:51 am    Post subject: Reply with quote

NeddySeagoon, what do you mean by doing stage 1? How is it done?
Back to top
View user's profile Send private message
NeddySeagoon
Administrator
Administrator


Joined: 05 Jul 2003
Posts: 54096
Location: 56N 3W

PostPosted: Sat Jan 19, 2013 10:40 am    Post subject: Reply with quote

friesia,

In days of old, there was stage1, stage2 and stage3 installs.
For stage1, you get nothing except enough to build the toolchain.
When stage1 is complete, you have your very own toolchain and can go on to emerge system, most of the system set is missing at this stage.
With the system set installed, you can continue with the optional packages that make up your gentoo base system.
The stage3 file that it used for installs today has stage1 and stage2 completed for you.

To run stage1 to build just the toolchain you do
Code:
cd /usr/portage
scripts/bootstrap.sh
This ignores your USE settings, so when you rebuild everything here later, with emerge -e world, your USE settings are applied to the toolchain.

The release engineering team build the weekly stage3 files following the stage1, stage2 process.
The stage1 and stage2 tarballs are no longer offered as they provided new users more scope for errors and on modern hardware, offer very little, if any, savings in exchange for the extra compile time.

You can use the stage3 tarball to do a stage1 if you wish. When the stage1 and stage2 tarballs were dropped, there was a long running thread on the forums about stage1 on stage3 installs.

The main advantage of a stage1 is that for users on i586 class hardware, the CHOST can be changed. There was only ever i386 and i686 32 bit Intel stage files.
When glibc dropped i386 support, Gentoo produced i486 and i686 stages.
_________________
Regards,

NeddySeagoon

Computer users fall into two groups:-
those that do backups
those that have never had a hard drive fail.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum