Date: Thu, 5 Aug 2004 15:18:27 -0400 From: Christopher Nehren <apeiron@comcast.net> To: FreeBSD Ports List <ports@freebsd.org> Subject: checklibs, version 1.0 Message-ID: <20040805191827.GA81915@prophecy.dyndns.org>
next in thread | raw e-mail | index | archive | help
--/WwmFnJnmDyWGHa4 Content-Type: multipart/mixed; boundary="J2SCkAp4GZ/dPZZf" Content-Disposition: inline --J2SCkAp4GZ/dPZZf Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable As I've been playing with the development version of the GNOME desktop, sometimes portupgrade's magic doesn't always work. Sometimes (read: often), my own stupidity causes problems. These issues combined lead to programs and libraries that aren't updated properly, and that thus have dependencies on library files that no longer exist. You can't run these programs, and you need to rebuild the program / library in question (and sometimes, dependent libraries as well). Wouldn't it be nice if there was a program that would check your files and tell you which ones have dependencies on missing libraries, and which libraries they are? Enter checklibs. checklibs takes a list of files as input, checks that each one is a real binary executable (not a shell script or something else not directly executable), and then runs ldd on each file. It looks through the output of ldd for a configurable string which indicates that a dependent library was not found. For each missing library of each file given on the command line, checklibs makes an entry in a global hash. At the end of its run, checklibs outputs each file with a missing dependency and all of the missing dependencies of each file, sorted lexicographically. Note that in order to do its job, checklibs uses Perl's file tests, including the -B test. Some naughty shell scripts (like sawfish-ui) include binary data like bytecode towards the top of the file, and this fools Perl into thinking that the file is binary. checklibs is covered by the Egoware License, version 1.0 (c) Christopher=20 Nehren. The Egoware License is identical to placing something in the public= =20 domain, except that a user of the materials in question who appreciates said materials is asked to write an email to the author stating such. --=20 I abhor a system designed for the "user", if that word is a coded pejorative meaning "stupid and unsophisticated". -- Ken Thompson - Unix is user friendly. However, it isn't idiot friendly. --J2SCkAp4GZ/dPZZf Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=checklibs Content-Transfer-Encoding: quoted-printable #!/usr/bin/perl -w use strict; $ENV{'PATH'} =3D "/bin:/sbin:/usr/bin:/usr/sbin"; my $LDD_PATH =3D "/usr/bin/ldd"; my $MISSING_STRING =3D " =3D> not found (0x0)"; my $WARN =3D 0; my $current_file =3D ""; my %bad_programs =3D (); for(@ARGV) { unless(-e) { warn "$_ doesn't exist, skipping...\n" if $WARN; next; } unless(-f _) { warn "$_ isn't a regular file, skipping...\n" if $WARN; next; } unless(-x _ or -X _) { warn "$_ isn't an executable, skipping...\n" if $WARN; next; } unless(-B _) { warn "$_ doesn't appear to be a binary file, skipping...\n" if $WARN; next; } if(-l $_) # need $_ because the previous stat may not have been an lstat { $current_file =3D readlink $_ or warn "problem reading $_: $!\n" if $WARN; } else { $current_file =3D $_; } my @ldd_output =3D qx/$LDD_PATH $current_file/; chomp @ldd_output; unless(@ldd_output) { warn "'$LDD_PATH $current_file' failed!\n" if $WARN; } my @sorted =3D sort grep (/\Q$MISSING_STRING\E/, @ldd_output); if(@sorted) { s/^\s+// for @sorted; my $previous =3D "previous"; my @bad_libraries =3D grep($_ ne $previous &&=20 ($previous =3D $_, 1), @sorted); my @split =3D map {(split / =3D> /)[0]} @bad_libraries; $bad_programs{$current_file} =3D [@split]; } } for(keys %bad_programs) { print "$_:\n"; for my $badlib (@{$bad_programs{$_}}) { print "\t$badlib not found\n"; } } __END__ =3Dhead1 NAME B<checklibs> -- analyse programs and libraries for missing libraries =3Dhead1 SYNOPSIS % checklibs file1 [file2 ... filen] % checklibs /usr/X11R6/bin/* /usr/local/bin/* =3Dhead1 DESCRIPTION B<checklibs> is a simple program which takes a list of files as command line arguments and checks each one to see if any of them depends upon a library = file which the linker cannot find. If B<checklibs> finds any files with missing dependencies, it lists them in a style similar to that of C<ldd(1)>. It doe= s=20 this by processing the output of C<ldd(1)> and using a configurable string = to indicate that a library was not found. Read the top of the file for tunable= s, including the variable which determines the "not found" string. =3Dhead1 CAVEATS Note that in order to do its job, checklibs uses Perl's file tests, including the -B test. Some naughty shell scripts include binary data like= =20 bytecode towards the top of the file, and this fools Perl into thinking tha= t=20 the file is binary. =3Dhead1 AUTHOR B<checklibs> was written by Christopher Nehren <apeiron@comcast.net>. =3Dhead1 LICENSE B<checklibs> is covered by the Egoware License, version 1.0 (c) Christopher Nehren. The Egoware License is identical to placing something in the public domain, except that a user of the materials in question who appreciates said materials is asked to write an email to the author stating such. =3Dhead1 SEE ALSO C<ldd(1)> --J2SCkAp4GZ/dPZZf-- --/WwmFnJnmDyWGHa4 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (FreeBSD) iD8DBQFBEogBk/lo7zvzJioRAiwoAJ9S2EVLexPL78wTPPG3AlabLsf6JQCeK85D alKo5S8T2xwpsQS1AipAO1U= =WGzB -----END PGP SIGNATURE----- --/WwmFnJnmDyWGHa4--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040805191827.GA81915>