#!/usr/bin/perl -w # # repack_cross: Convert foreign arch binary .rpm file into a noarch rpm # file suitable for sysroot installation. # # Copyright (C) 2007 Marvell Semiconductor # # TODO: # - preserve %attr config(missingok,noreplace)/ghost/verify(foo bar baz) # - scripts, and script-induced dependencies # sub getattr { my $rpm = shift; my $tag = shift; my $attr; local *OUTPUT; open OUTPUT, "rpm -qp $rpm --queryformat %{$tag} |"; local $/; $attr = ; close OUTPUT; return $attr; } sub getattr2 { my $rpm = shift; my $tag = shift; my @attr; local *OUTPUT; open OUTPUT, "rpm -qp $rpm --$tag |"; @attr = ; close OUTPUT; return @attr; } sub output_simple_attrs { my @attrs = ( "Name", "Epoch", "Version", "Release", "Summary", "Distribution", "License", "Group", "URL", ); my $rpm = shift; my $target = shift; my $value; foreach $attr (@attrs) { $value = getattr($rpm, $attr); next if ($value eq "(none)"); if ($attr eq "Name") { print "$attr: ${value}-${target}\n"; } else { print "$attr: $value\n"; } } } sub adjust_dep { my $dep = shift; my $target = shift; my $sysroot = shift; # Don't carry over rpmlib dependencies if ($dep =~ /^rpmlib/) { return ""; } # File dependency if ($dep =~ /^\//) { return "${sysroot}${dep}"; } # Shared object dependency if ($dep =~ /\.so/) { # Remove .so version info, as the Provides: don't # encode that info explicitly. $dep =~ s/\(.*\)//; # Remove trailing spaces $dep =~ s/ *$//; return "${dep}.${target}"; } # Package dependency if ($dep =~ / /) { $dep =~ s/ /-${target} /; } else { $dep .= "-${target}"; } return $dep; } sub output_provides_requires_conflicts { my $rpm = shift; my $target = shift; my $sysroot = shift; my @value; my $value; @value = getattr2($rpm, "conflicts"); foreach $value (@value) { chomp $value; if ($value ne "(none)") { $value = adjust_dep($value, $target, $sysroot); if ($value ne "") { print "Conflicts: $value\n"; } } } @value = getattr2($rpm, "provides"); foreach $value (@value) { chomp $value; if ($value ne "(none)") { $value = adjust_dep($value, $target, $sysroot); if ($value ne "") { print "Provides: $value\n"; } } } @value = getattr2($rpm, "requires"); foreach $value (@value) { chomp $value; if ($value ne "(none)") { $value = adjust_dep($value, $target, $sysroot); if ($value ne "") { print "Requires: $value\n"; } } } } sub output_description { my $rpm = shift; my $value; $value = getattr($rpm, "Description"); if ($value ne "(none)") { print "%description\n$value\n\n"; } } sub output_files { my $rpm = shift; my $basepath = shift; my $sysroot = shift; my $file; local *FILE; print "%files\n"; print "%attr(0755, root, root) %dir $basepath\n"; open FILE, "rpm -qp --dump $rpm |"; while ($line = ) { my @attr; my $file; my $perm; my $user; my $group; my $dir; my $config; my $doc; chomp $line; @attr = split " ", $line; $file = $sysroot . $attr[0]; $perm = substr($attr[4], -4); $user = $attr[5]; $group = $attr[6]; $dir = (substr($attr[4], -5, 1) eq "4") ? " %dir" : ""; $config = $attr[7] ? " %config" : ""; $doc = $attr[8] ? " %doc" : ""; print "%attr($perm, $user, $group)${dir}${config}${doc} $file\n"; } close FILE; print "\n"; } sub output_changelog { my $rpm = shift; my @value; my $value; print "%changelog\n"; @value = getattr2($rpm, "changelog"); foreach $value (@value) { $value =~ s/%/%%/g; print $value; } } my $rpm; my $target; my $basepath; my $sysroot; $rpm = shift or die; $target = shift or die; $basepath = "/usr/$target"; $sysroot = "/usr/$target/sys-root"; print "%define _unpackaged_files_terminate_build %{nil}\n"; print "%define _use_internal_dependency_generator %{nil}\n"; print "%define __find_provides %{nil}\n"; print "%define __find_requires %{nil}\n"; print "%define __mono_provides %{nil}\n"; print "%define __mono_requires %{nil}\n"; print "%define __os_install_post %{nil}\n"; print "%define __perl_provides %{nil}\n"; print "%define __perl_requires %{nil}\n"; print "%define __python_provides %{nil}\n"; print "%define __python_requires %{nil}\n"; print "\n"; output_simple_attrs($rpm, $target); print "Source0: " . `basename $rpm`; print "BuildArchitectures: noarch\n"; print "BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root\n"; print "\n"; output_provides_requires_conflicts($rpm, $target, $sysroot); print "\n"; output_description($rpm); print "%prep\n"; print "\n"; print "%build\n"; print "\n"; print "%install\n"; print "rm -rf \$RPM_BUILD_ROOT\n"; print "mkdir -p \$RPM_BUILD_ROOT/usr/$target/sys-root\n"; print "rpm2cpio < %{SOURCE0} | (cd \$RPM_BUILD_ROOT/usr/$target/sys-root; cpio -id)\n"; print "\n"; print "%clean\n"; print "rm -rf \$RPM_BUILD_ROOT\n"; print "\n"; output_files($rpm, $basepath, $sysroot); output_changelog($rpm);