作成 2012.01.28
更新 2012.03.11
更新 2012.03.11
FreeBSD のアップグレード後に各実行ファイルの Shared Object ファイルがリンクできているか確認する
FreeBSD を 9.0 へアップグレードした際に動かないのが多かったため。
コード
ldd-recursion.pl download
#!/usr/bin/perl use strict; use warnings; sub ldlist; sub chk_ldd; my $ldd = '/usr/bin/ldd'; my @list = ('/sbin', '/bin', '/usr/sbin', '/usr/bin', '/usr/games','/usr/local/sbin','/usr/local/bin', '/lib','/usr/lib','/usr/local/lib', '/libexec', '/usr/libexec', '/usr/local/libexec'); my %libs = (); my %done = (); foreach my $dir_path (@list){ print "###################\n"; &ldlist($dir_path); } sub ldlist{ print "DIR ".$_[0]."\n"; my $top_dir = $_[0]; opendir(DIR,$top_dir); my @file = readdir(DIR); closedir(DIR); my $path; foreach(@file){ if($_ eq '.' || $_ eq '..'){ next; } $path = $top_dir.'/'.$_; if(-l $path){ $path = readlink($path); if($path =~ /^[^\/]/){ $path = $top_dir.'/'.$path; } } if(-d $path){ &ldlist($path); next; } if(-x $path){ &chk_ldd($path); }elsif($path =~ /\.so/){ &chk_ldd($path); } } } sub chk_ldd{ my $chk_file = $_[0]; my $i; if(exists $done{$chk_file}){ return; } $done{$chk_file} = 1; print $chk_file."\n"; my @res = `$ldd $chk_file`; for($i=1; $i<=$#res; $i++){ my $r = $res[$i]; if($r =~ /not/i){ print $r; }else{ $r =~ s/^\s*(.*?)\s*$/$1/; my @l = split(/ +/,$r); if(exists $libs{$l[0]}){ next; } $libs{$l[0]} = $l[2]; print "*\t".$l[0]."\t".$l[2]."\n"; &chk_ldd($l[2]); } } }
実行例
result.log が作成されるので、"found" のキーワードで検索して見つからなければ多分OK。
$ perl ldd-recursion.pl > result.log 2>&1
not found の行が見つかった場合
とりあえず、アップデートが無いか確認。
"-a" だと全部まとめて。
例えば、libz.so.5 not found の場合は、以下の要領で。
# portsnap fetch # portsnap update # portaudit -Fda # pkg_version | grep -v "="アップデート。バージョン指定の port がある場合は、個別にアップデートしてから実行する。
"-a" だと全部まとめて。
# portmaster -aこれでも残っていた場合は、各ファイルが所属しているパッケージを検索し、再インストールする。
# grep -r ファイル名 /var/db/pkg # portmaster パッケージ名再インストールで解決しない場合、libファイルのアップデート版からリンクする。
例えば、libz.so.5 not found の場合は、以下の要領で。
# ln -s /lib/libz.so.6 /lib/libz.so.5未確認情報。依存するパッケージをすべて再インストール
# portmaster -R -r パッケージ