use File::Find ();
use File::Copy ();
use File::Compare ();
use POSIX ();
if ($#ARGV < 1) {
print "usage: $0 <source-directories ...> <dest-directory>\n";
exit 1;
}
my @sources = @ARGV[0..$#ARGV-1];
my $dest = $ARGV[-1];
my $errors = 0;
my %needs_lipo = ();
sub error {
printf STDERR "%s\n",$_[0];
$errors++;
}
foreach my $s (@sources)
{
sub eachfile {
my $destname = $dest . '/' . $File::Find::name;
if (-d) {
(mkdir $destname or error ("$destname: $!")) unless (-d $destname);
} elsif (-l) {
my $link1 = readlink;
defined $link1 or error ("$s/$_: $!");
if (-l $destname) {
my $link2 = readlink $destname;
defined $link2 or error ("$destname: $!");
$link1 eq $link2 or error ("$destname: different symlinks");
} elsif (-e $destname) {
error ("$destname: symlink vs. real file");
} else {
symlink $link1,$destname or error ("$destname: $!");
}
} elsif (! -f) {
error ("$destname: no idea how to handle special file");
} elsif (! -f $destname) {
system ("cp", "-p", $_, $destname) == 0 or $errors++;
} elsif (File::Compare::compare ($_, $destname) != 0) {
$needs_lipo{$File::Find::name} = 1;
}
}
chdir $s;
File::Find::find (\&eachfile, '.');
}
foreach my $l (keys %needs_lipo) {
my @f = ();
foreach my $s (@sources) {
my $sf = $s . '/' . $l;
push @f,($sf) if (-f $sf);
}
die "inconsistent directories" if ($#f == -1);
if ($#f == 0) {
system ("cp", "-p", $f[0], $dest . '/' . $l) == 0
or $errors++;
} else {
system ("lipo", "-create", "-output", $dest . '/' . $l, @f) == 0
or $errors++;
}
}
exit ($errors ? 1 : 0);