version 1.15, 2002/02/16 19:53:46
|
version 1.16, 2002/04/07 19:35:27
|
Line 1
|
Line 1
|
#!/usr/bin/perl |
#!/usr/bin/perl |
|
|
|
# -------------------------------------------------------- Documentation notice |
|
# Run "perldoc ./make_rpm.pl" in order to best view the software documentation |
|
# internalized in this program. |
|
|
|
# --------------------------------------------------------- License Information |
# The LearningOnline Network with CAPA |
# The LearningOnline Network with CAPA |
# make_rpm.pl - make RedHat package manager file (A CLEAN AND CONFIGURABLE WAY) |
# make_rpm.pl - make RedHat package manager file (A CLEAN AND CONFIGURABLE WAY) |
# |
# |
Line 32
|
Line 37
|
# YEAR=2001 |
# YEAR=2001 |
# 1/8,1/10,1/13,1/23,5/16 - Scott Harrison |
# 1/8,1/10,1/13,1/23,5/16 - Scott Harrison |
# YEAR=2002 |
# YEAR=2002 |
# 1/4,1/8,1/9,2/13 - Scott Harrison |
# 1/4,1/8,1/9,2/13,4/7 - Scott Harrison |
# |
# |
### |
### |
|
|
Line 45
|
Line 50
|
## ORGANIZATION OF THIS PERL SCRIPT ## |
## ORGANIZATION OF THIS PERL SCRIPT ## |
## ## |
## ## |
## 1. Check to see if RPM builder application is available ## |
## 1. Check to see if RPM builder application is available ## |
## 2. Read in arguments ## |
## 2. Read in command-line arguments ## |
## 3. Generate temporary directories ## |
## 3. Generate temporary directories (subdirs of first command-line argument)## |
## 4. Initialize some variables ## |
## 4. Initialize some variables ## |
## 5. Create a standalone rpm building environment ## |
## 5. Create a stand-alone rpm building environment ## |
## 6. Perform variable initializations and customizations ## |
## 6. Perform variable initializations and customizations ## |
## 7. Print header information for .spec file ## |
## 7. Print header information for .spec file ## |
## 8. Process file list and generate information ## |
## 8. Process file list and generate information ## |
Line 67 use strict;
|
Line 72 use strict;
|
|
|
# ------------------------ Check to see if RPM builder application is available |
# ------------------------ Check to see if RPM builder application is available |
|
|
unless (-e '/usr/lib/rpm/rpmrc') { |
unless (-e '/usr/lib/rpm/rpmrc') { # part of the expected rpm software package |
print <<END; |
print(<<END); |
ERROR: This script only works with a properly installed RPM builder |
**** ERROR **** This script only works with a properly installed RPM builder |
application. |
application. |
Cannot find /usr/lib/rpm/rpmrc, so cannot generate customized rpmrc file. |
Cannot find /usr/lib/rpm/rpmrc, so cannot generate customized rpmrc file. |
Script aborting. |
Script aborting. |
END |
END |
|
exit(1); |
} |
} |
|
|
# ----------------------------------------------------------- Read in arguments |
# ---------------------------------------------- Read in command-line arguments |
|
|
my ($tag,$version,$configuration_files,$documentation_files, |
my ($tag,$version,$configuration_files,$documentation_files, |
$pathprefix,$customize)=@ARGV; |
$pathprefix,$customize)=@ARGV; |
@ARGV=(); |
@ARGV=(); # read standard input based on a pipe, not a command-line argument |
|
|
if (!$version) { |
if (!$version) {# version should be defined and string length greater than zero |
print <<END; |
print(<<END); |
See "perldoc make_rpm.pl" for more information. |
See "perldoc make_rpm.pl" for more information. |
|
|
Usage: |
Usage: |
Line 92 Usage:
|
Line 98 Usage:
|
|
|
Standard input provides the list of files to work with. |
Standard input provides the list of files to work with. |
TAG, required descriptive tag. For example, a kerberos software |
TAG, required descriptive tag. For example, a kerberos software |
package might be tagged as "krb4". |
package might be tagged as "krb4". (This value is also used in |
|
the generation of a temporary directory; you cannot have |
|
a pre-existing directory named ./TAG.) |
VERSION, required version. Needed to generate version information |
VERSION, required version. Needed to generate version information |
for the RPM. This should be in the format N.M where N and M are |
for the RPM. It is recommended that this be in the format N.M where N and |
integers. |
M are integers. |
CONFIGURATION_FILES, optional comma-separated listing of files to |
CONFIGURATION_FILES, optional comma-separated listing of files to |
be treated as configuration files by RPM (and thus subject to saving |
be treated as configuration files by RPM (and thus subject to saving |
during RPM upgrades). |
during RPM upgrades). |
Line 108 root-level. Note, this still depends on
|
Line 116 root-level. Note, this still depends on
|
after PATHPREFIX. |
after PATHPREFIX. |
CUSTOMIZATION_XML, allows for customizing various pieces of information such |
CUSTOMIZATION_XML, allows for customizing various pieces of information such |
as vendor, summary, name, copyright, group, autoreqprov, requires, prereq, |
as vendor, summary, name, copyright, group, autoreqprov, requires, prereq, |
description, and pre-installation scripts (see more in the POD; |
description, and pre-installation scripts (see more in the POD, |
perldoc make_rpml.pl). |
"perldoc make_rpm.pl"). |
END |
END |
exit; |
exit(1); |
} |
} |
|
|
mkdir $tag,0755; |
# ----- Generate temporary directories (subdirs of first command-line argument) |
mkdir "$tag/BuildRoot",0755; |
|
mkdir "$tag/SOURCES",0755; |
# Do some error-checking related to important first command-line argument. |
mkdir "$tag/SPECS",0755; |
if ($tag=~/\W/) { # non-alphanumeric characters cause problems |
mkdir "$tag/BUILD",0755; |
print(<<END); |
mkdir "$tag/SRPMS",0755; |
**** ERROR **** Invalid tag name "$tag" |
mkdir "$tag/RPMS",0755; |
(The first command-line argument must be alphanumeric characters without |
mkdir "$tag/RPMS/i386",0755; |
spaces.) |
|
END |
|
exit(1); |
|
} |
|
if (-e $tag) { # do not overwrite or conflict with existing data |
|
print(<<END); |
|
**** ERROR **** a file or directory "./$tag" already exists |
|
(This program needs to generate a temporary directory named "$tag".) |
|
END |
|
exit(1); |
|
} |
|
|
|
print('Generating temporary directory ./'.$tag."\n"); |
|
mkdir($tag,0755) or die("**** ERROR **** cannot generate $tag directory\n"); |
|
mkdir("$tag/BuildRoot",0755); |
|
mkdir("$tag/SOURCES",0755); |
|
mkdir("$tag/SPECS",0755); |
|
mkdir("$tag/BUILD",0755); |
|
mkdir("$tag/SRPMS",0755); |
|
mkdir("$tag/RPMS",0755); |
|
mkdir("$tag/RPMS/i386",0755); |
|
|
# -------------------------------------------------------- Initialize variables |
# -------------------------------------------------------- Initialize variables |
|
|
my $file; |
my $file; |
my $binaryroot="$tag/BinaryRoot"; |
my $binaryroot=$tag.'/BinaryRoot'; |
my ($type,$size,$octalmode,$user,$group); |
my ($type,$size,$octalmode,$user,$group); |
|
|
my $currentdir=`pwd`; chop $currentdir; my $invokingdir=$currentdir; |
my $currentdir=`pwd`; chomp($currentdir); my $invokingdir=$currentdir; |
$currentdir.="/$tag"; |
$currentdir.='/'.$tag; |
|
|
# -------------------------------- Create a standalone rpm building environment |
# ------------------------------- Create a stand-alone rpm building environment |
|
|
open (IN,'</usr/lib/rpm/rpmrc') or die('Cannot open /usr/lib/rpm/rpmrc'); |
print('Creating stand-alone rpm build environment.'."\n"); |
|
open(IN,'</usr/lib/rpm/rpmrc') or die('Cannot open /usr/lib/rpm/rpmrc'."\n"); |
my @lines=<IN>; |
my @lines=<IN>; |
close IN; |
close(IN); |
|
|
open (RPMRC,">$tag/SPECS/rpmrc"); |
open(RPMRC,">$tag/SPECS/rpmrc"); |
foreach my $line (@lines) { |
foreach my $line (@lines) { |
if ($line=~/^macrofiles/) { |
if ($line=~/^macrofiles/) { |
chop $line; |
chomp($line); |
$line.=":$currentdir/SPECS/rpmmacros\n"; |
$line.=":$currentdir/SPECS/rpmmacros\n"; |
} |
} |
print RPMRC $line; |
print(RPMRC $line); |
} |
} |
close RPMRC; |
close(RPMRC); |
|
|
open (RPMMACROS,">$tag/SPECS/rpmmacros"); |
open(RPMMACROS,">$tag/SPECS/rpmmacros"); |
print RPMMACROS <<END; |
print(RPMMACROS <<END); |
\%_topdir $currentdir |
\%_topdir $currentdir |
\%__spec_install_post \\ |
\%__spec_install_post \\ |
/usr/lib/rpm/brp-strip \\ |
/usr/lib/rpm/brp-strip \\ |
/usr/lib/rpm/brp-strip-comment-note \\ |
/usr/lib/rpm/brp-strip-comment-note \\ |
\%{nil} |
\%{nil} |
END |
END |
close RPMMACROS; |
close(RPMMACROS); |
|
|
# ------------------------- Perform variable initializations and customizations |
# ------------------------- Perform variable initializations and customizations |
|
|
my $cu; |
my $cu=''; # string that holds customization XML file contents |
if ($customize) { |
if (length($customize)>0) { |
open (IN,"<$customize") or die("Cannot open $customize"); |
print('Reading in XML-formatted customizations from '.$customize."\n"); |
|
open(IN,"<$customize") or |
|
( |
|
print(`cd $invokingdir; rm -Rf $tag`) and |
|
die('Cannot open customization file "'.$customize.'"'."\n") |
|
); |
my @clines=(<IN>); |
my @clines=(<IN>); |
$cu=join('',@clines); |
$cu=join('',@clines); |
close IN; |
close(IN); |
} |
} |
my $tv; # tag value variable for storing retrievals from $cu |
|
|
|
# (Sure. We could use HTML::TokeParser here.. but that wouldn't be fun now, |
# tv - temporary variable (if it exists inside the XML document) then use it, |
|
# otherwise don't overwrite existing values of variables |
|
my $tv=''; |
|
|
|
# (Sure. We could use HTML::TokeParser here... but that wouldn't be fun now, |
# would it?) |
# would it?) |
my $name=$tag; |
my $name=$tag; |
# read in name from customization if available |
# read in name from customization if available |
$tv=grabtag('name',$cu,1); $name=$tv if $tv; |
$tv=grabtag('name',$cu,1); $name=$tv if $tv; |
$name=~s/\<tag \/\>/$tag/g; |
$name=~s/\<tag \/\>/$tag/g; |
|
|
# okay.. now we can generate this needed directory |
# (When in doubt, be paranoid about overwriting things.) |
mkdir "$tag/SOURCES/$name-$version",0755; |
if (-e "$name-$version-1.i386.rpm") { |
|
print(`cd $invokingdir; rm -Rf $tag`); # clean temporary filespace in use |
|
die("**** ERROR **** $name-$version-1.i386.rpm already exists.\n"); |
|
} |
|
|
my $requires=""; |
my $requires=''; |
# read in relevant requires info from customization file (if applicable) |
# read in relevant requires info from customization file (if applicable) |
# note that "PreReq: item" controls order of CD-ROM installation (if you |
# note that "PreReq: item" controls order of CD-ROM installation (if you |
# are making a customized CD-ROM) |
# are making a customized CD-ROM) |
Line 190 $requires=~s/\s*\<\/item\>\s*//g;
|
Line 230 $requires=~s/\s*\<\/item\>\s*//g;
|
$requires=~s/\s*\<item\>\s*/\n/g; |
$requires=~s/\s*\<item\>\s*/\n/g; |
$requires=~s/^\s+//s; |
$requires=~s/^\s+//s; |
|
|
my $summary="Files for the $name software package."; |
my $summary='Files for the '.$name.' software package.'; |
# read in summary from customization if available |
# read in summary from customization if available |
$tv=grabtag('summary',$cu,1); $summary=$tv if $tv; |
$tv=grabtag('summary',$cu,1); $summary=$tv if $tv; |
$summary=~s/\<tag \/\>/$tag/g; |
$summary=~s/\<tag \/\>/$tag/g; |
Line 204 my $copyright="not specified here";
|
Line 244 my $copyright="not specified here";
|
$tv=grabtag('copyright',$cu,1); $copyright=$tv if $tv; |
$tv=grabtag('copyright',$cu,1); $copyright=$tv if $tv; |
$copyright=~s/\<tag \/\>/$tag/g; |
$copyright=~s/\<tag \/\>/$tag/g; |
|
|
open (SPEC,">$tag/SPECS/$name-$version.spec"); |
open(SPEC,">$tag/SPECS/$name-$version.spec"); |
|
|
my $vendor='Me'; |
my $vendor='Me'; |
# read in vendor from customization if available |
# read in vendor from customization if available |
Line 216 my $description="$name software package"
|
Line 256 my $description="$name software package"
|
$tv=grabtag('description',$cu,0); $description=$tv if $tv; |
$tv=grabtag('description',$cu,0); $description=$tv if $tv; |
$description=~s/\<tag \/\>/$tag/g; |
$description=~s/\<tag \/\>/$tag/g; |
|
|
my $pre=""; |
my $pre=''; |
# read in pre-installation script if available |
# read in pre-installation script if available |
$tv=grabtag('pre',$cu,0); $pre=$tv if $tv; |
$tv=grabtag('pre',$cu,0); $pre=$tv if $tv; |
$pre=~s/\<tag \/\>/$tag/g; |
$pre=~s/\<tag \/\>/$tag/g; |
|
|
# ------------------------------------- Print header information for .spec file |
# ------------------------------------- Print header information for .spec file |
|
|
print SPEC <<END; |
print(SPEC <<END); |
Summary: $summary |
Summary: $summary |
Name: $name |
Name: $name |
Version: $version |
Version: $version |
Line 265 my %BinaryRootMakefile;
|
Line 305 my %BinaryRootMakefile;
|
my %Makefile; |
my %Makefile; |
my %dotspecfile; |
my %dotspecfile; |
|
|
foreach $file (<>) { |
foreach my $file (<>) { |
chop $file; |
chomp($file); |
my $comment=""; |
my $comment=""; |
if ($file=~/\s+\#(.*)$/) { |
if ($file=~/\s+\#(.*)$/) { |
$file=~s/\s+\#(.*)$//; |
$file=~s/\s+\#(.*)$//; |
Line 288 foreach $file (<>) {
|
Line 328 foreach $file (<>) {
|
$file=~s/^$pathprefix//; |
$file=~s/^$pathprefix//; |
} |
} |
if ($type eq "files") { |
if ($type eq "files") { |
push @{$BinaryRootMakefile{$type}},"\tinstall -D -m $octalmode ". |
push(@{$BinaryRootMakefile{$type}},"\tinstall -D -m $octalmode ". |
"$pathprefix$file $binaryroot$file\n"; |
"$pathprefix$file $binaryroot$file\n"); |
push @{$Makefile{$type}},"\tinstall -D -m $octalmode ". |
push(@{$Makefile{$type}},"\tinstall -D -m $octalmode ". |
"\$(SOURCE)$file \$(ROOT)$file\n"; |
"\$(SOURCE)$file \$(ROOT)$file\n"); |
push @{$dotspecfile{$type}},"$directive\%attr($octalmode,$user,". |
push(@{$dotspecfile{$type}},"$directive\%attr($octalmode,$user,". |
"$group) $file\n"; |
"$group) $file\n"); |
} |
} |
elsif ($type eq "directories") { |
elsif ($type eq "directories") { |
push @{$BinaryRootMakefile{$type}},"\tinstall -m $octalmode -d ". |
push(@{$BinaryRootMakefile{$type}},"\tinstall -m $octalmode -d ". |
"$binaryroot$file\n"; |
"$binaryroot$file\n"); |
push @{$Makefile{$type}},"\tinstall -m $octalmode -d ". |
push(@{$Makefile{$type}},"\tinstall -m $octalmode -d ". |
"\$(SOURCE)$file \$(ROOT)$file\n"; |
"\$(SOURCE)$file \$(ROOT)$file\n"); |
push @{$dotspecfile{$type}},"\%dir \%attr($octalmode,$user,". |
push(@{$dotspecfile{$type}},"\%dir \%attr($octalmode,$user,". |
"$group) $file\n"; |
"$group) $file\n"); |
} |
} |
elsif ($type eq "links") { |
elsif ($type eq "links") { |
my $link=$size; # I use the size variable to pass the link value |
my $link=$size; # I use the size variable to pass the link value |
# from the subroutine find_info |
# from the subroutine find_info |
$link=~s/^$pathprefix//; |
$link=~s/^$pathprefix//; |
push @{$BinaryRootMakefile{$type}}, |
push(@{$BinaryRootMakefile{$type}}, |
"\tln -s $link $binaryroot$file\n"; |
"\tln -s $link $binaryroot$file\n"); |
push @{$Makefile{$type}},"\tln -s $link \$(ROOT)$file\n"; |
push(@{$Makefile{$type}},"\tln -s $link \$(ROOT)$file\n"); |
push @{$dotspecfile{$type}},"\%attr(-,$user,$group) $file\n"; |
push(@{$dotspecfile{$type}},"\%attr(-,$user,$group) $file\n"); |
} |
} |
} |
} |
} |
} |
|
|
# -------------------------------------- Generate SRPM and BinaryRoot Makefiles |
# -------------------------------------- Generate SRPM and BinaryRoot Makefiles |
|
|
open OUTS, ">$tag/SOURCES/$name-$version/Makefile"; |
# Generate a much needed directory. |
open OUTB, ">$tag/BinaryRootMakefile"; |
# This directory is meant to hold all source code information |
|
# necessary for converting .src.rpm files into .i386.rpm files. |
|
mkdir("$tag/SOURCES/$name-$version",0755); |
|
|
|
open(OUTS,">$tag/SOURCES/$name-$version/Makefile"); |
|
open(OUTB, ">$tag/BinaryRootMakefile"); |
foreach $type ("directories","files","links") { |
foreach $type ("directories","files","links") { |
print OUTS "$type\:\n"; |
print(OUTS "$type\:\n"); |
print OUTS join("",@{$Makefile{$type}}) if $Makefile{$type}; |
print(OUTS join("",@{$Makefile{$type}})) if $Makefile{$type}; |
print OUTS "\n"; |
print(OUTS "\n"); |
print OUTB "$type\:\n"; |
print(OUTB "$type\:\n"); |
print OUTB join("",@{$BinaryRootMakefile{$type}}) |
print(OUTB join("",@{$BinaryRootMakefile{$type}})) |
if $BinaryRootMakefile{$type}; |
if $BinaryRootMakefile{$type}; |
print OUTB "\n"; |
print(OUTB "\n"); |
print SPEC join("",@{$dotspecfile{$type}}) if $dotspecfile{$type}; |
print(SPEC join("",@{$dotspecfile{$type}})) if $dotspecfile{$type}; |
} |
} |
close OUTB; |
close(OUTB); |
close OUTS; |
close(OUTS); |
|
|
close SPEC; |
close(SPEC); |
|
|
# ------------------ mirror copy (BinaryRoot) files under a temporary directory |
# ------------------ mirror copy (BinaryRoot) files under a temporary directory |
|
|
Line 341 close SPEC;
|
Line 386 close SPEC;
|
`make -f $tag/BinaryRootMakefile links`; |
`make -f $tag/BinaryRootMakefile links`; |
|
|
# ------------------------------------------------- roll everything into an RPM |
# ------------------------------------------------- roll everything into an RPM |
|
print('Build a tarball and then run the rpm -ba command.'."\n"); |
my $command="cd $currentdir/SOURCES; tar czvf $name-$version.tar.gz ". |
my $command="cd $currentdir/SOURCES; tar czvf $name-$version.tar.gz ". |
"$name-$version"; |
"$name-$version"; |
print `$command`; |
print(`$command`); |
$command="cd $currentdir/SPECS; rpm --rcfile=./rpmrc -ba ". |
$command="cd $currentdir/SPECS; rpm --rcfile=./rpmrc -ba ". |
"$name-$version.spec; cd ../RPMS/i386; cp ". |
"$name-$version.spec; cd ../RPMS/i386; cp -v ". |
"$name-$version-1.i386.rpm $invokingdir/."; |
"$name-$version-1.i386.rpm $invokingdir/."; |
print `$command`; |
print(`$command`); |
|
|
# --------------------------------------------------------- clean everything up |
# --------------------------------------------------------- clean everything up |
|
print('Removing temporary ./'.$tag.' directory'."\n"); |
|
print(`cd $invokingdir; rm -Rf $tag`); |
|
|
print `cd $invokingdir; rm -Rf $tag`; |
# -------------------------------------------------------- Yeah! We're all done |
|
print('Success. Script complete.'."\n"); |
|
|
# ----------------------------------------------------------------- SUBROUTINES |
# ----------------------------------------------------------------- SUBROUTINES |
# ----- Subroutine: find_info - recursively gather information from a directory |
# ----- Subroutine: find_info - recursively gather information from a directory |
sub find_info { |
sub find_info { |
my ($file)=@_; |
my ($file)=@_; |
my $line; |
my $line=''; |
if (($line=`find $file -type f -prune`)=~/^$file\n/) { |
if (($line=`find $file -type f -prune`)=~/^$file\n/) { |
$line=`find $file -type f -prune -printf "\%s\t\%m\t\%u\t\%g"`; |
$line=`find $file -type f -prune -printf "\%s\t\%m\t\%u\t\%g"`; |
return ("files",split(/\t/,$line)); |
return("files",split(/\t/,$line)); |
} |
} |
elsif (($line=`find $file -type d -prune`)=~/^$file\n/) { |
elsif (($line=`find $file -type d -prune`)=~/^$file\n/) { |
$line=`find $file -type d -prune -printf "\%s\t\%m\t\%u\t\%g"`; |
$line=`find $file -type d -prune -printf "\%s\t\%m\t\%u\t\%g"`; |
return ("directories",split(/\t/,$line)); |
return("directories",split(/\t/,$line)); |
} |
} |
elsif (($line=`find $file -type l -prune`)=~/^$file\n/) { |
elsif (($line=`find $file -type l -prune`)=~/^$file\n/) { |
$line=`find $file -type l -prune -printf "\%l\t\%m\t\%u\t\%g"`; |
$line=`find $file -type l -prune -printf "\%l\t\%m\t\%u\t\%g"`; |
return ("links",split(/\t/,$line)); |
return("links",split(/\t/,$line)); |
} |
} |
die("**** ERROR **** $file is neither a directory, soft link, or file"); |
die("**** ERROR **** $file is neither a directory, soft link, or file.\n"); |
} |
} |
|
|
# ------------------------- Subroutine: grabtag - grab a tag from an xml string |
# ------------------------- Subroutine: grabtag - grab a tag from an xml string |
sub grabtag { |
sub grabtag { |
my ($tag,$text,$clean)=@_; |
my ($tag,$text,$clean)=@_; |
# meant to be quick and dirty as opposed to a formal state machine parser |
# meant to be quick and dirty as opposed to a formal state machine parser |
my $value; |
my $value=''; |
$cu=~/\<$tag\>(.*?)\<\/$tag\>/s; |
$cu=~/\<$tag\>(.*?)\<\/$tag\>/s; |
$value=$1; $value=~s/^\s+//; |
$value=$1; $value=~s/^\s+//; |
if ($clean) { |
if ($clean==1) { |
$value=~s/\n\s/ /g; |
$value=~s/\n\s/ /g; |
$value=~s/\s\n/ /g; |
$value=~s/\s\n/ /g; |
$value=~s/\n/ /g; |
$value=~s/\n/ /g; |
$value=~s/\s+$//; |
$value=~s/\s+$//; |
} |
} |
return $value; |
return($value); |
} |
} |
|
|
# ----------------------------------------------------- Plain Old Documentation |
# ----------------------------------------------------- Plain Old Documentation |
|
|
=head1 NAME |
=head1 NAME |
|
|
make_rpm.pl - automatically generate an RPM software package |
make_rpm.pl - cleanly generate an rpm in a simple one-line command |
|
|
=head1 SYNOPSIS |
=head1 SYNOPSIS |
|
|
Usage: <TAG> <VERSION> [CONFIGURATION_FILES] |
Usage: <STDIN> | make_rpm.pl <TAG> <VERSION> |
[DOCUMENTATION_FILES] [PATHPREFIX] [CUSTOMIZATION_XML] |
[CONFIGURATION_FILES] [DOCUMENTATION_FILES] |
|
[PATHPREFIX] [CUSTOMIZATION_XML] |
|
|
|
=head2 The standard input stream |
|
|
|
I<STDIN>, the standard input stream, provides the list of files to work |
|
with. This list of file names must give the complete filesystem |
|
path starting from '/'. |
|
|
Standard input provides the list of files to work with. |
=over 4 |
|
|
TAG, required descriptive tag. For example, a kerberos software |
=item * For instance, the following is invalid: |
|
|
|
romeodir/file1.txt # ** INVALID! ** missing leading filesystem path |
|
romeodir/file2.txt |
|
romeodir/file3.txt |
|
|
|
=item * Whereas, the following is valid: |
|
|
|
/home/joe/romeodir/file1.txt |
|
/home/joe/romeodir/file2.txt |
|
/home/joe/romeodir/file3.txt |
|
|
|
=item * In terms of the B<find> command, |
|
|
|
"find romeodir | perl make_rpm.pl [COMMAND-LINE ARGUMENTS]" |
|
|
|
is incorrect, whereas |
|
|
|
"find /home/joe/romeodir |perl make_rpm.pl [COMMAND-LINE ARGUMENTS]" |
|
|
|
or |
|
|
|
"find `pwd`/romeodir |perl make_rpm.pl [COMMAND-LINE ARGUMENTS]" |
|
|
|
is correct. |
|
|
|
=back |
|
|
|
The standard input stream can also |
|
specify configuration files and documentation files through |
|
'#'-style commenting. |
|
|
|
For example, the following file listing encodes some of these directives: |
|
|
|
/home/joe/romeodir/buildloc/etc/romeo/user.conf # config(noreplace) |
|
/home/joe/romeodir/buildloc/etc/romeo/juliet.conf # config |
|
/home/joe/romeodir/buildloc/doc/man/man.1/romeo.1 # doc |
|
/home/joe/romeodir/buildloc/doc/man/man.1/romeo_talks.1 # doc |
|
/home/joe/romeodir/buildloc/usr/local/bin/where_art_thou |
|
/home/joe/romeodir/buildloc/usr/local/bin/romeo_talks |
|
|
|
The I<config> directive controls how files are replaced |
|
and/or backed up when a user attempts to install (B<rpm -i>) the F<.rpm> |
|
file generated by B<make_rpm.pl>. The I<doc> directive controls how a |
|
given file is placed inside special documentation directories |
|
on the filesystem during rpm installation (B<rpm -i>). |
|
(If you want to learn more on how the B<rpm> tool gives configuration and |
|
documentation files special treatment, you should read about "Directives" |
|
in Edward Bailey's well-known "Maximum RPM" book available online |
|
at http://www.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html.) |
|
|
|
=head2 Description of command-line arguments |
|
|
|
I<TAG> ($tag), B<required> descriptive tag. For example, a kerberos software |
package might be tagged as "krb4". |
package might be tagged as "krb4". |
|
|
VERSION, required version. Needed to generate version information |
I<VERSION> ($version), B<required> version. Needed to generate version |
for the RPM. This should be in the format N.M where N and M are |
information for the RPM. This should be in the format N.M where N and M are |
integers. |
integers. |
|
|
CONFIGURATION_FILES, optional comma-separated listing of files to |
I<CONFIGURATION_FILES>, B<optional> comma-separated listing of files to |
be treated as configuration files by RPM (and thus subject to saving |
be treated as configuration files by RPM (and thus subject to saving |
during RPM upgrades). |
during RPM upgrades). Configuration files can also be specified in |
|
the standard input stream (as described in L<"The standard input stream">). |
|
|
DOCUMENTATION_FILES, optional comma-separated listing of files to be |
I<DOCUMENTATION_FILES>, B<optional> comma-separated listing of files to be |
treated as documentation files by RPM (and thus subject to being |
treated as documentation files by RPM (and thus subject to being |
placed in the /usr/doc/RPM-NAME directory during RPM installation). |
placed in the F</usr/doc/RPM-NAME> directory during RPM installation). |
|
Documentation files can also be specified in |
|
the standard input stream (as described in L<"The standard input stream">). |
|
|
PATHPREFIX, optional path to be removed from file listing. This |
I<PATHPREFIX>, B<optional> path to be removed from file listing. This |
is in case you are building an RPM from files elsewhere than |
is in case you are building an RPM from files elsewhere than |
root-level. Note, this still depends on a root directory hierarchy |
root-level. Note, this still depends on a root directory hierarchy |
after PATHPREFIX. |
after PATHPREFIX. |
|
|
CUSTOMIZATION_XML, allows for customizing various pieces of information such |
I<CUSTOMIZATION_XML>, B<optional> filename where XML-ish information exists. |
|
Allows for customizing various pieces of information such |
as vendor, summary, name, copyright, group, autoreqprov, requires, prereq, |
as vendor, summary, name, copyright, group, autoreqprov, requires, prereq, |
description, and pre-installation scripts (see more in the POD; |
description, and pre-installation scripts |
perldoc make_rpml.pl). |
(see L<"Customizing descriptive data of your RPM software package">). |
|
|
Examples: |
=head2 Examples |
|
|
[prompt] find notreallyrootdir | perl make_rpm.pl makemoney 3.1 '' \ |
bash$ find /notreallyrootdir | perl make_rpm.pl \ |
'/usr/doc/man/man3/makemoney.3' notreallyrootdir |
makemoney 3.1 '' \ |
|
'/usr/doc/man/man3/makemoney.3' \ |
|
/notreallyrootdir |
would generate makemoney-3.1-1.i386.rpm |
would generate makemoney-3.1-1.i386.rpm |
|
|
[prompt] find /usr/local/bin | perl make_rpm.pl mybinfiles 1.0 |
bash$ find /usr/local/bin | \ |
|
perl make_rpm.pl mybinfiles 1.0 |
would generate mybinfiles-1.0-1.i386.rpm |
would generate mybinfiles-1.0-1.i386.rpm |
|
|
[prompt] find romeo | perl make_rpm.pl romeo 1.0 '' '' '' customize.xml |
bash$ find /home/joe/romeodir/buildloc | \ |
|
perl make_rpm.pl romeo \ |
|
1.0 '' '' '/home/joe/romeodir/buildloc' customize.xml |
would generate romeo with customizations from customize.xml. |
would generate romeo with customizations from customize.xml. |
|
|
The CUSTOMIZATION_XML argument represents a way to customize the |
The I<CUSTOMIZATION_XML> argument represents a way to customize the |
numerous variables associated with RPMs. This argument represents |
numerous variables associated with RPMs. This argument represents |
a file name. (Parsing is done in an unsophisticated fashion using |
a file name. (Parsing is done in an unsophisticated fashion using |
regular expressions.) Here are example contents of such a file: |
regular expressions.) See |
|
L<"Customizing descriptive data of your RPM software package">. |
|
|
|
=head1 Customizing descriptive data of your RPM software package |
|
|
|
RPMS can be (and often are) packaged with descriptive data |
|
describing authorship, dependencies, descriptions, etc. |
|
|
|
The following values can be tagged inside an XML file |
|
(specified by the 6th command-line argument) |
|
and made part of the RPM package information |
|
(B<rpm -qi E<lt>package-nameE<gt>>). |
|
|
|
=over 4 |
|
|
|
=item * vendor |
|
|
|
=item * summary |
|
|
|
=item * name |
|
|
|
(overrides the <TAG> argument value; see |
|
L<"Description of command-line arguments>) |
|
|
|
=item * copyright |
|
|
|
=item * group |
|
|
|
(the software package group; |
|
e.g. Applications/System, User Interface/X, Development/Libraries, |
|
etc.) |
|
|
|
=item * requires |
|
|
|
Contains all the dependency information (see the example below). |
|
|
|
=item * description |
|
|
|
=item * pre |
|
|
|
Commands to be executed prior to software package installation. |
|
|
|
=back |
|
|
|
Here is an example (note that B<make_rpm.pl> automatically substitutes |
|
any "<tag />" string with the first command-line argument described |
|
in L<"Description of command-line arguments">): |
|
|
<vendor> |
<vendor> |
Laboratory for Instructional Technology Education, Division of |
Laboratory for Instructional Technology Education, Division of |
Line 474 regular expressions.) Here are example
|
Line 637 regular expressions.) Here are example
|
For more on the LON-CAPA project, visit http://www.lon-capa.org/. |
For more on the LON-CAPA project, visit http://www.lon-capa.org/. |
</description> |
</description> |
<pre> |
<pre> |
echo "***********************************************************************" |
echo "************************************************************" |
echo "LON-CAPA LearningOnline with CAPA" |
echo "LON-CAPA LearningOnline with CAPA" |
echo "http://www.lon-capa.org/" |
echo "http://www.lon-capa.org/" |
echo " " |
echo " " |
Line 485 regular expressions.) Here are example
|
Line 648 regular expressions.) Here are example
|
echo " " |
echo " " |
echo "This installation assumes an installation of Redhat 6.2" |
echo "This installation assumes an installation of Redhat 6.2" |
echo " " |
echo " " |
echo "The server computer should be currently connected to the ethernet" |
echo "The files in this package are for the <tag /> component." |
echo " " |
echo "***********************************************************" |
echo "The files in this package are only those for the <tag /> component." |
|
echo "Configuration files are sometimes part of the LON-CAPA-base RPM." |
|
echo "***********************************************************************" |
|
</pre> |
</pre> |
|
|
=head1 DESCRIPTION |
=head1 DESCRIPTION |
|
|
Automatically generate an RPM software package from a list of files. |
Automatically generate an RPM software package from a list of files. |
|
|
This script builds the RPM in a very clean and configurable fashion. |
B<make_rpm.pl> builds the RPM in a very clean and configurable fashion. |
(Finally! Making RPMs outside of /usr/src/redhat without a zillion |
(Finally! Making RPMs outside of F</usr/src/redhat> without a zillion |
file intermediates left over!) |
file intermediates left over!) |
|
|
This script generates and then deletes temporary |
B<make_rpm.pl> generates and then deletes temporary |
files needed to build an RPM with. |
files needed to build an RPM with. |
It works cleanly and independently from pre-existing |
It works cleanly and independently from pre-existing |
directory trees such as /usr/src/redhat/*. |
directory trees such as F</usr/src/redhat/*>. |
|
|
The script is also simple. It accepts four kinds of information, |
Input to the script is simple. B<make_rpm.pl> accepts five kinds of |
two of which are mandatory: |
information, three of which are mandatory: |
|
|
=over 4 |
=over 4 |
|
|
=item * |
=item * |
|
|
a list of files that are to be part of the software package; |
(required) a list of files that are to be part of the software package; |
|
|
=item * |
=item * |
|
|
|
(required) the absolute filesystem location of these files |
|
(see L<"The standard input stream">); |
|
|
|
=item * |
|
|
the location of these files; |
(required) a descriptive tag and a version tag for the naming of the |
|
RPM software package; |
|
|
=item * |
=item * |
|
|
(optional) a descriptive tag and a version tag; |
(optional) documentation and configuration files; |
|
|
=item * |
=item * |
|
|
Line 529 associated with the RPM software package
|
Line 695 associated with the RPM software package
|
|
|
=back |
=back |
|
|
The following items are initially and temporarily generated during the |
A temporary directory named $tag (first argument described in |
construction of an RPM: |
L<"Description of command-line arguments">) is |
|
|
|
=over 4 |
|
|
|
=item * |
|
|
|
generated under the directory from which you run B<make_rpm.pl>. |
|
|
|
For example, user "joe" running |
|
|
|
cat file_list.txt | make_rpm.pl krb4 1.0 |
|
|
|
would temporarily generate F</home/joe/krb4/>. |
|
|
|
=item * |
|
|
|
F</home/joe/krb4/> is deleted after the *.rpm |
|
file is generated. |
|
|
|
=back |
|
|
|
The RPM will typically be named $name-$version.i386.rpm |
|
where $name=$tag. (The $name can be overridden in the customization |
|
XML file; see |
|
L<"Customizing descriptive data of your RPM software package">.) |
|
|
|
Here are some of the items are generated inside |
|
the $tag directory during the construction of an RPM: |
|
|
|
=over 4 |
|
|
|
=item * |
|
|
|
RPM .spec file (F<./$tag/SPECS/$name-$version.spec>) |
|
|
|
=item * |
|
|
|
RPM Makefile (F<./$tag/SOURCES/$name-$version/Makefile>) |
|
|
|
This is the Makefile that is called by the rpm |
|
command in building the .i386.rpm from the .src.rpm. |
|
The following directories are generated and/or used: |
|
|
=over 4 |
=over 4 |
|
|
=item * |
=item * |
|
|
RPM .spec file |
SOURCE directory: F<./$tag/BinaryRoot/> |
|
|
|
=item * |
|
|
|
TARGET directory: F<./$tag/BuildRoot/> |
|
|
|
=back |
|
|
|
=item * |
|
|
|
BinaryRootMakefile (F<./$tag/BinaryRootMakefile>) |
|
|
|
This is the Makefile that this script creates and calls |
|
to build the F<$tag/BinaryRoot/> directory from the existing |
|
filesystem. |
|
The following directories are generated and/or used: |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
RPM Makefile |
SOURCE directory: / (your entire filesystem) |
|
|
=item * |
=item * |
|
|
SourceRoot |
TARGET directory: F<./$tag/BinaryRoot/> |
|
|
=back |
=back |
|
|
A resulting .rpm file is generated. |
=back |
|
|
|
The final output of B<make_rpm.pl> is a binary F<.rpm> file. |
|
The F<./tag> directory is deleted (along with the F<.src.rpm> |
|
file). The typical file name generated by B<make_rpm.pl> is |
|
F<$tag-$version.i386.rpm>. |
|
|
make_rpm.pl is compatible with both rpm version 3.* and rpm version 4.*. |
B<make_rpm.pl> is compatible with either rpm version 3.* or rpm version 4.*. |
|
|
=head1 README |
=head1 README |
|
|
Automatically generate an RPM software package from a list of files. |
Automatically generate an RPM software package from a list of files. |
|
|
This script builds the RPM in a very clean and configurable fashion. |
B<make_rpm.pl> builds the RPM in a very clean and configurable fashion. |
(Making RPMs the simple and right way!) |
(Making RPMs "the simple way" in a one-line command.) |
|
|
This script generates and then deletes temporary |
B<make_rpm.pl> generates and then deletes temporary |
files (and binary root directory tree) to build an RPM with. |
files (and binary root directory tree) to build an RPM with. |
It is designed to work cleanly and independently from pre-existing |
It is designed to work cleanly and independently from pre-existing |
directory trees such as /usr/src/redhat/*. |
directory trees such as /usr/src/redhat/*. |
Line 568 directory trees such as /usr/src/redhat/
|
Line 797 directory trees such as /usr/src/redhat/
|
|
|
This script requires the C<strict> module. |
This script requires the C<strict> module. |
|
|
=pod OSNAMES |
=head1 AUTHOR |
|
|
|
Scott Harrison |
|
harris41@msu.edu |
|
|
|
Please let me know how/if you are finding this script useful and |
|
any/all suggestions. -Scott |
|
|
|
=head1 LICENSE |
|
|
|
Written by Scott Harrison, harris41@msu.edu |
|
|
|
Copyright Michigan State University Board of Trustees |
|
|
|
This file is part of the LearningOnline Network with CAPA (LON-CAPA). |
|
|
|
This is free software; you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation; either version 2 of the License, or |
|
(at your option) any later version. |
|
|
|
This file is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
The GNU Public License is available for review at |
|
http://www.gnu.org/copyleft/gpl.html. |
|
|
|
For information on the LON-CAPA project, please visit |
|
http://www.lon-capa.org/. |
|
|
|
=head1 OSNAMES |
|
|
Linux |
Linux |
|
|
=pod SCRIPT CATEGORIES |
=head1 SCRIPT CATEGORIES |
|
|
UNIX/System Administration |
UNIX/System Administration |
|
|
=cut |
=cut |
|
|