=head1 NAME How2 - create a PPM distribution - 0.2 =head1 DESCRIPTION This is to give you some information on how to make a PPM distribution. This is an unofficial document based on my own findings and suggestions from the mailing list. =head2 PPD The .ppd file may be generated by : perl Makefile.PL nmake ppd or nmake ppd BINARY_LOCATION=Module.tar.gz If you use the first, you'll have to edit the resulting .ppd and add the name of the archive into (The HREF should be relative to the location of the ppd file.) You should specify the AUTHOR and ABSTRACT parameters in the Makefile.PL so that they are present in the ppd and may be searched through! Be forewarned though that these parameters were added only in 5.005 so older perls will not like them. You should pass them to WriteMakefile only if the ($] ge '5.005'). =head2 Example Makefile.PL Deurl.pm\Makefile.PL : =========================== use ExtUtils::MakeMaker; WriteMakefile( 'NAME' =? 'Deurl', 'VERSION_FROM' =? 'Deurl.pm', # finds $VERSION ($] ge '5.005') ? ( 'AUTHOR' =? 'Jan Krynicky (Jenda@Krynicky.cz)', 'ABSTRACT' =? 'Decode the parameters passed to a CGI', ) : (), ); =========================== or =========================== use ExtUtils::MakeMaker; @if5005 = ( 'AUTHOR' => 'Jan Krynicky (Jenda@Krynicky.cz)', 'ABSTRACT' => 'Ask for HTTP authentification unless condition holds', ) if $] ge '5.005'; WriteMakefile( 'NAME' => 'Authent', 'VERSION_FROM' => 'Authent.pm', # finds $VERSION 'NEEDS_LINKING' => 0, 'dist' => {COMPRESS => 'gzip -9f', SUFFIX => 'gz'}, @if5005 ); =========================== =head2 Archive The archive referenced in .ppd should contain the blib directory that's created when you run perl Makefile.PL nmake Of course you may use dmake or standard make, but if you do you have to change the settings in ...\perl\lib\Config.pm. Search for line make='nmake' and change it to make='make' or make='dmake' You may get nmake from ftp://ftp.microsoft.com/Softlib/MSLFILES/nmake15.exe . You should also create a directory ...\blib\html\lib\ and place the HTML documentation for the module there. For example for Mail::Sender I generate Sender.html by pod2html.bat and save it as ...\blib\html\lib\Mail\Sender.html. This way the documentation will be linked from the module list in ...\perl\html\perltoc.html The blib directory should then be compressed using tar and gzip. I do include the version number in the name, ActiveState doesn't, it's up to you. Just keep in mind that the .ppd file MUST contain correct archive name! The archive may be created by tar cvf ArchiveName.tar blib gzip --best ArchiveName.tar You can get tar and gzip for example from http://www.itribe.net/virtunix/ =head2 Repository To set up a PPM repository all you have to do is to copy the .ppd files and .tar.gz archives to a webserver and enable directory listing to the directory where are the ppd files. You may have both .ppd files and the archives in the same directory (then the is just the archive name) or in a different directory (then the is the relative URL of the archive). If you want to set it up for VPM (Visual Package Manager) as well you need to get default.prk from ActiveState, set it up to be executed as a perl script and save it in the same directory where are the .ppd files. If you do not want to create your own repository you may send the .ppd and .tar.gz to me and I'll add it to my repository. =head2 My way I use the script below to generate both ordinary distributions and PPM distributions at once. This process creates three files : ModuleName-version.tar.gz = ordinary distro ModuleName.ppd = the ppd description file ModuleName-version-PPM.tar.gz = the archive for PPM If you add line with PPM_BINDIR='something' into ...\perl\lib\Config.pm, or to system varibles, it will be used as the directory where you store the archives. For example if you have the ppd files in http://www.yoursite.com/packages/ and the archives in http://www.yoursite.com/packages/x86, the variable should contain 'x86'. =head2 Makeppd.pl #makeppd.pl 2.0 use FileHandle; use File::DosGlob qw(glob); use Win32::FileOp; $make='nmake.exe'; END {print "\nDONE -- PRESS ENTER\n";}; my $has_xs = 0; #unixify files { opendir my $DIR, '.' or die "Can't read current directory: $!\n"; my $file ; while (defined($file = readdir $DIR)) { $has_xs = 1 if $file =~ /\.xs$/i; next unless $file =~ /\.(?:pm|pl|xs|t|html|htm|txt)$/i or $file =~ /^(?:MANIFEST|Changes)$/i; open my $FILE, "<".$file or die "Can't open file $file : $!\n"; binmode $FILE; my $line = <$FILE>; # next unless $line =~ /\r/; open my $OUT, ">".$file.".tmp" or die "Can't create file $file.tmp : $!\n"; binmode $OUT; while (defined $line) { $line =~ s/\r?\n?$//; print $OUT $line,"\x0A"; $line = <$FILE> } close $FILE; close $OUT; unlink $file; rename $file.'.tmp' => $file; } } system('perl Makefile.PL'); system($make) and die "Failed to make!\n"; system($make, 'dist'); # this creates the ordinary distribution # I need the archive to find the version number! # If you comment this out, always copy the archive to current directory. # this part of code finds the latest distribution, I don't have time to # explore how to find the version number @archives = grep {!/-PPM\.tar\.gz$/i} <*.tar.gz>; $archive = findNewest (@archives); ($name = $archive) =~ s/\.tar\.gz$//; ($module = $name) =~ s/-[\d.]+$//; ($file = $module) =~ s/^.*-(.*?)$/$1/; $ppd = $module.".ppd"; $module =~ s/-/\\/g; print "Module name : $file\n"; print "Newest archive is $archive\n"; system('perl','Makefile.PL', "BINARY_LOCATION=$name-PPM.tar.gz"); system($make, 'ppd'); # you may do something like # system($make, 'ppd', "BINARY_LOCATION=$name-PPM.tar.gz"); # if you do not apply my patch to ExtUtils\MM_Unix.pm print (qq{pod2html.bat "-htmlroot=." "$file.pm" "-outfile=$file.html"\n}); system(qq{pod2html.bat "-htmlroot=." "$file.pm" "-outfile=$file.html"}); #mkdir 'blib/html'; # not necessary Copy "$file.html" => "$file.pm.html"; Move "$file.html" => "blib/html/site/lib/$module.html"; system(qq{pod2text.bat "$file.pm" "$file.pm.txt"}); system("tar cvf $name-PPM.tar blib"); system("gzip --best $name-PPM.tar"); Delete qw(blib pod2html-dircache pod2html-itemcache pm_to_blib pod2htmd.x~~ pod2htmi.x~~); if (! $has_xs) { open $PPD, "<$ppd" or die "Can't open the $ppd file: $!\n"; open $NEWPPD, ">$ppd.tmp" or die "Can't create the $ppd.tmp file: $!\n"; while (<$PPD>) { next if (/ $ppd; } exit; #================== sub findNewest { my $maxitem; my $maxver = pack('C4',0,0,0,0); foreach my $item (@_) { $item =~ /-(\d+)\.(\d+)\.(?:(\d+)\.(?:(\d+)\.)?)?tar\.gz/; my $ver = pack('C4',$1,$2,$3,$4); if ($ver gt $maxver) { $maxver = $ver; $maxitem = $item; } } return $maxitem; } =head1 AUTHOR "Jan Krynicky" =head1 COPYRIGHT Copyright (c) 2002 "Jan Krynicky" . All rights reserved. =cut