On 01/17/2012 07:51 PM, Kevin Oberman wrote:
I have just been cleaning up the mess caused by the upgrade of xcb-utils.
On my systmes I have hundreds of ports that will be re-built by the methods
listed in UPDATING, even though the vast majority of them are only
dependent on other ports that are dependent on xcb-utils, but don't
actually load any of the libraries in xcb-utils. It is a huge waste of time
and CPU cycles.

I think that I can see two ways of eliminating the rebuilding of ports that
don't need it. One is rather manual but can be done now while the other
wou;d be automatic, but would need to be written by someone who is far
better at writing shell scripts than I.

The manual method would be to install sysutils/bsdadminscripts and use a
command like `pkg_libchk | grep -E "xcb-.+.so" | sort>  tmpfile` to provide
a list of ports that actually are linked to the libraries in question. This
would be fed into portmaster to rebuild just these ports. (I guess I could
use awk and uniq to remove repeats.)

Should this become a preferred method of handling this problem?


You mean something like the attached script?

Type

perl pkg_libchk xcb-util-0.3.6,1

and it tells you all the ports that have xcb-util-0.3.6,1 as a lib-depends.

On my system I get 38 ports that require upgrading. All the other 248 dependencies installed on my system are only run-depends, and so don't need to be upgraded.

I wrote it using perl, because I think a shell script would be quite a bit slower. And it is already quite slow as it is.

It looks worth implementing, because it looks like it could save considerable compilation time. If other people think this tool is useful, someone could clean up the script (e.g. it isn't PREFIX friendly, and assumes the port database is /var/db/pkg, etc). It could also be written as a C program without too much trouble.
#!/usr/bin/perl -w

use strict;

my %lib_found;
my %ldd;
 
sub pkg_libchk {
  my $req="/var/db/pkg/$_[0]/+REQUIRED_BY";
  return if ! -e $req;

  my @libs;
  open(my $C,"/var/db/pkg/$_[0]/+CONTENTS") || die;
  while (<$C>) {
    if (!/^\@/ && /\/(lib[^\/]+\.so)$/) {
      push @libs,$1;
    }
  }
  close $C;
  return if $#libs==-1;

  open(my $R,$req) || die;
  while (my $r=<$R>) {
    next if defined($lib_found{$r});
    chomp $r;
    open(my $C,"/var/db/pkg/$r/+CONTENTS") || die;
    while (my $f=<$C>) {
      chomp $f;
      if ($f !~ /^@/) {
        if (!defined($ldd{$f})) {
          $ldd{$f} = `ldd "/usr/local/$f" 2>/dev/null`;
        }
        foreach my $l (@libs) {
          if ($ldd{$f} =~/$l/) {
            if (!defined($lib_found{$r})) {
              print "$r\n";
              $lib_found{$r}=1;
              pkg_libchk($r);
              goto DONE;
            }
          }
        }
      }
    }
DONE:
    close($C);
  }
  close($R);
}

die if ! -e "/var/db/pkg/$ARGV[0]";
pkg_libchk($ARGV[0]);
_______________________________________________
freebsd-ports@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ports
To unsubscribe, send any mail to "freebsd-ports-unsubscr...@freebsd.org"

Reply via email to