https://wiki.archlinux.org/api.php?action=feedcontributions&user=Juster&feedformat=atomArchWiki - User contributions [en]2024-03-28T13:01:08ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=Talk:Smokeping&diff=372228Talk:Smokeping2015-05-02T20:40:44Z<p>Juster: </p>
<hr />
<div>== Installation using the Arch Linux package ==<br />
<br />
I propose to update the last section of the [smokeping] wiki page such that it discusses how to set it up using the {{Pkg|smokeping}} package instead of another installation from source. I believe the former to be more relevant to ArchLinux. I've mostly just updated the paths. Here's what I propose it should look like:<br />
<br />
=== Setup using the {{Pkg|smokeping}} package with FastCGI in Apache ===<br />
It is possible to trade off runtime speed for setup simplicity using the method described below.<br />
Instead of using PSGI, we setup FastCGI as described in [https://wiki.archlinux.org/index.php/Apache_and_FastCGI].<br />
<br />
The smokeping package consists of two parts:<br />
* The smokeping daemon and configs in {{ic|/etc/smokeping/}}<br />
* The smokeping "htdocs" in {{ic|/srv/http/smokeping}}<br />
<br />
In addition, you will need:<br />
* an image cache directory that the FastCGI script can write to, e.g. {{ic|/srv/smokeping/imgcache}}<br />
* a data directory that the smokeping daemon can write to, and the FastCGI script can read, e.g. {{ic|/srv/smokeping/data}}<br />
* to ensure that the main config file is readable by the smokeping daemon.<br />
<br />
1. Install {{Pkg|smokeping}}, {{Pkg|fping}}, {{Pkg|apache}} and {{Pkg|mod_fastcgi}}<br />
# pacman -S smokeping apache mod_fastcgi fping<br />
2. We remove {{ic|.dist}} from the config files in {{ic|/etc/smokeping}}:<br />
# cd /etc/smokeping<br />
# find . -name '*.dist' -print -execdir sh -c 'mv {} $(basename {} .dist)' \;<br />
# sudo mv /srv/http/smokeping/smokeping.fcgi.dist /srv/http/smokeping/smokeping.fcgi<br />
3. We edit the config file as described above, so that the {{ic|/etc/smokeping/config}} file looks something like this:<br />
{{hc|/etc/smokeping/config|2=<nowiki><br />
*** General ***<br />
<br />
owner = Your Name Here # your name<br />
contact = your.email@host.bla # your email<br />
mailhost = your.smtp.server.bla # your mail server<br />
sendmail = /bin/false # where the sendmail program is<br />
imgcache = /srv/smokeping/imgcache # filesystem directory where we store files<br />
imgurl = imgcache # URL directory to find them<br />
datadir = /srv/smokeping/data # where we share data between the daemon and webapp<br />
piddir = /var/run # filesystem directory to store PID file<br />
cgiurl = http://localhost/smokeping/smokeping.cgi # exterior URL<br />
smokemail = /etc/smokeping/smokemail <br />
tmail = /etc/smokeping/tmail<br />
syslogfacility = local0<br />
# each probe is now run in its own process<br />
# disable this to revert to the old behaviour<br />
# concurrentprobes = no<br />
<br />
*** Database ***<br />
<br />
step = 300<br />
pings = 20<br />
<br />
# consfn mrhb steps total<br />
<br />
AVERAGE 0.5 1 1008<br />
AVERAGE 0.5 12 4320<br />
MIN 0.5 12 4320<br />
MAX 0.5 12 4320<br />
AVERAGE 0.5 144 720<br />
MAX 0.5 144 720<br />
MIN 0.5 144 720<br />
<br />
*** Presentation ***<br />
<br />
template = /etc/smokeping/basepage.html<br />
<br />
+ charts<br />
<br />
menu = Charts<br />
title = The most interesting destinations<br />
++ stddev<br />
sorter = StdDev(entries=>4)<br />
title = Top Standard Deviation<br />
menu = Std Deviation<br />
format = Standard Deviation %f<br />
<br />
++ max<br />
sorter = Max(entries=>5)<br />
title = Top Max Roundtrip Time<br />
menu = by Max<br />
format = Max Roundtrip Time %f seconds<br />
<br />
++ loss<br />
sorter = Loss(entries=>5)<br />
title = Top Packet Loss<br />
menu = Loss<br />
format = Packets Lost %f<br />
<br />
++ median<br />
sorter = Median(entries=>5)<br />
title = Top Median Roundtrip Time<br />
menu = by Median<br />
format = Median RTT %f seconds<br />
<br />
+ overview <br />
<br />
width = 600<br />
height = 50<br />
range = 10h<br />
<br />
+ detail<br />
<br />
width = 600<br />
height = 200<br />
unison_tolerance = 2<br />
<br />
"Last 3 Hours" 3h<br />
"Last 30 Hours" 30h<br />
"Last 10 Days" 10d<br />
"Last 400 Days" 400d<br />
<br />
*** Probes ***<br />
<br />
+ FPing<br />
<br />
binary = /usr/sbin/fping<br />
<br />
<br />
*** Targets ***<br />
<br />
probe = FPing<br />
<br />
menu = Top<br />
title = Network Latency Grapher<br />
remark = Welcome to the SmokePing website of Arch User. \<br />
Here you will learn all about the latency of our network.<br />
<br />
+ targets<br />
menu = Targets<br />
<br />
++ Server<br />
<br />
menu = Arch Linux<br />
title = Arch Linux Website<br />
host = 66.211.214.131<br />
<br />
++ MultiHost<br />
<br />
menu = Multihost<br />
title = Arch Wiki and Kernel.org<br />
host = 5.9.250.164 149.20.4.69<br />
<br />
</nowiki>}}<br />
<br />
{{Note|If we use smokeping_secrets we will have to make it unreadable to the rest, or else smokeping will eror: {{ic|chmod 600 /etc/smokeping/smokeping_secrets}}.}}<br />
4. Now setup the extra directories:<br />
# mkdir -p /srv/smokeping/data<br />
# mkdir -p /srv/smokeping/imgcache<br />
# chown -R smokeping:smokeping /srv/smokeping<br />
# chown -R http:http /srv/smokeping/imgcache<br />
# chmod a+rx /srv/smokeping<br />
# chmod -R a+rx /srv/smokeping/data<br />
<br />
5. The Smokeping configuration is read by both the smokeping daemon and the FastCGI scripts, so it needs to be readable:<br />
# chmod a+rx /etc/smokeping<br />
# chmod a+r /etc/smokeping/config<br />
<br />
6. Start smokeping<br />
# systemctl start smokeping<br />
<br />
7. We edit /etc/httpd/conf/httpd.conf so it includes<br />
{{hc|/etc/httpd/conf/httpd.conf|2=<nowiki><br />
LoadModule fastcgi_module modules/mod_fastcgi.so<br />
<IfModule fastcgi_module><br />
AddHandler fastcgi-script .fcgi # you can put whatever extension you want<br />
</IfModule><br />
#FastCgiConfig -idle-timeout 90 # try this if you hit errors about the scripts exceeding the idle timeout.<br />
ScriptAlias /smokeping/smokeping.cgi /srv/http/smokeping.fcgi<br />
<br />
Alias /smokeping/imgcache /srv/smokeping/imgcache<br />
Alias /smokeping /srv/http/smokeping<br />
<br />
<Directory "/srv/smokeping/imgcache"><br />
AllowOverride all<br />
Order Deny,Allow<br />
Allow from all<br />
Require all granted<br />
</Directory><br />
<br />
<Directory "/srv/http/smokeping"><br />
Options FollowSymLinks ExecCGI<br />
AllowOverride all<br />
Order Deny,Allow<br />
Allow from all<br />
Require all granted<br />
</Directory><br />
</nowiki>}}<br />
<br />
8. Start Apache:<br />
systemctl start httpd<br />
<br />
9. Wait a few minutes and check the first data at {{ic|http://localhost/smokeping/smokeping.cgi}}<br />
<br />
[[User:M01|M01]] ([[User talk:M01|talk]]) 22:02, 16 March 2015 (UTC)<br />
<br />
:Hello, well done! I suppose you can change the wiki since it works for you. When I get some time (hopefully within 2015 :)) I'll try it in a container to check it works fine with a fresh Arch install.<br />
:[[User:Costis|Costis]] ([[User talk:Costis|talk]]) 18:41, 22 March 2015 (UTC)<br />
<br />
:: Thank you for the feedback! I've now tested the instructions in an Arch Linux Vagrant box just to be sure.<br />
:: [[User:M01|M01]] ([[User talk:M01|talk]]) 08:21, 7 April 2015 (UTC)<br />
<br />
No you shouldn't add a new section. You should rewrite the entire page :). What I wrote was for an old version of smokeping. When I wrote this, smokeping was not designed to use FastCGI. Most of what I wrote is no longer applicable.<br />
<br />
My advice is to burn it down and rebuild it. Remove everything that doesn't use Apache and FastCGI. You're right, it's too complicated. Simplify it. Make sure older sections do not refer to other old or missing sections. You don't have to limit yourself to a new section to protect other peoples' feelings. Not mine anyways.<br />
<br />
[[User:Juster|Juster]] ([[User talk:Juster|talk]]) 21:11, 22 March 2015 (UTC)<br />
<br />
: I just replaced the last section, but only now noticed your comment here! Not sure how I missed it, I'm watching both the page and the talk page. Anyway:<br />
<br />
: Thanks for explaining that, I suspected that was the case but wasn't sure if FastCGI would be faster or slower than PSGI, so I didn't really dare to touch it in case it was still the superior solution. On my Raspberry Pi FastCGI is pretty slow, but in the Vagrant box where I just tested the new instructions it's pretty speedy. I'll rewrite the wiki page. Thank you for the encouragement!<br />
<br />
:[[User:M01|M01]] ([[User talk:M01|talk]]) 08:21, 7 April 2015 (UTC)<br />
<br />
: I followed your advice and rebuilt the page! [[User:M01|M01]] ([[User talk:M01|talk]]) 12:06, 2 May 2015 (UTC)<br />
<br />
: Looking good! [[User:Juster|Juster]] ([[User talk:Juster|talk]]) 20:40, 2 May 2015 (UTC)</div>Justerhttps://wiki.archlinux.org/index.php?title=Talk:Smokeping&diff=366779Talk:Smokeping2015-03-22T21:11:50Z<p>Juster: </p>
<hr />
<div>== Installation using the Arch Linux package ==<br />
<br />
I propose to update the last section of the [smokeping] wiki page such that it discusses how to set it up using the {{Pkg|smokeping}} package instead of another installation from source. I believe the former to be more relevant to ArchLinux. I've mostly just updated the paths. Here's what I propose it should look like:<br />
<br />
=== Setup using the {{Pkg|smokeping}} package with FastCGI in Apache ===<br />
It is possible to trade off runtime speed for setup simplicity using the method described below.<br />
Instead of using PSGI, we setup FastCGI as described in [https://wiki.archlinux.org/index.php/Apache_and_FastCGI].<br />
<br />
The smokeping package consists of two parts:<br />
* The smokeping daemon and configs in {{ic|/etc/smokeping/}}<br />
* The smokeping "htdocs" in {{ic|/srv/http/smokeping}}<br />
<br />
In addition, you will need:<br />
* an image cache directory that the FastCGI script can write to, e.g. {{ic|/srv/smokeping/imgcache}}<br />
* a data directory that the smokeping daemon can write to, and the FastCGI script can read, e.g. {{ic|/srv/smokeping/data}}<br />
* to ensure that the main config file is readable by the smokeping daemon.<br />
<br />
1. Install {{Pkg|smokeping}}, {{Pkg|apache}} and {{Pkg|mod_fastcgi}}<br />
pacman -S smokeping apache mod_fastcgi<br />
2. We remove {{ic|.dist}} from the config files in {{ic|/etc/smokeping}}:<br />
cd /etc/smokeping<br />
find . -name '*.dist' -print -execdir sh -c 'mv {} $(basename {} .dist)' \;<br />
3. We edit the config file as described above, so that the {{ic|/etc/smokeping/config}} file looks something like this:<br />
{{hc|/etc/smokeping/config|2=<nowiki><br />
*** General ***<br />
<br />
owner = Your Name Here # your name<br />
contact = your.email@host.bla # your email<br />
mailhost = your.smtp.server.bla # your mail server<br />
sendmail = /bin/false # where the sendmail program is<br />
imgcache = /srv/smokeping/imgcache # filesystem directory where we store files<br />
imgurl = imgcache # URL directory to find them<br />
datadir = /srv/smokeping/data # where we share data between the daemon and webapp<br />
piddir = /var/run # filesystem directory to store PID file<br />
cgiurl = http://localhost/smokeping/smokeping.cgi # exterior URL<br />
smokemail = /etc/smokeping/smokemail <br />
tmail = /etc/smokeping/tmail<br />
syslogfacility = local0<br />
# each probe is now run in its own process<br />
# disable this to revert to the old behaviour<br />
# concurrentprobes = no<br />
<br />
*** Database ***<br />
<br />
step = 300<br />
pings = 20<br />
<br />
# consfn mrhb steps total<br />
<br />
AVERAGE 0.5 1 1008<br />
AVERAGE 0.5 12 4320<br />
MIN 0.5 12 4320<br />
MAX 0.5 12 4320<br />
AVERAGE 0.5 144 720<br />
MAX 0.5 144 720<br />
MIN 0.5 144 720<br />
<br />
*** Presentation ***<br />
<br />
template = /etc/smokeping/basepage.html<br />
<br />
+ charts<br />
<br />
menu = Charts<br />
title = The most interesting destinations<br />
++ stddev<br />
sorter = StdDev(entries=>4)<br />
title = Top Standard Deviation<br />
menu = Std Deviation<br />
format = Standard Deviation %f<br />
<br />
++ max<br />
sorter = Max(entries=>5)<br />
title = Top Max Roundtrip Time<br />
menu = by Max<br />
format = Max Roundtrip Time %f seconds<br />
<br />
++ loss<br />
sorter = Loss(entries=>5)<br />
title = Top Packet Loss<br />
menu = Loss<br />
format = Packets Lost %f<br />
<br />
++ median<br />
sorter = Median(entries=>5)<br />
title = Top Median Roundtrip Time<br />
menu = by Median<br />
format = Median RTT %f seconds<br />
<br />
+ overview <br />
<br />
width = 600<br />
height = 50<br />
range = 10h<br />
<br />
+ detail<br />
<br />
width = 600<br />
height = 200<br />
unison_tolerance = 2<br />
<br />
"Last 3 Hours" 3h<br />
"Last 30 Hours" 30h<br />
"Last 10 Days" 10d<br />
"Last 400 Days" 400d<br />
<br />
*** Probes ***<br />
<br />
+ FPing<br />
<br />
binary = /usr/sbin/fping<br />
<br />
<br />
*** Targets ***<br />
<br />
probe = FPing<br />
<br />
menu = Top<br />
title = Network Latency Grapher<br />
remark = Welcome to the SmokePing website of Arch User. \<br />
Here you will learn all about the latency of our network.<br />
<br />
+ targets<br />
menu = Targets<br />
<br />
++ Server<br />
<br />
menu = Arch Linux<br />
title = Arch Linux Website<br />
host = 66.211.214.131<br />
<br />
++ MultiHost<br />
<br />
menu = Multihost<br />
title = Arch Wiki and Kernel.org<br />
host = 5.9.250.164 149.20.4.69<br />
<br />
</nowiki>}}<br />
<br />
{{Note|If we use smokeping_secrets we will have to make it unreadable to the rest, or else smokeping will eror: {{ic|chmod 600 /etc/smokeping/smokeping_secrets}}.}}<br />
4. Now setup the extra directories:<br />
# mkdir -p /srv/smokeping/data<br />
# mkdir -p /srv/smokeping/imgcache<br />
# chown -R smokeping:smokeping /srv/smokeping<br />
# chown -R http:http /srv/smokeping/imgcache<br />
<br />
5. The FastCGI script is used by both the smokeping daemon and the FastCGI scripts, so it needs to be readable:<br />
# chmod a+rx /etc/smokeping<br />
# chmod a+r /etc/smokeping/config<br />
<br />
6. Start smokeping<br />
# systemctl start smokeping<br />
<br />
7. We edit /etc/httpd/conf/httpd.conf so it includes<br />
{{hc|/etc/httpd/conf/httpd.conf|2=<nowiki><br />
LoadModule fastcgi_module modules/mod_fastcgi.so<br />
<IfModule fastcgi_module><br />
AddHandler fastcgi-script .fcgi # you can put whatever extension you want<br />
</IfModule><br />
#FastCgiConfig -idle-timeout 90 # try this if you hit errors about the scripts exceeding the idle timeout.<br />
ScriptAlias /smokeping/smokeping.cgi /srv/http/smokeping.fcgi<br />
<br />
Alias /smokeping/imgcache /srv/smokeping/imgcache<br />
Alias /smokeping /srv/http/smokeping<br />
<br />
<Directory "/srv/smokeping/imgcache"><br />
AllowOverride all<br />
Order Deny,Allow<br />
Allow from all<br />
Require all granted<br />
</Directory><br />
<br />
<Directory "/srv/http/smokeping"><br />
Options FollowSymLinks<br />
AllowOverride all<br />
Order Deny,Allow<br />
Allow from all<br />
Require all granted<br />
</Directory><br />
</nowiki>}}<br />
<br />
8. Start Apache:<br />
systemctl start http<br />
<br />
9. Wait a few minutes and check the first data at {{ic|http://localhost/smokeping/smokeping.cgi}}<br />
<br />
[[User:M01|M01]] ([[User talk:M01|talk]]) 22:02, 16 March 2015 (UTC)<br />
<br />
:Hello, well done! I suppose you can change the wiki since it works for you. When I get some time (hopefully within 2015 :)) I'll try it in a container to check it works fine with a fresh Arch install.<br />
:[[User:Costis|Costis]] ([[User talk:Costis|talk]]) 18:41, 22 March 2015 (UTC)<br />
<br />
No you shouldn't add a new section. You should rewrite the entire page :). What I wrote was for an old version of smokeping. When I wrote this, smokeping was not designed to use FastCGI. Most of what I wrote is no longer applicable.<br />
<br />
My advice is to burn it down and rebuild it. Remove everything that doesn't use Apache and FastCGI. You're right, it's too complicated. Simplify it. Make sure older sections do not refer to other old or missing sections. You don't have to limit yourself to a new section to protect other peoples' feelings. Not mine anyways.<br />
<br />
[[User:Juster|Juster]] ([[User talk:Juster|talk]]) 21:11, 22 March 2015 (UTC)</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=355452Perl package guidelines2015-01-05T03:05:18Z<p>Juster: /* PKGBUILD Examples */ Mentions my sneaky trick from awhile back.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the creation of [[PKGBUILD]]s for perl modules distributed over CPAN, the Comprehensive Perl Authors Network. The target audience of this document is intended to be packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl module packages consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl packages should install module files into {{ic|/usr/lib/perl5/vendor_perl/}}, or {{ic|/usr/share/perl5/vendor_perl/}}. This is done by setting the {{Ic|INSTALLDIRS}} command line parameter to {{ic|vendor}} as shown below. No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. When a user installs modules system-wide by using the <i>cpan</i> shell, modules end up in the site-perl sub-directories.<br />
<br />
The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{Ic|('i686' 'x86_64')}} in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
The build, check, and package functions use parenthesis instead of curly brackets to surround their body of statements. Doing so causes the function body to be run in a subshell, avoiding modification of makepkg's environment. This is simply a precaution.<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
== Installation modules ==<br />
One of perl's greatest strengths is the sheer number of modules available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
These modules are concerned with building the distribution and installing module files wherever the user prefers. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. Installation modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build and install process. The script always ends with the {{ic|.PL}} suffix and is termed the "Build script" in the below list.<br />
<br />
=== ExtUtils::MakeMaker ===<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people!<br />
<br />
=== Module::Build ===<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
=== Module::Install ===<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. {{Ic|MI}} was designed as a drop-in replacement for {{Ic|MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. Ironically, it depends on {{Ic|MakeMaker}} in order to operate. The {{ic|Makefile.PL}} files that are generated by {{Ic|MI}} look much different and are implemented using a simple domain specific language.<br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''Though not recommended by {{Ic|Module::Install}}'s authors this feature is used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Pacman optimizes this process by deciding that the version component with the longest length, as a string, is automatically considered the largest.<br />
<br />
This means that 5.0001 is greater than 5.1 because "0001" has a length of 4 and "1" has a length of 1. For the same reason 5.10 is not equal to 5.1, it is greater than 5.1. The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=355451Perl package guidelines2015-01-05T03:00:01Z<p>Juster: /* Installation modules */ Restructure into a main page section.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the creation of [[PKGBUILD]]s for perl modules distributed over CPAN, the Comprehensive Perl Authors Network. The target audience of this document is intended to be packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl module packages consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl packages should install module files into {{ic|/usr/lib/perl5/vendor_perl/}}, or {{ic|/usr/share/perl5/vendor_perl/}}. This is done by setting the {{Ic|INSTALLDIRS}} command line parameter to {{ic|vendor}} as shown below. No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. When a user installs modules system-wide by using the <i>cpan</i> shell, modules end up in the site-perl sub-directories.<br />
<br />
The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{Ic|('i686' 'x86_64')}} in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
== Installation modules ==<br />
One of perl's greatest strengths is the sheer number of modules available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
These modules are concerned with building the distribution and installing module files wherever the user prefers. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. Installation modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build and install process. The script always ends with the {{ic|.PL}} suffix and is termed the "Build script" in the below list.<br />
<br />
=== ExtUtils::MakeMaker ===<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people!<br />
<br />
=== Module::Build ===<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
=== Module::Install ===<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. {{Ic|MI}} was designed as a drop-in replacement for {{Ic|MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. Ironically, it depends on {{Ic|MakeMaker}} in order to operate. The {{ic|Makefile.PL}} files that are generated by {{Ic|MI}} look much different and are implemented using a simple domain specific language.<br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''Though not recommended by {{Ic|Module::Install}}'s authors this feature is used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Pacman optimizes this process by deciding that the version component with the longest length, as a string, is automatically considered the largest.<br />
<br />
This means that 5.0001 is greater than 5.1 because "0001" has a length of 4 and "1" has a length of 1. For the same reason 5.10 is not equal to 5.1, it is greater than 5.1. The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=355450Perl package guidelines2015-01-05T02:43:46Z<p>Juster: /* Perl and Pacman version conflicts */ Improve the clarity of examples and shorten paragraph.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the creation of [[PKGBUILD]]s for perl modules distributed over CPAN, the Comprehensive Perl Authors Network. The target audience of this document is intended to be packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl module packages consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl packages should install module files into {{ic|/usr/lib/perl5/vendor_perl/}}, or {{ic|/usr/share/perl5/vendor_perl/}}. This is done by setting the {{Ic|INSTALLDIRS}} command line parameter to {{ic|vendor}} as shown below. No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. When a user installs modules system-wide by using the <i>cpan</i> shell, modules end up in the site-perl sub-directories.<br />
<br />
The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{Ic|('i686' 'x86_64')}} in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
==== Module::Build ====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
==== Module::Install ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Pacman optimizes this process by deciding that the version component with the longest length, as a string, is automatically considered the largest.<br />
<br />
This means that 5.0001 is greater than 5.1 because "0001" has a length of 4 and "1" has a length of 1. For the same reason 5.10 is not equal to 5.1, it is greater than 5.1. The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=355449Perl package guidelines2015-01-05T02:40:09Z<p>Juster: /* Perl and Pacman version conflicts */ Removes an older, redundant paragraph.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the creation of [[PKGBUILD]]s for perl modules distributed over CPAN, the Comprehensive Perl Authors Network. The target audience of this document is intended to be packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl module packages consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl packages should install module files into {{ic|/usr/lib/perl5/vendor_perl/}}, or {{ic|/usr/share/perl5/vendor_perl/}}. This is done by setting the {{Ic|INSTALLDIRS}} command line parameter to {{ic|vendor}} as shown below. No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. When a user installs modules system-wide by using the <i>cpan</i> shell, modules end up in the site-perl sub-directories.<br />
<br />
The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{Ic|('i686' 'x86_64')}} in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
==== Module::Build ====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
==== Module::Install ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=312083Perl package guidelines2014-04-27T19:59:24Z<p>Juster: /* ArchLinux Packaging Conventions */ Fix typo of missing s</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the creation of [[PKGBUILD]]s for perl modules distributed over CPAN, the Comprehensive Perl Authors Network. The target audience of this document is intended to be packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl module packages consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl packages should install module files into {{ic|/usr/lib/perl5/vendor_perl/}}, or {{ic|/usr/share/perl5/vendor_perl/}}. This is done by setting the {{Ic|INSTALLDIRS}} command line parameter to {{ic|vendor}} as shown below. No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. When a user installs modules system-wide by using the <i>cpan</i> shell, modules end up in the site-perl sub-directories.<br />
<br />
The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{Ic|('i686' 'x86_64')}} in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
==== Module::Build ====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
==== Module::Install ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=312082Perl package guidelines2014-04-27T19:58:43Z<p>Juster: Try to fix poor grammar in intro paragraph. i.e. perl modules are written in perl, implicitly</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the creation of [[PKGBUILD]]s for perl modules distributed over CPAN, the Comprehensive Perl Authors Network. The target audience of this document is intended to be packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl package consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl packages should install module files into {{ic|/usr/lib/perl5/vendor_perl/}}, or {{ic|/usr/share/perl5/vendor_perl/}}. This is done by setting the {{Ic|INSTALLDIRS}} command line parameter to {{ic|vendor}} as shown below. No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. When a user installs modules system-wide by using the <i>cpan</i> shell, modules end up in the site-perl sub-directories.<br />
<br />
The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{Ic|('i686' 'x86_64')}} in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
==== Module::Build ====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
==== Module::Install ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=312081Perl package guidelines2014-04-27T19:55:33Z<p>Juster: The C in CPAN is Comprehensive, not Central.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the topic of creating [[PKGBUILD]]s for perl modules written in [[Wikipedia:Perl|Perl]] and distributed over CPAN, the Comprehensive Perl Authors Network. The primary audience of this document are packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl package consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl packages should install module files into {{ic|/usr/lib/perl5/vendor_perl/}}, or {{ic|/usr/share/perl5/vendor_perl/}}. This is done by setting the {{Ic|INSTALLDIRS}} command line parameter to {{ic|vendor}} as shown below. No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. When a user installs modules system-wide by using the <i>cpan</i> shell, modules end up in the site-perl sub-directories.<br />
<br />
The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{Ic|('i686' 'x86_64')}} in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
==== Module::Build ====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
==== Module::Install ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=312080Perl package guidelines2014-04-27T19:53:24Z<p>Juster: /* Automation */ There are not a few scripts to help automation anymore...</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the topic of creating [[PKGBUILD]]s for perl modules written in [[Wikipedia:Perl|Perl]] and distributed over CPAN, the Central Perl Authors Network. The primary audience of this document are packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl package consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl packages should install module files into {{ic|/usr/lib/perl5/vendor_perl/}}, or {{ic|/usr/share/perl5/vendor_perl/}}. This is done by setting the {{Ic|INSTALLDIRS}} command line parameter to {{ic|vendor}} as shown below. No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. When a user installs modules system-wide by using the <i>cpan</i> shell, modules end up in the site-perl sub-directories.<br />
<br />
The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{Ic|('i686' 'x86_64')}} in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
==== Module::Build ====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
==== Module::Install ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=312079Perl package guidelines2014-04-27T19:53:00Z<p>Juster: /* Package file placement */ Fix slight inaccuracies in the Package file placement section.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the topic of creating [[PKGBUILD]]s for perl modules written in [[Wikipedia:Perl|Perl]] and distributed over CPAN, the Central Perl Authors Network. The primary audience of this document are packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl package consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl packages should install module files into {{ic|/usr/lib/perl5/vendor_perl/}}, or {{ic|/usr/share/perl5/vendor_perl/}}. This is done by setting the {{Ic|INSTALLDIRS}} command line parameter to {{ic|vendor}} as shown below. No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. When a user installs modules system-wide by using the <i>cpan</i> shell, modules end up in the site-perl sub-directories.<br />
<br />
The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{Ic|('i686' 'x86_64')}} in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
==== Module::Build ====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
==== Module::Install ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=312078Perl package guidelines2014-04-27T19:49:14Z<p>Juster: /* Architecture */ fix typo</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the topic of creating [[PKGBUILD]]s for perl modules written in [[Wikipedia:Perl|Perl]] and distributed over CPAN, the Central Perl Authors Network. The primary audience of this document are packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl package consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{Ic|('i686' 'x86_64')}} in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
==== Module::Build ====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
==== Module::Install ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=312077Perl package guidelines2014-04-27T19:48:29Z<p>Juster: /* Architecture */ Mentions when the arch value of 'any' should not be used.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the topic of creating [[PKGBUILD]]s for perl modules written in [[Wikipedia:Perl|Perl]] and distributed over CPAN, the Central Perl Authors Network. The primary audience of this document are packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl package consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent. XS modules are compiled into dynamically loaded libraries (.so files) and should explicitly set their architecture to {{lc|('i686' 'x86_64') in order to indicate that they are architecture dependent when built. An XS module usually contains one or more .xs files which dynamically generate .c files.<br />
<br />
=== Automation ===<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
==== Module::Build ====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
==== Module::Install ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=312075Perl package guidelines2014-04-27T19:43:59Z<p>Juster: Major reorganization. Move easy stuff to top. Removed superfluous hierarchy (i.e. advanced section). Moved advanced topics/troubleshooting to the end.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the topic of creating [[PKGBUILD]]s for perl modules written in [[Wikipedia:Perl|Perl]] and distributed over CPAN, the Central Perl Authors Network. The primary audience of this document are packagers of perl modules.<br />
<br />
== ArchLinux Packaging Conventions ==<br />
<br />
The following conventions should be used to keep perl package consistent. This section serves as an introduction to the concept of perl packaging, from the point of view of ArchLinux; that is, package management and system administration. In an effort to please the casual TL;DR reader, the easiest and/or most popular material is at the top.<br />
<br />
=== Package names ===<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
=== Package file placement ===<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
=== Architecture ===<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent.<br />
<br />
=== Automation ===<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
== PKGBUILD Examples ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
The following two PKGBUILD examples use techniques, introduced in this page, that are intended to make a PKGBUILD more resilient to more sophisticated problems. Because there are two styles of build scripts, there are two example PKGBUILDS. The first PKGBUILD is an example of how to package a distribution that uses {{ic|Makefile.PL}}. The second PKGBUILD can be used as a starting point for a distribution which uses {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
/usr/bin/perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_LOCAL_LIB_ROOT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
/usr/bin/perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT PERL_LOCAL_LIB_ROOT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
Justification for the added complexity of these PKGBUILDs is attempted in the latter sections.<br />
<br />
== CPAN Module Mechanics ==<br />
<br />
There are a number of carefully, and not so carefully, designed mechanics that work together to create the module system. When making use of the CPAN, procedures must be followed to fetch the source code of a module, build that fetched module, and insert it into the system software for later execution. In order to understand how modules should be packaged, it helps immensely if one understands how modules work without any involvement from pacman and ArchLinux packages. Our goal in the end is to try to be unobtrusive as possible, while improving organization and consistency in the end product.<br />
<br />
=== Modules ===<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
=== Distributions ===<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== CPAN ===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Module dependencies ===<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are "defined" inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
==== Module::Build ====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
==== Module::Install ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
== Perl and Pacman version conflicts ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Problems with user-installed perl ==<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=280514Perl package guidelines2013-10-30T20:11:39Z<p>Juster: Fix typo in new PKGBUILD for Build.PL.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the topic of creating [[PKGBUILD]]s for perl modules written in [[Wikipedia:Perl|Perl]] and distributed over CPAN, the Central Perl Authors Network. The primary audience of this document are packagers of perl modules.<br />
<br />
== Package naming ==<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
== File placement ==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
== Notes ==<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent.<br />
<br />
== Example ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
== Automation ==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with {{pkg|pacman}}''>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with {{pkg|pacman}}''>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
== Module dependencies ==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Implementation ===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are defined inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
== Perl and Pacman versions ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Advanced topics ==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
=== Glossary ===<br />
You should be familiar with the following terms.<br />
<br />
==== Module ====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
==== Core module ====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
==== Distributions ====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== User-installed perl ===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
=== Hardened example ===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it.<br />
First is an example using {{ic|Makefile.PL}}, after which is an example using {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT<br />
./Build install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=280512Perl package guidelines2013-10-30T20:09:45Z<p>Juster: Update the ancient PKGBUILD.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the topic of creating [[PKGBUILD]]s for perl modules written in [[Wikipedia:Perl|Perl]] and distributed over CPAN, the Central Perl Authors Network. The primary audience of this document are packagers of perl modules.<br />
<br />
== Package naming ==<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
== File placement ==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
== Notes ==<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent.<br />
<br />
== Example ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
== Automation ==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with {{pkg|pacman}}''>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with {{pkg|pacman}}''>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
== Module dependencies ==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Implementation ===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are defined inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
== Perl and Pacman versions ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Advanced topics ==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
=== Glossary ===<br />
You should be familiar with the following terms.<br />
<br />
==== Module ====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
==== Core module ====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
==== Distributions ====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== User-installed perl ===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
=== Hardened example ===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it.<br />
First is an example using {{ic|Makefile.PL}}, after which is an example using {{ic|Build.PL}}.<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps<br />
perl Makefile.PL<br />
make<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT<br />
export PERL_MM_USE_DEFAULT=1<br />
make test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT<br />
make install INSTALLDIRS=vendor DESTDIR="$pkgdir"<br />
)<br />
</nowiki>}}<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=1.0<br />
pkgrel=1<br />
pkgdesc='This packages the Foo-Bar distribution, containing the Foo::Bar module!'<br />
_dist=Foo-Bar<br />
arch=('any')<br />
url="https://metacpan.org/release/$_dist"<br />
license=('GPL' 'PerlArtistic')<br />
depends=(perl)<br />
options=('!emptydirs' purge)<br />
source=("http://search.cpan.org/CPAN/authors/id/BAZ/$_dist-$pkgver.tar.gz")<br />
md5sums=(...)<br />
<br />
build() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT<br />
export PERL_MM_USE_DEFAULT=1 MODULEBUILDRC=/dev/null<br />
perl Build.PL<br />
./Build<br />
)<br />
<br />
check() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT<br />
export PERL_MM_USE_DEFAULT=1<br />
./Build test<br />
)<br />
<br />
package() (<br />
cd "$srcdir/$_dist-$pkgver"<br />
unset PERL5LIB PERL_MM_OPT PERL_MB_OPT<br />
make install installdirs=vendor destdir="$pkgdir"<br />
)<br />
</nowiki>}}</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=280507Perl package guidelines2013-10-30T19:53:20Z<p>Juster: Update the intro to make a complete sentence or two.</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
This document covers the topic of creating [[PKGBUILD]]s for perl modules written in [[Wikipedia:Perl|Perl]] and distributed over CPAN, the Central Perl Authors Network. The primary audience of this document are packagers of perl modules.<br />
<br />
== Package naming ==<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
== File placement ==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
== Notes ==<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent.<br />
<br />
== Example ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
== Automation ==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with {{pkg|pacman}}''>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with {{pkg|pacman}}''>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
== Module dependencies ==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Implementation ===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are defined inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
== Perl and Pacman versions ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Advanced topics ==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
=== Glossary ===<br />
You should be familiar with the following terms.<br />
<br />
==== Module ====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
==== Core module ====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
==== Distributions ====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== User-installed perl ===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
=== Hardened example ===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=('!emptydirs')<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
}<br />
</nowiki>}}</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=280506Perl package guidelines2013-10-30T19:47:33Z<p>Juster: Undo revision 278565 by Anthraxx (talk) he obviously didn't read any of the wiki page, ignoring important env vars for example</p>
<hr />
<div>[[Category:Package development]]<br />
[[it:Perl Package Guidelines]]<br />
{{Package Guidelines}}<br />
<br />
Creating [[PKGBUILD]]s for software written in [[Wikipedia:Perl|Perl]].<br />
<br />
== Package naming ==<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
== File placement ==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
== Notes ==<br />
In most cases, the {{Ic|arch}} array should contain {{Ic|'any'}} because most Perl packages are architecture independent.<br />
<br />
== Example ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
== Automation ==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with {{pkg|pacman}}''>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with {{pkg|pacman}}''>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
== Module dependencies ==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Implementation ===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Dependency definition ===<br />
Where are dependencies defined in perl distributions? They are defined inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
== Perl and Pacman versions ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Advanced topics ==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
=== Glossary ===<br />
You should be familiar with the following terms.<br />
<br />
==== Module ====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
==== Core module ====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
==== Distributions ====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== User-installed perl ===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl Arch Linux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
=== Installation modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
==== PERL5LIB ====<br />
The directories searched for libraries can be set by the user (particularly if they are using {{ic|Local::Lib}}) by setting {{ic|PERL5LIB}}. That should be cleared before building.<br />
<br />
==== PERL_LOCAL_LIB_ROOT ====<br />
If the user is using {{ic|Local::Lib}} it will set {{ic|PERL_LOCAL_LIB_ROOT}}. That should be cleared before building.<br />
<br />
=== Hardened example ===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
{{hc|PKGBUILD|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=('!emptydirs')<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
}<br />
</nowiki>}}</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=194419Perl package guidelines2012-04-15T23:00:14Z<p>Juster: /* Implementation */ Keep mention of the cpan shell italicized and not emboldened.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
{{i18n|Perl Package Guidelines}}<br />
{{Package Guidelines}}<br />
<br />
Creating [[PKGBUILD]]s for software written in [[Wikipedia:Perl|Perl]].<br />
<br />
== Package Naming ==<br />
For modules the package name should begin with {{Ic|perl-}} and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to {{Ic|HTML::Parser}} will be {{Ic|perl-html-parser}}. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
== File Placement ==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example PKGBUILD described below.<br />
<br />
== Notes ==<br />
In most cases, you should put {{Ic|any}} in the {{Ic|arch}} array since most Perl packages are architecture independent.<br />
<br />
== Example ==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package.<br />
<br />
== Automation ==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
== Module Dependencies ==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
=== Implementation ===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
=== Dependency Definition ===<br />
Where are dependencies defined in perl distributions? They are defined inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
=== Meta Information ===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
== Perl and Pacman Versions ==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
== Advanced Topics ==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
=== Glossary ===<br />
You should be familiar with the following terms.<br />
<br />
==== Module ====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
==== Core Module ====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
==== Distributions ====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
=== User-Installed perl ===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl ArchLinux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
=== Installation Modules ===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
==== ExtUtils::MakeMaker ====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
=== Environment Variables ===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting PKGBUILD or cause unexpected behavior.<br />
<br />
==== PERL_MM_USE_DEFAULT ====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
==== PERL_AUTOINSTALL ====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
==== PERL_MM_OPT ====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
==== PERL_MB_OPT ====<br />
This is the same thing as {{Ic|PERL_MM_OPT}} except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
==== MODULEBUILDRC ====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
=== Hardened Example ===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
{{bc|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</nowiki>}}</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=186736Perl package guidelines2012-02-27T22:05:52Z<p>Juster: Use the version.pm docs instead of dagolden's blog post. It's more relevant to the paragraph.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
<br />
{{i18n|Perl Package Guidelines}}<br />
<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package. It is also reproduced below:<br />
{{bc|<nowiki><br />
# Maintainer: Your Name <youremail@domain.com><br />
_author=AUTHOR_NAME<br />
_perlmod=MODNAME<br />
pkgname=perl-$_perlmod<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url="http://search.cpan.org/~$_author/$_perlmod-$pkgver/"<br />
license=('GPL' 'PerlArtistic')<br />
groups=()<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://cpan.perl.org/modules/by-authors/id/$_author/$_perlmod-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
<br />
# Install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor<br />
make<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
}<br />
<br />
package() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
make install DESTDIR="$pkgdir/"<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build install<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</nowiki>}}<br />
<br />
In most cases, you should put '''any''' in the {{Ic|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
==Module Dependencies==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
===Implementation===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
===Dependency Definition===<br />
Where are dependencies defined in perl distributions? They are defined inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
===Meta Information===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
==Perl and Pacman Versions==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! The [https://metacpan.org/module/version::Internals internal docs] for the version.pm module describes the conversion of dotted decimal versions in more detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===User-Installed perl===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl ArchLinux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{ic|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
====MODULEBUILDRC====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
{{bc|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</nowiki>}}</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=186735Perl package guidelines2012-02-27T22:02:59Z<p>Juster: Discuss the differences between perl and pacman version comparisons.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
<br />
{{i18n|Perl Package Guidelines}}<br />
<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package. It is also reproduced below:<br />
{{bc|<nowiki><br />
# Maintainer: Your Name <youremail@domain.com><br />
_author=AUTHOR_NAME<br />
_perlmod=MODNAME<br />
pkgname=perl-$_perlmod<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url="http://search.cpan.org/~$_author/$_perlmod-$pkgver/"<br />
license=('GPL' 'PerlArtistic')<br />
groups=()<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://cpan.perl.org/modules/by-authors/id/$_author/$_perlmod-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
<br />
# Install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor<br />
make<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
}<br />
<br />
package() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
make install DESTDIR="$pkgdir/"<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build install<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</nowiki>}}<br />
<br />
In most cases, you should put '''any''' in the {{Ic|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
==Module Dependencies==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
===Implementation===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
===Dependency Definition===<br />
Where are dependencies defined in perl distributions? They are defined inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
===Meta Information===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
==Perl and Pacman Versions==<br />
In perl versions are numbers. In pacman versions are strings.<br />
<br />
Perl allows both decimal versions, like 5.002006, and dotted decimal versions, like 5.2.6. You might have a hard time comparing between decimals and dotted decimals, so perl converts dotted decimal versions to decimal versions by padding with zeros. Each dot separates up to three digits and 5.2.6 becomes 5.002006. Now its easy to compare with some simple arithmetic! This isn't the whole story but it about sums it up. David Golden, author of {{ic|Module::Build}}, has a relevant blog post called [http://www.dagolden.com/index.php/369/version-numbers-should-be-boring/ Version Numbers Should Be Boring] which describe versions in mind-numbing detail.<br />
<br />
The important thing is that perl compares versions exactly the same as it compares two numbers. Versions are numbers. 5.10 = 5.1. Pretty easy right? Dotted decimals are not so easy. 5.1.1 == 5.001001. Huh? The bad part is most other systems think of versions as strings making perl the odd man out.<br />
<br />
Pacman works best with dotted decimal versions and doesn't compare them numerically. Components are split at non-alphanumeric characters and compared side-by-side as integers. The first component that is not equal determines which version string is less than or greater the other. Right away the component with the longest length, as a string, is considered the largest. This means that 5.0001 is greater than 5.1. 5.10 is not equal to 5.1, it is greater.<br />
<br />
The problem is that changing the length of the version string can seriously confuse pacman. Consider the releases of [https://metacpan.org/release/AnyEvent AnyEvent]:<br />
<br />
# 6.01 (2011-08-26)<br />
# 6.02 (2011-08-26)<br />
# 6.1 (2011-10-24)<br />
# 6.11 (2011-11-22)<br />
# 6.12 (2011-12-12)<br />
<br />
That 6.1 in the middle can cause problems because the length of the version string has decreased. In pacman's world 6.1 is less than 6.02. If a package depends on {{ic|<nowiki>perl-anyevent>=6.02</nowiki>}} and only 6.1 is available in the repository, then pacman would be unable to fulfill the dependency.<br />
<br />
One solution to this problem is to pad the pkgver with zeroes. Dependencies might also have to be padded with zeroes to make pacman happy. Version 6.1 would become 6.10.<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===User-Installed perl===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl ArchLinux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{ic|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
====MODULEBUILDRC====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
{{bc|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</nowiki>}}</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=186732Perl package guidelines2012-02-27T21:15:53Z<p>Juster: Meta Information had too many ='s</p>
<hr />
<div>[[Category:Package development (English)]]<br />
<br />
{{i18n|Perl Package Guidelines}}<br />
<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package. It is also reproduced below:<br />
{{bc|<nowiki><br />
# Maintainer: Your Name <youremail@domain.com><br />
_author=AUTHOR_NAME<br />
_perlmod=MODNAME<br />
pkgname=perl-$_perlmod<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url="http://search.cpan.org/~$_author/$_perlmod-$pkgver/"<br />
license=('GPL' 'PerlArtistic')<br />
groups=()<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://cpan.perl.org/modules/by-authors/id/$_author/$_perlmod-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
<br />
# Install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor<br />
make<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
}<br />
<br />
package() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
make install DESTDIR="$pkgdir/"<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build install<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</nowiki>}}<br />
<br />
In most cases, you should put '''any''' in the {{Ic|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
==Module Dependencies==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
===Implementation===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
===Dependency Definition===<br />
Where are dependencies defined in perl distributions? They are defined inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
===Meta Information===<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===User-Installed perl===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl ArchLinux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{ic|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
====MODULEBUILDRC====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
{{bc|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</nowiki>}}</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=186731Perl package guidelines2012-02-27T21:14:07Z<p>Juster: Add section on module dependency definitions and meta information.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
<br />
{{i18n|Perl Package Guidelines}}<br />
<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package. It is also reproduced below:<br />
{{bc|<nowiki><br />
# Maintainer: Your Name <youremail@domain.com><br />
_author=AUTHOR_NAME<br />
_perlmod=MODNAME<br />
pkgname=perl-$_perlmod<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url="http://search.cpan.org/~$_author/$_perlmod-$pkgver/"<br />
license=('GPL' 'PerlArtistic')<br />
groups=()<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://cpan.perl.org/modules/by-authors/id/$_author/$_perlmod-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
<br />
# Install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor<br />
make<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
}<br />
<br />
package() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
make install DESTDIR="$pkgdir/"<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build install<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</nowiki>}}<br />
<br />
In most cases, you should put '''any''' in the {{Ic|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
==Module Dependencies==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
{{bc|1=<br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
}}<br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
{{bc|<br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
}}<br />
<br />
===Implementation===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
===Dependency Definition===<br />
Where are dependencies defined in perl distributions? They are defined inside of the {{ic|Makefile.PL}} or {{ic|Build.PL}} script. For example, inside of the {{ic|Makefile.PL}} script the {{ic|WriteMakeFile}} function is called to generate the {{ic|Makefile}} like this:<br />
<br />
{{bc|<nowiki><br />
use ExtUtils::MakeMaker;<br />
WriteMakeFile(<br />
'NAME' => 'ArchLinux::Module',<br />
'VERSION' => '0.01',<br />
'PREREQ_PM' => { 'POSIX' => '0.01' },<br />
);<br />
</nowiki>}}<br />
<br />
This is a contrived example but it is important to understand the dependencies aren't final until after the {{ic|Makefile.PL}} or {{ic|Build.PL}} script is run. Dependencies are specified at runtime, which means they can be changed or modified using the full power of perl. This means the module author can add, remove, or change versions of dependencies right before the distribution is installed. Some modules authors use this to do overly clever things like depend on modules only if they are installed. Some multi-platform dists also depend on system-specific modules when installed on different operating systems.<br />
<br />
As an example, the CPANPLUS distribution looks for CPANPLUS::Dist plugins that are currently installed. If any plugins are installed for the currently installed version of CPANPLUS it adds them to the new CPANPLUS's prerequisites. I'm not quite sure why. Luckily for the perl packager most dependencies are static like in the above example that requires the POSIX module with a minimum version of 0.01.<br />
<br />
====Meta Information====<br />
Meta files are included in recent distributions which contain meta-information about distributions such as the name, author, abstract description, and module requirements. Previously there were {{ic|META.yml}} files in the YAML format but more recently the switch has been made to {{ic|META.json}} files in the JSON format. These files can<br />
be edited by hand but more often they are generated automatically by {{ic|Makefile.PL}} or {{ic|Build.PL}} scripts when packaging a distribution for release. The latest specification is described in [http://search.cpan.org/perldoc?CPAN::Meta::Spec CPAN::Meta::Spec's online docs].<br />
<br />
Remember that dependencies can be changed at runtime! For this reason another meta file is generated after running the build script. This second meta file is called {{ic|MYMETA.json}} and reflects changes the script made at runtime and may be different from the meta file generated when the distribution was packaged for CPAN.<br />
<br />
Elderly distributions on the CPAN have no meta file at all. These old releases predate the idea of the META.yml file and only describe their prerequisites in their {{ic|Makefile.PL}}.<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===User-Installed perl===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl ArchLinux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{ic|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
{{bc|1=export PERL_AUTOINSTALL='--skipdeps'}}<br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
{{bc|1=export PERL_MM_OPT=INSTALLBASE=~/perl5}}<br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
{{bc|1=export PERL_MB_OPT=--install_base=~/perl5}}<br />
<br />
====MODULEBUILDRC====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
{{bc|<nowiki><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</nowiki>}}</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=186442Perl package guidelines2012-02-26T16:15:55Z<p>Juster: Add example of how a module VERSION is printed.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
<br />
{{i18n|Perl Package Guidelines}}<br />
<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package. It is also reproduced below:<br />
<pre><br />
# Maintainer: Your Name <youremail@domain.com><br />
_author=AUTHOR_NAME<br />
_perlmod=MODNAME<br />
pkgname=perl-$_perlmod<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url="http://search.cpan.org/~$_author/$_perlmod-$pkgver/"<br />
license=('GPL' 'PerlArtistic')<br />
groups=()<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://cpan.perl.org/modules/by-authors/id/$_author/$_perlmod-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
<br />
# Install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor<br />
make<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
}<br />
<br />
package() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
make install DESTDIR="$pkgdir/"<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build install<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the {{Ic|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
==Module Dependencies==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
<pre><br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
</pre><br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine. For example:<br />
<br />
<pre><br />
use Foo::Module;<br />
print $Foo::Module::VERSION, "\n";<br />
</pre><br />
<br />
===Implementation===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===User-Installed perl===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl ArchLinux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{ic|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
<pre>export PERL_AUTOINSTALL='--skipdeps'</pre><br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
<pre>export PERL_MM_OPT=INSTALLBASE=~/perl5</pre><br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
<pre>export PERL_MB_OPT=--install_base=~/perl5</pre><br />
<br />
====MODULEBUILDRC====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</pre></div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=186441Perl package guidelines2012-02-26T16:13:06Z<p>Juster: Describe how perl dists depend on modules and not dists.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
<br />
{{i18n|Perl Package Guidelines}}<br />
<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package. It is also reproduced below:<br />
<pre><br />
# Maintainer: Your Name <youremail@domain.com><br />
_author=AUTHOR_NAME<br />
_perlmod=MODNAME<br />
pkgname=perl-$_perlmod<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url="http://search.cpan.org/~$_author/$_perlmod-$pkgver/"<br />
license=('GPL' 'PerlArtistic')<br />
groups=()<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://cpan.perl.org/modules/by-authors/id/$_author/$_perlmod-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
<br />
# Install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor<br />
make<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
}<br />
<br />
package() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
make install DESTDIR="$pkgdir/"<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build install<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the {{Ic|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
==Module Dependencies==<br />
Perl has a unique way of defining dependencies compared to similar systems like python eggs and ruby gems. Eggs define dependencies on other eggs. Gems depend on gems. Perl dists depend on modules. Modules are only available from CPAN distributions so in a way perl distributions depend on distributions only indirectly. Modules can define their own versions independent from distributions inside the module source code. This is done by defining a <i>package</i> variable called {{ic|$VERSION}}. When using strict and warnings, this is defined with the our keyword. For example:<br />
<br />
<pre><br />
package Foo::Module;<br />
use warnings;<br />
use strict;<br />
our $VERSION = '1.00';<br />
</pre><br />
<br />
Modules can change their versions however they like and even have a version distinct from the distribution version. The utility of this is questionable but it is important to keep in mind. Module versions are more difficult to determine from outside of the perl interpreter and require parsing the perl code itself and maybe even loading the module into perl. The advantage is that from inside the perl interpreter module versions are easy to determine.<br />
<br />
===Implementation===<br />
The CPAN is a Centralized Network for Perl Authors. Each CPAN mirror contains indices that list the distributions on CPAN, the modules in the dists, and the name of the author who uploaded the dist. These are simply text files. The most useful index is in the {{ic|/modules/02packages.details.txt.gz}} file available from each CPAN mirror. The term "packages" here refers to the {{ic|package}} keyword in the perl language itself, not something similar to pacman packages. The CPAN shell, referred to as lowercased, italicized <i>cpan</i>, is simply the venerable perl script which navigates indices to find the module you want to install.<br />
<br />
Modules are found in the {{ic|02packages.details.txt.gz}} list. On the same line as the module/package name is the path to the distribution tarball that contains the module. When you ask <i>cpan</i> to install a module, it will look up the module and install the relevant distribution. As the distribution is installing it will generate a list of module dependencies. <i>Cpan</i> will try to load each module dependency into the perl interpreter. If a module of the given version cannot be loaded the process is repeated.<br />
<br />
The <i>cpan</i> shell does not have to worry about what version of the required module it is installing. <i>cpan</i> can rely on the fact that the latest version of the module must satisfy the requirements of the original module that it began installing in the first place. Only the latest versions of modules are listed in the packages details file. Unfortunately for the perl package author, we cannot always rely on the fact that our packages offer the most recent version of a perl distribution and the modules contained within. Pacman dependency checking is much more static and strongly enforced.<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===User-Installed perl===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl ArchLinux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{ic|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
<pre>export PERL_AUTOINSTALL='--skipdeps'</pre><br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
<pre>export PERL_MM_OPT=INSTALLBASE=~/perl5</pre><br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
<pre>export PERL_MB_OPT=--install_base=~/perl5</pre><br />
<br />
====MODULEBUILDRC====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</pre></div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=186438Perl package guidelines2012-02-26T15:09:02Z<p>Juster: Replace broken AUR link with mention of perl-cpanplus-dist-arch package.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
<br />
{{i18n|Perl Package Guidelines}}<br />
<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{ic|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Ic|INSTALLDIRS}} variable as shown below). No files should be stored in {{ic|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{ic|perllocal.pod}} and {{ic|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{ic|/usr/share/pacman/PKGBUILD-perl.proto}}, which is in the {{Pkg|abs}} package. It is also reproduced below:<br />
<pre><br />
# Maintainer: Your Name <youremail@domain.com><br />
_author=AUTHOR_NAME<br />
_perlmod=MODNAME<br />
pkgname=perl-$_perlmod<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url="http://search.cpan.org/~$_author/$_perlmod-$pkgver/"<br />
license=('GPL' 'PerlArtistic')<br />
groups=()<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://cpan.perl.org/modules/by-authors/id/$_author/$_perlmod-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
<br />
# Install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor<br />
make<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
}<br />
<br />
package() {<br />
cd "$srcdir/$_perlmod-$pkgver"<br />
make install DESTDIR="$pkgdir/"<br />
<br />
## For packages with Build.PL, do this instead:<br />
# perl Build install<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the {{Ic|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
A plugin for the second-generation CPAN shell, CPANPLUS, is available in the perl-cpanplus-dist-arch package from the community repo. This plugin packages distributions on the fly as they are installed by CPANPLUS. Online documentation is available at https://metacpan.org/release/CPANPLUS-Dist-Arch<br />
<br />
{{Warning|''Pacpan'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
There is also a script called {{Ic|pacpan}}, which can recursively generate PKGBUILDs for a module: http://xyne.archlinux.ca/old_projects/pacpan/<br />
<br />
It is worth mentioning that [[Bauerbill]] has similar support for generating PKGBUILDs to {{Ic|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
{{Warning|''Bauerbill'' development has been officially discontinued: its latest version does not work with ''pacman>&#61;3.5''. See [https://bbs.archlinux.org/viewtopic.php?id&#61;115660].}}<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Ic|package}} keyword in perl. Modules are contained inside a {{ic|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Ic|package}}) is in the file. Modules have namespaces separated with {{Ic|::}} (double colons), like: {{Ic|Archlinux::Module}}. When loading a module, the {{Ic|::}}s are replaced with directory separators. For example: {{ic|Archlinux/Module.pm}} will be loaded for the module {{Ic|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{ic|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{ic|Template-Toolkit-2.22.tar.gz}}, for the {{Ic|Template-Toolkit}} dist, contains no {{Ic|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===User-Installed perl===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl ArchLinux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Ic|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{ic|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{ic|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{ic|/usr/bin/perl}}) when running perl in the {{ic|PKGBUILD}}.<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Ic|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{ic|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{ic|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{ic|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Ic|Module::Build}} was not already installed, you could not run the bundled {{ic|Build.PL}} script! This is not a problem with recent versions of perl because {{Ic|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{ic|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Ic|Module::Install}} still requires the {{ic|make}} program be installed to function. It was designed as a drop-in replacement for {{Ic|ExtUtils::MakeMaker}}, to address some of {{Ic|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Ic|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Ic|MakeMaker}} or {{Ic|M::B}}, you do not need {{Ic|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Ic|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{ic|Makefile.PL}} is executed. This feature is skipped when {{Ic|Module::Install}} detects it is being run by {{Ic|CPAN}} or {{Ic|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{ic|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Ic|Module::Install}}'s {{ic|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Ic|--skipdeps}} to this.<br />
<br />
<pre>export PERL_AUTOINSTALL='--skipdeps'</pre><br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{ic|Makefile.PL}} and/or {{ic|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
<pre>export PERL_MM_OPT=INSTALLBASE=~/perl5</pre><br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT except it is only for {{Ic|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
<pre>export PERL_MB_OPT=--install_base=~/perl5</pre><br />
<br />
====MODULEBUILDRC====<br />
{{Ic|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{ic|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Ic|MODULEBUILDRC}}. The paranoid might set {{Ic|MODULEBUILDRC}} to {{ic|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</pre></div>Justerhttps://wiki.archlinux.org/index.php?title=Smokeping&diff=133830Smokeping2011-03-16T02:28:16Z<p>Juster: Remove mention of plack being outdated on the AUR. It no longer is.</p>
<hr />
<div>[[Category:Networking (English)]]<br />
<br />
= Introduction =<br />
<br />
Smokeping allows you to probe a list of servers, store that data using<br />
RRDtool, and generate statistical charts based on RRDtool's<br />
output. Smokeping consists of two parts. A daemon runs in the<br />
background pinging and collecting data at set intervals. A web<br />
interface displays that data in the form of graphs.<br />
<br />
;Smokeping Website: http://oss.oetiker.ch/smokeping/index.en.html<br />
<br />
This guide only sets up the smokeping daemon and CGI script. We<br />
do not set up advanced features like the AJAX traceroute or the<br />
JavaScript graph cropper. Why? Because these did not work properly<br />
for me and I don't need these features enough to figure out why.<br />
<br />
= Installation =<br />
<br />
The smokeping CGI script runs under [http://daemoninc.com/SpeedyCGI/ SpeedyCGI].<br />
SpeedyCGI is a modified version of perl that allows<br />
scripts to be run persistently. Without persistence, the smokeping CGI<br />
script must load all modules and data on every webpage view. This<br />
would be too slow.<br />
<br />
SpeedyCGI has not been updated since 2003 (as of Nov 1, 2010) and no<br />
longer compiles with perl, which has since gone through API changes.<br />
Instead of using SpeedyCGI for persistence, we will convert the<br />
{{Filename|smokeping.cgi}} script into a<br />
[http://search.cpan.org/~miyagawa/PSGI-1.03/PSGI.pod PSGI] webapp<br />
which can then be made persistent a variety of ways. More on that<br />
later.<br />
<br />
We will just be installing the smokeping chart interface as a<br />
webapp. The traceroute feature will not be included.<br />
<br />
== Prerequisites ==<br />
<br />
;perl: The smokeping daemon and cgi script are perl scripts. We will use the system-wide perl for this example. You might also consider a perl for only the smokeping app. You may also compile an old version of perl (try 5.8.x) if you choose to use SpeedyCGI.<br />
;fping: Smokeping has many many different ways to probe a host. The simplest and default method is a simple ping probe which requires the fping program.<br />
;rrdtool: RRDTool is created by the same author as smokeping. RRDTool collects and displays statistical information in a disk-efficient manner.<br />
;Plack: Plack is perl's version of Ruby's rack. Plack is the implementation of the PSGI specification. PSGI is like Python's WSGI. By using Plack/PSGI we can run the smokeping.cgi as a webapp on any number of backends (proxied, FreeCGI, mod_perl, CGI, etc).<br />
;perl-cgi-emulate-psgi: The CGI::Emulate::PSGI fools the smokeping.cgi script into thinking it is running in a CGI environment, when instead it is executing inside a PSGI app.<br />
;ttf-dejavu: Without this font the graphs are unreadable and the letters are replaced with blocks.<br />
<br />
=== Optional Prerequisites ===<br />
<br />
If you want to use other probes such as the DNS or http probe you will<br />
need other packages shown below. We will only be setting up the basic<br />
ping probe in this example.<br />
<br />
{| border="1"<br />
! Probe !! Package Needed<br />
|-<br />
| Curl || curl<br />
|-<br />
| DNS || dig<br />
|-<br />
| EchoPing || echoping (AUR)<br />
|-<br />
| SSH || ssh<br />
|-<br />
| TelnetIOSPing || perl-net-telnet<br />
|-<br />
| AnotherDNS || perl-net-dns<br />
|-<br />
| LDAP || perl-net-ldap<br />
|-<br />
| LDAP (tls) || perl-io-socket-ssl<br />
|-<br />
| Authen || perl-authen-radius<br />
|}<br />
<br />
In our example we use a simple Plack-based webserver. You may wish to<br />
install a full-fledged webserver. If you wish to use the master/slave<br />
functionality of Smokeping you will need the ''perl-libwww''<br />
package. If you want to probe IPv6 servers you will need the<br />
''perl-socket6'' package from the AUR. I will not be covering any of<br />
these features and will stick to the bare minimum.<br />
<br />
== Installing Packages ==<br />
<br />
First we can install the packages that are available from the official<br />
repositories:<br />
<br />
sudo pacman -S rrdtool fping perl ttf-dejavu<br />
<br />
Now install packages from the AUR by using an [[AUR Helpers|AUR helper]]<br />
like clyde or packer or even manually if you prefer:<br />
<br />
packer -S perl-cgi-emulate-psgi perl-plack<br />
<br />
== Downloading Smokeping ==<br />
<br />
We are going to download Smokeping and extract it in our home<br />
directory so we can edit it.<br />
<br />
cd<br />
curl -O http://oss.oetiker.ch/smokeping/pub/smokeping-2.4.2.tar.gz<br />
tar zxf smokeping-2.4.2.tar.gz<br />
<br />
= Configuration =<br />
<br />
Smokeping requires you to edit a few files. The unedited files end<br />
with the {{Filename|.dist}} extension. Rename the {{Filename|.dist}}<br />
files to names without the suffix. The ''find'' command does this and<br />
prints out each file that is being renamed and needs editing:<br />
<br />
cd smokeping-2.4.2<br />
find . -name '*.dist' -print -execdir sh -c 'mv {} $(basename {} .dist)' \;<br />
<br />
== Editing Scripts ==<br />
<br />
The files inside the bin/ directory I call scripts. The script files<br />
contain {{Codeline|use lib}} statements. These add a path to search<br />
for when loading perl modules (similar to {{Codeline|$PATH}}). We don't<br />
need these. We will add to the module search path at runtime.<br />
<br />
You must set the proper config file path. The config file is by<br />
default set to {{Filename|etc/config.dist}}. We will remove the<br />
{{Filename|.dist}} suffix. I prefer relative directories so that I<br />
can move the smokeping directory to anywhere I please without re-editing<br />
these files. The downside to using relative paths is you must be sure<br />
to start the daemon and webapp in the proper directory.<br />
<br />
Run this sed command to edit these scripts:<br />
<br />
sed -i -e '/^use lib/d' -e 's/config.dist/config/' bin/*<br />
<br />
== Editing the config file ==<br />
<br />
Next edit the {{Filename|etc/config}} file. The first section of the<br />
{{Filename|etc/config}} file is the easiest to edit. Personalize the<br />
top of the config file to match your information. Replace the absolute<br />
paths to relative paths. The ''General'' section should look similar<br />
to my example below. The comments describe each field.<br />
<br />
{{File|name=config|content=<br />
<nowiki><br />
*** General ***<br />
<br />
owner = Your Name Here # your name<br />
contact = your.email@host.bla # your email<br />
mailhost = your.smtp.server.bla # your mail server<br />
sendmail = /usr/sbin/sendmail # where the sendmail program is<br />
imgcache = public/images # filesystem directory where we store files<br />
imgurl = images # URL directory to find them<br />
datadir = var/pingdata # where we share data between the daemon and webapp<br />
piddir = var # filesystem directory to store PID file<br />
cgiurl = http://yourdomain/smokeping # exterior URL<br />
smokemail = etc/smokemail # new relative dir, remove .dist<br />
tmail = etc/tmail # ditto<br />
syslogfacility = local0<br />
# each probe is now run in its own process<br />
# disable this to revert to the old behaviour<br />
# concurrentprobes = no<br />
</nowiki><br />
}}<br />
<br />
{{Note|If you don't have the sendmail program installed (ie from postfix or sendmail) then use something else instead like {{Filename|/bin/false}}. The file you specify must exist or smokeping will error out.}}<br />
<br />
We are setting up the bare minimum and are not using alerts, so comment out<br />
the {{Codeline|*** Alerts ***}} section. Scroll down to the {{Codeline|*** Presentation ***}} section and replace the '''template''' path with a relative path:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Presentation ***<br />
<br />
template = etc/basepage.html<br />
</nowiki>}}<br />
<br />
The {{Codeline|*** Probes ***}} section specify which probes are<br />
active. By default only the ''FPing'' probe is set. Leave this for<br />
now. Comment out or delete the {{Codeline|*** Slaves ***}} section,<br />
you don't have any slaves... right? Scroll down to the<br />
{{Codeline|*** Targets ***}} section. This is where you specify which<br />
hosts to ping. Replace it with a host you would like to collect statistics on,<br />
like so:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Targets ***<br />
<br />
probe = FPing<br />
<br />
menu = Top<br />
title = Network Latency Grapher<br />
remark = Hello World!<br />
<br />
+ ArchLinux<br />
menu = ArchLinux<br />
title = ArchLinux Hosts<br />
host = /ArchLinux/ArchLinux_News /ArchLinux/ArchLinux_BBS /ArchLinux/ArchLinux_Wiki<br />
<br />
++ ArchLinux_News<br />
menu = News<br />
title = ArchLinux Main Site<br />
host = archlinux.org<br />
<br />
++ ArchLinux_BBS<br />
menu = BBS<br />
title = ArchLinux BBS<br />
host = bbs.archlinux.org<br />
<br />
++ ArchLinux_Wiki<br />
menu = Wiki<br />
title = ArchLinux Wiki<br />
host = wiki.archlinux.org <br />
</nowiki>}}<br />
<br />
Each '''+''' character defines a section in our hierarchy. Spaces are<br />
not allowed in the section names. You can define {{Codeline|host}} as<br />
either a real host name or the path to another section to generate a<br />
multiple host chart. These hosts are all on the same machine so the<br />
statistics aren't very interesting.<br />
<br />
You can learn more about the Smokeping config<br />
file with the examples at<br />
http://oss.oetiker.ch/smokeping/doc/smokeping_examples.en.html<br />
<br />
For now let's just try to get things started.<br />
<br />
= Setup =<br />
<br />
Create the directories we specified or else smokeping will error out.<br />
<br />
mkdir -p var/pingdata public/images<br />
<br />
Now we create the PSGI app that will wrap the CGI script. If you open<br />
the htdocs/smokeping.cgi file you will see it is really simple and just<br />
calls the ''Smokeping'' module's ''cgi'' subroutine. We are going to fool<br />
the CGI code into thinking that it is using the CGI environment. Here<br />
is where Plack comes into play.<br />
<br />
Inside the smokeping dir, create a new file called<br />
{{Filename|app.psgi}}. Copy/paste the following into the file:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*-<br />
<br />
use Plack::App::Directory;<br />
use Plack::Builder;<br />
use CGI::Emulate::PSGI;<br />
<br />
use CGI qw();<br />
<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
my $fileapp = Plack::App::Directory->new<br />
({ 'root' => 'public' })->to_app;<br />
<br />
$smokeping = CGI::Emulate::PSGI->handler( $smokeping );<br />
<br />
builder {<br />
mount "/" => $smokeping;<br />
mount "/smokeping/" => $fileapp;<br />
};<br />
</nowiki><br />
}}<br />
<br />
This file does the same thing as {{Filename|smokeping.cgi}}. We are in<br />
effect fooling smokeping to think it is still run with CGI. The<br />
difference is we wrap the CGI app into a PSGI app. This allows it to<br />
run persistently among other things. The concept of SpeedyCGI is<br />
similar. We also add file serving for the static files like images. The<br />
default, empty, or root path is set to the smokeping app itself and<br />
anything under the {{Filename|smokeping/}} URL component serves a<br />
file from the {{Filename|public/}} directory. The only files we<br />
serve are the graph images files.<br />
<br />
= Testing =<br />
<br />
Now we are going to test our webapp. Type the following commands<br />
to start the smokeping daemon and a webserver:<br />
<br />
perl -Ilib bin/smokeping<br />
plackup -Ilib<br />
<br />
Here the '''-I''' switch adds the {{Filename|lib}} directory to perl's<br />
module search path. This does the same thing as {{Codeline|use lib}};<br />
<br />
Our commands start the smokeping daemon and a simple server for the<br />
webapp which listens on port 5000 by default. Go to the webpage<br />
(''yourdomain.com:5000'') and look at the pretty graph. Keep in mind<br />
the default setup pings every 5 minutes so you may have to wait for<br />
some data to appear. If something goes wrong, fix it before<br />
continuing.<br />
<br />
If it works and that is all you wanted feel free to stop here. You can<br />
run your webapp with a better server by installing perl-starman from<br />
the AUR. Starman is a ''fast'' production quality pre-forking<br />
server. I usually set it to a very low number of worker processes though<br />
because I don't receive alot of traffic.<br />
<br />
You should set the plack environment to ''deployment'' if you don't<br />
want/need debugging information like stack traces printed. By default<br />
''Plack'' runs in the ''development'' environment. For example:<br />
<br />
starman -Ilib -p 80 -E deployment --workers 2 &<br />
<br />
The '''-I''' switch does the same thing as ''PERL5LIB''. '''-p''' listens on<br />
port 80, the default http port. '''-E''' sets the plack environment to<br />
''deployment'' which disables bug checking.<br />
<br />
= Deployment =<br />
<br />
{{Note|This section is incomplete and needs a walkthrough written for it}}<br />
<br />
Now you should probably setup a user for smokeping and<br />
create a {{Filename|/etc/rc.d/}} daemon startup script to start the<br />
smokeping daemon as well as the FastCGI webapp daemon. You could also<br />
create a directory under {{Filename|/srv/http}} for smokeping. When<br />
you copy the files, you only need the following files and directories<br />
and you can leave the rest.<br />
<br />
* app.psgi<br />
* lib/<br />
* etc/<br />
* var/<br />
* public/<br />
<br />
Copy those files and directories into the destination. The rest is<br />
junk! Make sure to ''cd'' into the destination before starting the<br />
smokeping daemon and FastCGI webapp.<br />
<br />
You should also setup the webserver to serve the files and remove file<br />
serving code from from {{Filename|app.psgi}} so it looks like this:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*- <br />
<br />
use CGI::Emulate::PSGI;<br />
use CGI qw();<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
CGI::Emulate::PSGI->handler( $smokeping );<br />
</nowiki><br />
}}<br />
<br />
Much simpler!<br />
<br />
== Proxied ==<br />
<br />
You can continue to use a plack web server. If you do please upgrade from plackup<br />
which is designed for testing purposes. The main web server will act as a proxy and<br />
forward requests to the plack server.<br />
<br />
=== nginx ===<br />
<br />
I use nginx so here is a quick walkthrough. I like this method because<br />
it is quick and easy. Make sure that the port that the Plack server is<br />
running on is blocked from outside by a proxy (like<br />
[[iptables]]). Edit your nginx configuration file similar to this:<br />
<br />
{{File|name=nginx.conf|content=<br />
<nowiki><br />
location /smokeping {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
proxy_buffers 8 16k;<br />
proxy_buffer_size 32k;<br />
proxy_pass http://localhost:9003/;<br />
}<br />
<br />
location /smokeping/ {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
alias /srv/http/smokeping/public/;<br />
}<br />
</nowiki><br />
}}<br />
<br />
Nginx will serve our image files for us and will pass any request for<br />
''/smokeping'' to the proxied webapp server. When you start the proxied<br />
server, make sure it has the port set:<br />
<br />
cd /srv/http/smokeping<br />
starman -Ilib -p 9003 -E deployment --workers 2 &<br />
<br />
Feel free to use any port you like instead of 9003.<br />
<br />
== FastCGI ==<br />
<br />
You can easily set up the webapp to use FastCGI. Just use plackup to<br />
start the FastCGI server process:<br />
<br />
plackup -s FCGI --listen /var/run/smokeping.sock --daemonize --nproc 4<br />
<br />
(You will need the perl FCGI module installed via the 'perl-fcgi' package)<br />
<br />
Now just setup your web server (i.e. apache, lighttpd, nginx) to<br />
route traffic to your FastCGI "server" by pointing to the<br />
{{Filename|/var/run/smokeping.sock}} socket.<br />
<br />
= Advanced Configuration =<br />
<br />
{{Note|This section is incomplete.}}<br />
<br />
There are many idiosyncracies to the smokeping configuration file. There is also alot<br />
of power. You can setup many different types of probes. You can setup slave smokeping<br />
servers that can send their statistics and show you probes from other servers. You<br />
can also create your custom probes in perl. I haven't gotten that far along and the<br />
example configuration file above should be a good start.<br />
<br />
== Idiosyncracies ==<br />
<br />
I have found some things to avoid in config files through trial and error. Make sure<br />
you do not use spaces or periods in section names. You should probably avoid forward<br />
slashes too. Sections are defined with '''+'''s.<br />
<br />
This is probably because the RRD files are stored under the data directory with the<br />
same exact names as the sections.<br />
<br />
= Bugs =<br />
<br />
There are a few bugs I have noticed.<br />
<br />
== Tr.cgi ==<br />
<br />
The traceroute CGI script simply doesn't work. This could be a mistake<br />
on my part or a bug in the code. I don't need it or like it so I<br />
simply don't use it.<br />
<br />
== Cropper ==<br />
<br />
I had noticed that if I try to use the javascript cropper it does not work<br />
very well. Click on a graph long enough and it will pop up. If I try to<br />
crop a graph to zoom in, the server crashes. '''Hard'''.<br />
<br />
I decided to remove the cropper until I could track down the bug. To<br />
do this remove the {{Codeline|<script>}} tags inside the<br />
{{Filename|etc/basepage.html}} file. You may have noticed that I<br />
created a new file serving dir called {{Filename|public/}}. This<br />
avoids all the old files I don't use that are needed for the cropper<br />
and the traceroute script. This isn't the most ideal fix and the<br />
server is likely still vulnerable to crashes but at least they won't<br />
happen on '''accident'''.<br />
<br />
== CPU Crunch ==<br />
<br />
Every once and awhile I noticed that the CPU usage goes crazy for the<br />
web interface. When I use Twiggy the CPU usage goes up to 100% and<br />
stays there, locking up the server. I have decided instead to use the<br />
Starman server. That way if one process goes to crap Starman will<br />
spawn another one. This could be caused by a race condition in the<br />
Smokeping module. I haven't really tried to track it down.</div>Justerhttps://wiki.archlinux.org/index.php?title=Smokeping&diff=120534Smokeping2010-11-02T19:45:39Z<p>Juster: /* Editing Scripts */ Add missing closing bracket to Filename</p>
<hr />
<div>[[Category:Networking (English)]]<br />
<br />
= Introduction =<br />
<br />
Smokeping allows you to probe a list of servers, store that data using<br />
RRDtool, and generate statistical charts based on RRDtool's<br />
output. Smokeping consists of two parts. A daemon runs in the<br />
background pinging and collecting data at set intervals. A web<br />
interface displays that data in the form of graphs.<br />
<br />
;Smokeping Website: http://oss.oetiker.ch/smokeping/index.en.html<br />
<br />
This guide only sets up the smokeping daemon and CGI script. We<br />
do not set up advanced features like the AJAX traceroute or the<br />
JavaScript graph cropper. Why? Because these did not work properly<br />
for me and I don't need these features enough to figure out why.<br />
<br />
= Installation =<br />
<br />
The smokeping CGI script runs under [http://daemoninc.com/SpeedyCGI/ SpeedyCGI].<br />
SpeedyCGI is a modified version of perl that allows<br />
scripts to be run persistently. Without persistence, the smokeping CGI<br />
script must load all modules and data on every webpage view. This<br />
would be too slow.<br />
<br />
SpeedyCGI has not been updated since 2003 (as of Nov 1, 2010) and no<br />
longer compiles with perl, which has since gone through API changes.<br />
Instead of using SpeedyCGI for persistence, we will convert the<br />
{{Filename|smokeping.cgi}} script into a<br />
[http://search.cpan.org/~miyagawa/PSGI-1.03/PSGI.pod PSGI] webapp<br />
which can then be made persistent a variety of ways. More on that<br />
later.<br />
<br />
We will just be installing the smokeping chart interface as a<br />
webapp. The traceroute feature will not be included.<br />
<br />
== Prerequisites ==<br />
<br />
;perl: The smokeping daemon and cgi script are perl scripts. We will use the system-wide perl for this example. You might also consider a perl for only the smokeping app. You may also compile an old version of perl (try 5.8.x) if you choose to use SpeedyCGI.<br />
;fping: Smokeping has many many different ways to probe a host. The simplest and default method is a simple ping probe which requires the fping program.<br />
;rrdtool: RRDTool is created by the same author as smokeping. RRDTool collects and displays statistical information in a disk-efficient manner.<br />
;Plack: Plack is perl's version of Ruby's rack. Plack is the implementation of the PSGI specification. PSGI is like Python's WSGI. By using Plack/PSGI we can run the smokeping.cgi as a webapp on any number of backends (proxied, FreeCGI, mod_perl, CGI, etc).<br />
;perl-cgi-emulate-psgi: The CGI::Emulate::PSGI fools the smokeping.cgi script into thinking it is running in a CGI environment, when instead it is executing inside a PSGI app.<br />
;ttf-dejavu: Without this font the graphs are unreadable and the letters are replaced with blocks.<br />
<br />
=== Optional Prerequisites ===<br />
<br />
If you want to use other probes such as the DNS or http probe you will<br />
need other packages shown below. We will only be setting up the basic<br />
ping probe in this example.<br />
<br />
{| border="1"<br />
! Probe !! Package Needed<br />
|-<br />
| Curl || curl<br />
|-<br />
| DNS || dig<br />
|-<br />
| EchoPing || echoping (AUR)<br />
|-<br />
| SSH || ssh<br />
|-<br />
| TelnetIOSPing || perl-net-telnet<br />
|-<br />
| AnotherDNS || perl-net-dns<br />
|-<br />
| LDAP || perl-net-ldap<br />
|-<br />
| LDAP (tls) || perl-io-socket-ssl<br />
|-<br />
| Authen || perl-authen-radius<br />
|}<br />
<br />
In our example we use a simple Plack-based webserver. You may wish to<br />
install a full-fledged webserver. If you wish to use the master/slave<br />
functionality of Smokeping you will need the ''perl-libwww''<br />
package. If you want to probe IPv6 servers you will need the<br />
''perl-socket6'' package from the AUR. I will not be covering any of<br />
these features and will stick to the bare minimum.<br />
<br />
== Installing Packages ==<br />
<br />
First we can install the packages that are available from the official<br />
repositories:<br />
<br />
sudo pacman -S rrdtool fping perl ttf-dejavu<br />
<br />
Now install packages from the AUR by using an [[AUR Helpers|AUR helper]]<br />
like clyde or packer or even manually if you prefer:<br />
<br />
packer -S perl-cgi-emulate-psgi perl-plack<br />
<br />
(Plack is outdated on the AUR. If you experience problems use a CPAN<br />
packager like pacpan/bauerbill or the CPANPLUS plugin<br />
CPANPLUS::Dist::Arch to get the latest version. See [[Perl Package Guidelines]]<br />
for links.)<br />
<br />
== Downloading Smokeping ==<br />
<br />
We are going to download Smokeping and extract it in our home<br />
directory so we can edit it.<br />
<br />
cd<br />
curl -O http://oss.oetiker.ch/smokeping/pub/smokeping-2.4.2.tar.gz<br />
tar zxf smokeping-2.4.2.tar.gz<br />
<br />
= Configuration =<br />
<br />
Smokeping requires you to edit a few files. The unedited files end<br />
with the {{Filename|.dist}} extension. Rename the {{Filename|.dist}}<br />
files to names without the suffix. The ''find'' command does this and<br />
prints out each file that is being renamed and needs editing:<br />
<br />
cd smokeping-2.4.2<br />
find . -name '*.dist' -print -execdir sh -c 'mv {} $(basename {} .dist)' \;<br />
<br />
== Editing Scripts ==<br />
<br />
The files inside the bin/ directory I call scripts. The script files<br />
contain {{Codeline|use lib}} statements. These add a path to search<br />
for when loading perl modules (similar to {{Codeline|$PATH}}). We don't<br />
need these. We will add to the module search path at runtime.<br />
<br />
You must set the proper config file path. The config file is by<br />
default set to {{Filename|etc/config.dist}}. We will remove the<br />
{{Filename|.dist}} suffix. I prefer relative directories so that I<br />
can move the smokeping directory to anywhere I please without re-editing<br />
these files. The downside to using relative paths is you must be sure<br />
to start the daemon and webapp in the proper directory.<br />
<br />
Run this sed command to edit these scripts:<br />
<br />
sed -i -e '/^use lib/d' -e 's/config.dist/config/' bin/*<br />
<br />
== Editing the config file ==<br />
<br />
Next edit the {{Filename|etc/config}} file. The first section of the<br />
{{Filename|etc/config}} file is the easiest to edit. Personalize the<br />
top of the config file to match your information. Replace the absolute<br />
paths to relative paths. The ''General'' section should look similar<br />
to my example below. The comments describe each field.<br />
<br />
{{File|name=config|content=<br />
<nowiki><br />
*** General ***<br />
<br />
owner = Your Name Here # your name<br />
contact = your.email@host.bla # your email<br />
mailhost = your.smtp.server.bla # your mail server<br />
sendmail = /usr/sbin/sendmail # where the sendmail program is<br />
imgcache = public/images # filesystem directory where we store files<br />
imgurl = images # URL directory to find them<br />
datadir = var/pingdata # where we share data between the daemon and webapp<br />
piddir = var # filesystem directory to store PID file<br />
cgiurl = http://yourdomain/smokeping # exterior URL<br />
smokemail = etc/smokemail # new relative dir, remove .dist<br />
tmail = etc/tmail # ditto<br />
syslogfacility = local0<br />
# each probe is now run in its own process<br />
# disable this to revert to the old behaviour<br />
# concurrentprobes = no<br />
</nowiki><br />
}}<br />
<br />
{{Note|If you don't have the sendmail program installed (ie from postfix or sendmail) then use something else instead like {{Filename|/bin/false}}. The file you specify must exist or smokeping will error out.}}<br />
<br />
We are setting up the bare minimum and are not using alerts, so comment out<br />
the {{Codeline|*** Alerts ***}} section. Scroll down to the {{Codeline|*** Presentation ***}} section and replace the '''template''' path with a relative path:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Presentation ***<br />
<br />
template = etc/basepage.html<br />
</nowiki>}}<br />
<br />
The {{Codeline|*** Probes ***}} section specify which probes are<br />
active. By default only the ''FPing'' probe is set. Leave this for<br />
now. Comment out or delete the {{Codeline|*** Slaves ***}} section,<br />
you don't have any slaves... right? Scroll down to the<br />
{{Codeline|*** Targets ***}} section. This is where you specify which<br />
hosts to ping. Replace it with a host you would like to collect statistics on,<br />
like so:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Targets ***<br />
<br />
probe = FPing<br />
<br />
menu = Top<br />
title = Network Latency Grapher<br />
remark = Hello World!<br />
<br />
+ ArchLinux<br />
menu = ArchLinux<br />
title = ArchLinux Hosts<br />
host = /ArchLinux/ArchLinux_News /ArchLinux/ArchLinux_BBS /ArchLinux/ArchLinux_Wiki<br />
<br />
++ ArchLinux_News<br />
menu = News<br />
title = ArchLinux Main Site<br />
host = archlinux.org<br />
<br />
++ ArchLinux_BBS<br />
menu = BBS<br />
title = ArchLinux BBS<br />
host = bbs.archlinux.org<br />
<br />
++ ArchLinux_Wiki<br />
menu = Wiki<br />
title = ArchLinux Wiki<br />
host = wiki.archlinux.org <br />
</nowiki>}}<br />
<br />
Each '''+''' character defines a section in our hierarchy. Spaces are<br />
not allowed in the section names. You can define {{Codeline|host}} as<br />
either a real host name or the path to another section to generate a<br />
multiple host chart. These hosts are all on the same machine so the<br />
statistics aren't very interesting.<br />
<br />
You can learn more about the Smokeping config<br />
file with the examples at<br />
http://oss.oetiker.ch/smokeping/doc/smokeping_examples.en.html<br />
<br />
For now let's just try to get things started.<br />
<br />
= Setup =<br />
<br />
Create the directories we specified or else smokeping will error out.<br />
<br />
mkdir -p var/pingdata public/images<br />
<br />
Now we create the PSGI app that will wrap the CGI script. If you open<br />
the htdocs/smokeping.cgi file you will see it is really simple and just<br />
calls the ''Smokeping'' module's ''cgi'' subroutine. We are going to fool<br />
the CGI code into thinking that it is using the CGI environment. Here<br />
is where Plack comes into play.<br />
<br />
Inside the smokeping dir, create a new file called<br />
{{Filename|app.psgi}}. Copy/paste the following into the file:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*-<br />
<br />
use Plack::App::Directory;<br />
use Plack::Builder;<br />
use CGI::Emulate::PSGI;<br />
<br />
use CGI qw();<br />
<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
my $fileapp = Plack::App::Directory->new<br />
({ 'root' => 'public' })->to_app;<br />
<br />
$smokeping = CGI::Emulate::PSGI->handler( $smokeping );<br />
<br />
builder {<br />
mount "/" => $smokeping;<br />
mount "/smokeping/" => $fileapp;<br />
};<br />
</nowiki><br />
}}<br />
<br />
This file does the same thing as {{Filename|smokeping.cgi}}. We are in<br />
effect fooling smokeping to think it is still run with CGI. The<br />
difference is we wrap the CGI app into a PSGI app. This allows it to<br />
run persistently among other things. The concept of SpeedyCGI is<br />
similar. We also add file serving for the static files like images. The<br />
default, empty, or root path is set to the smokeping app itself and<br />
anything under the {{Filename|smokeping/}} URL component serves a<br />
file from the {{Filename|public/}} directory. The only files we<br />
serve are the graph images files.<br />
<br />
= Testing =<br />
<br />
Now we are going to test our webapp. Type the following commands<br />
to start the smokeping daemon and a webserver:<br />
<br />
perl -Ilib bin/smokeping<br />
plackup -Ilib<br />
<br />
Here the '''-I''' switch adds the {{Filename|lib}} directory to perl's<br />
module search path. This does the same thing as {{Codeline|use lib}};<br />
<br />
Our commands start the smokeping daemon and a simple server for the<br />
webapp which listens on port 5000 by default. Go to the webpage<br />
(''yourdomain.com:5000'') and look at the pretty graph. Keep in mind<br />
the default setup pings every 5 minutes so you may have to wait for<br />
some data to appear. If something goes wrong, fix it before<br />
continuing.<br />
<br />
If it works and that is all you wanted feel free to stop here. You can<br />
run your webapp with a better server by installing perl-starman from<br />
the AUR. Starman is a ''fast'' production quality pre-forking<br />
server. I usually set it to a very low number of worker processes though<br />
because I don't receive alot of traffic.<br />
<br />
You should set the plack environment to ''deployment'' if you don't<br />
want/need debugging information like stack traces printed. By default<br />
''Plack'' runs in the ''development'' environment. For example:<br />
<br />
starman -Ilib -p 80 -E deployment --workers 2 &<br />
<br />
The '''-I''' switch does the same thing as ''PERL5LIB''. '''-p''' listens on<br />
port 80, the default http port. '''-E''' sets the plack environment to<br />
''deployment'' which disables bug checking.<br />
<br />
= Deployment =<br />
<br />
{{Note|This section is incomplete and needs a walkthrough written for it}}<br />
<br />
Now you should probably setup a user for smokeping and<br />
create a {{Filename|/etc/rc.d/}} daemon startup script to start the<br />
smokeping daemon as well as the FastCGI webapp daemon. You could also<br />
create a directory under {{Filename|/srv/http}} for smokeping. When<br />
you copy the files, you only need the following files and directories<br />
and you can leave the rest.<br />
<br />
* app.psgi<br />
* lib/<br />
* etc/<br />
* var/<br />
* public/<br />
<br />
Copy those files and directories into the destination. The rest is<br />
junk! Make sure to ''cd'' into the destination before starting the<br />
smokeping daemon and FastCGI webapp.<br />
<br />
You should also setup the webserver to serve the files and remove file<br />
serving code from from {{Filename|app.psgi}} so it looks like this:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*- <br />
<br />
use CGI::Emulate::PSGI;<br />
use CGI qw();<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
CGI::Emulate::PSGI->handler( $smokeping );<br />
</nowiki><br />
}}<br />
<br />
Much simpler!<br />
<br />
== Proxied ==<br />
<br />
You can continue to use a plack web server. If you do please upgrade from plackup<br />
which is designed for testing purposes. The main web server will act as a proxy and<br />
forward requests to the plack server.<br />
<br />
=== nginx ===<br />
<br />
I use nginx so here is a quick walkthrough. I like this method because<br />
it is quick and easy. Make sure that the port that the Plack server is<br />
running on is blocked from outside by a proxy (like<br />
[[iptables]]). Edit your nginx configuration file similar to this:<br />
<br />
{{File|name=nginx.conf|content=<br />
<nowiki><br />
location /smokeping {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
proxy_buffers 8 16k;<br />
proxy_buffer_size 32k;<br />
proxy_pass http://localhost:9003/;<br />
}<br />
<br />
location /smokeping/ {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
alias /srv/http/smokeping/public/;<br />
}<br />
</nowiki><br />
}}<br />
<br />
Nginx will serve our image files for us and will pass any request for<br />
''/smokeping'' to the proxied webapp server. When you start the proxied<br />
server, make sure it has the port set:<br />
<br />
cd /srv/http/smokeping<br />
starman -Ilib -p 9003 -E deployment --workers 2 &<br />
<br />
Feel free to use any port you like instead of 9003.<br />
<br />
== FastCGI ==<br />
<br />
You can easily set up the webapp to use FastCGI. Just use plackup to<br />
start the FastCGI server process:<br />
<br />
plackup -s FCGI --listen /var/run/smokeping.sock --daemonize --nproc 4<br />
<br />
(You will need the perl FCGI module installed via the 'perl-fcgi' package)<br />
<br />
Now just setup your web server (i.e. apache, lighttpd, nginx) to<br />
route traffic to your FastCGI "server" by pointing to the<br />
{{Filename|/var/run/smokeping.sock}} socket.<br />
<br />
= Advanced Configuration =<br />
<br />
{{Note|This section is incomplete.}}<br />
<br />
There are many idiosyncracies to the smokeping configuration file. There is also alot<br />
of power. You can setup many different types of probes. You can setup slave smokeping<br />
servers that can send their statistics and show you probes from other servers. You<br />
can also create your custom probes in perl. I haven't gotten that far along and the<br />
example configuration file above should be a good start.<br />
<br />
== Idiosyncracies ==<br />
<br />
I have found some things to avoid in config files through trial and error. Make sure<br />
you do not use spaces or periods in section names. You should probably avoid forward<br />
slashes too. Sections are defined with '''+'''s.<br />
<br />
This is probably because the RRD files are stored under the data directory with the<br />
same exact names as the sections.<br />
<br />
= Bugs =<br />
<br />
There are a few bugs I have noticed.<br />
<br />
== Tr.cgi ==<br />
<br />
The traceroute CGI script simply doesn't work. This could be a mistake<br />
on my part or a bug in the code. I don't need it or like it so I<br />
simply don't use it.<br />
<br />
== Cropper ==<br />
<br />
I had noticed that if I try to use the javascript cropper it does not work<br />
very well. Click on a graph long enough and it will pop up. If I try to<br />
crop a graph to zoom in, the server crashes. '''Hard'''.<br />
<br />
I decided to remove the cropper until I could track down the bug. To<br />
do this remove the {{Codeline|<script>}} tags inside the<br />
{{Filename|etc/basepage.html}} file. You may have noticed that I<br />
created a new file serving dir called {{Filename|public/}}. This<br />
avoids all the old files I don't use that are needed for the cropper<br />
and the traceroute script. This isn't the most ideal fix and the<br />
server is likely still vulnerable to crashes but at least they won't<br />
happen on '''accident'''.<br />
<br />
== CPU Crunch ==<br />
<br />
Every once and awhile I noticed that the CPU usage goes crazy for the<br />
web interface. When I use Twiggy the CPU usage goes up to 100% and<br />
stays there, locking up the server. I have decided instead to use the<br />
Starman server. That way if one process goes to crap Starman will<br />
spawn another one. This could be caused by a race condition in the<br />
Smokeping module. I haven't really tried to track it down.</div>Justerhttps://wiki.archlinux.org/index.php?title=Smokeping&diff=120471Smokeping2010-11-01T20:29:54Z<p>Juster: /* FastCGI */ add missing parameter to fastcgi command</p>
<hr />
<div>[[Category:Networking (English)]]<br />
<br />
= Introduction =<br />
<br />
Smokeping allows you to probe a list of servers, store that data using<br />
RRDtool, and generate statistical charts based on RRDtool's<br />
output. Smokeping consists of two parts. A daemon runs in the<br />
background pinging and collecting data at set intervals. A web<br />
interface displays that data in the form of graphs.<br />
<br />
;Smokeping Website: http://oss.oetiker.ch/smokeping/index.en.html<br />
<br />
This guide only sets up the smokeping daemon and CGI script. We<br />
do not set up advanced features like the AJAX traceroute or the<br />
JavaScript graph cropper. Why? Because these did not work properly<br />
for me and I don't need these features enough to figure out why.<br />
<br />
= Installation =<br />
<br />
The smokeping CGI script runs under [http://daemoninc.com/SpeedyCGI/ SpeedyCGI].<br />
SpeedyCGI is a modified version of perl that allows<br />
scripts to be run persistently. Without persistence, the smokeping CGI<br />
script must load all modules and data on every webpage view. This<br />
would be too slow.<br />
<br />
SpeedyCGI has not been updated since 2003 (as of Nov 1, 2010) and no<br />
longer compiles with perl, which has since gone through API changes.<br />
Instead of using SpeedyCGI for persistence, we will convert the<br />
{{Filename|smokeping.cgi}} script into a<br />
[http://search.cpan.org/~miyagawa/PSGI-1.03/PSGI.pod PSGI] webapp<br />
which can then be made persistent a variety of ways. More on that<br />
later.<br />
<br />
We will just be installing the smokeping chart interface as a<br />
webapp. The traceroute feature will not be included.<br />
<br />
== Prerequisites ==<br />
<br />
;perl: The smokeping daemon and cgi script are perl scripts. We will use the system-wide perl for this example. You might also consider a perl for only the smokeping app. You may also compile an old version of perl (try 5.8.x) if you choose to use SpeedyCGI.<br />
;fping: Smokeping has many many different ways to probe a host. The simplest and default method is a simple ping probe which requires the fping program.<br />
;rrdtool: RRDTool is created by the same author as smokeping. RRDTool collects and displays statistical information in a disk-efficient manner.<br />
;Plack: Plack is perl's version of Ruby's rack. Plack is the implementation of the PSGI specification. PSGI is like Python's WSGI. By using Plack/PSGI we can run the smokeping.cgi as a webapp on any number of backends (proxied, FreeCGI, mod_perl, CGI, etc).<br />
;perl-cgi-emulate-psgi: The CGI::Emulate::PSGI fools the smokeping.cgi script into thinking it is running in a CGI environment, when instead it is executing inside a PSGI app.<br />
;ttf-dejavu: Without this font the graphs are unreadable and the letters are replaced with blocks.<br />
<br />
=== Optional Prerequisites ===<br />
<br />
If you want to use other probes such as the DNS or http probe you will<br />
need other packages shown below. We will only be setting up the basic<br />
ping probe in this example.<br />
<br />
{| border="1"<br />
! Probe !! Package Needed<br />
|-<br />
| Curl || curl<br />
|-<br />
| DNS || dig<br />
|-<br />
| EchoPing || echoping (AUR)<br />
|-<br />
| SSH || ssh<br />
|-<br />
| TelnetIOSPing || perl-net-telnet<br />
|-<br />
| AnotherDNS || perl-net-dns<br />
|-<br />
| LDAP || perl-net-ldap<br />
|-<br />
| LDAP (tls) || perl-io-socket-ssl<br />
|-<br />
| Authen || perl-authen-radius<br />
|}<br />
<br />
In our example we use a simple Plack-based webserver. You may wish to<br />
install a full-fledged webserver. If you wish to use the master/slave<br />
functionality of Smokeping you will need the ''perl-libwww''<br />
package. If you want to probe IPv6 servers you will need the<br />
''perl-socket6'' package from the AUR. I will not be covering any of<br />
these features and will stick to the bare minimum.<br />
<br />
== Installing Packages ==<br />
<br />
First we can install the packages that are available from the official<br />
repositories:<br />
<br />
sudo pacman -S rrdtool fping perl ttf-dejavu<br />
<br />
Now install packages from the AUR by using an [[AUR Helpers|AUR helper]]<br />
like clyde or packer or even manually if you prefer:<br />
<br />
packer -S perl-cgi-emulate-psgi perl-plack<br />
<br />
(Plack is outdated on the AUR. If you experience problems use a CPAN<br />
packager like pacpan/bauerbill or the CPANPLUS plugin<br />
CPANPLUS::Dist::Arch to get the latest version. See [[Perl Package Guidelines]]<br />
for links.)<br />
<br />
== Downloading Smokeping ==<br />
<br />
We are going to download Smokeping and extract it in our home<br />
directory so we can edit it.<br />
<br />
cd<br />
curl -O http://oss.oetiker.ch/smokeping/pub/smokeping-2.4.2.tar.gz<br />
tar zxf smokeping-2.4.2.tar.gz<br />
<br />
= Configuration =<br />
<br />
Smokeping requires you to edit a few files. The unedited files end<br />
with the {{Filename|.dist}} extension. Rename the {{Filename|.dist}}<br />
files to names without the suffix. The ''find'' command does this and<br />
prints out each file that is being renamed and needs editing:<br />
<br />
cd smokeping-2.4.2<br />
find . -name '*.dist' -print -execdir sh -c 'mv {} $(basename {} .dist)' \;<br />
<br />
== Editing Scripts ==<br />
<br />
The files inside the bin/ directory I call scripts. The script files<br />
contain {{Codeline|use lib}} statements. These add a path to search<br />
for when loading perl modules (similar to {{Codeline|$PATH}}). We don't<br />
need these. We will add to the module search path at runtime.<br />
<br />
You must set the proper config file path. The config file is by<br />
default set to {{Filename|etc/config.dist}. We will remove the<br />
{{Filename|.dist}} suffix. I prefer relative directories so that I<br />
can move the smokeping directory to anywhere I please without re-editing<br />
these files. The downside to using relative paths is you must be sure<br />
to start the daemon and webapp in the proper directory.<br />
<br />
Run this sed command to edit these scripts:<br />
<br />
sed -i -e '/^use lib/d' -e 's/config.dist/config/' bin/*<br />
<br />
== Editing the config file ==<br />
<br />
Next edit the {{Filename|etc/config}} file. The first section of the<br />
{{Filename|etc/config}} file is the easiest to edit. Personalize the<br />
top of the config file to match your information. Replace the absolute<br />
paths to relative paths. The ''General'' section should look similar<br />
to my example below. The comments describe each field.<br />
<br />
{{File|name=config|content=<br />
<nowiki><br />
*** General ***<br />
<br />
owner = Your Name Here # your name<br />
contact = your.email@host.bla # your email<br />
mailhost = your.smtp.server.bla # your mail server<br />
sendmail = /usr/sbin/sendmail # where the sendmail program is<br />
imgcache = public/images # filesystem directory where we store files<br />
imgurl = images # URL directory to find them<br />
datadir = var/pingdata # where we share data between the daemon and webapp<br />
piddir = var # filesystem directory to store PID file<br />
cgiurl = http://yourdomain/smokeping # exterior URL<br />
smokemail = etc/smokemail # new relative dir, remove .dist<br />
tmail = etc/tmail # ditto<br />
syslogfacility = local0<br />
# each probe is now run in its own process<br />
# disable this to revert to the old behaviour<br />
# concurrentprobes = no<br />
</nowiki><br />
}}<br />
<br />
{{Note|If you don't have the sendmail program installed (ie from postfix or sendmail) then use something else instead like {{Filename|/bin/false}}. The file you specify must exist or smokeping will error out.}}<br />
<br />
We are setting up the bare minimum and are not using alerts, so comment out<br />
the {{Codeline|*** Alerts ***}} section. Scroll down to the {{Codeline|*** Presentation ***}} section and replace the '''template''' path with a relative path:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Presentation ***<br />
<br />
template = etc/basepage.html<br />
</nowiki>}}<br />
<br />
The {{Codeline|*** Probes ***}} section specify which probes are<br />
active. By default only the ''FPing'' probe is set. Leave this for<br />
now. Comment out or delete the {{Codeline|*** Slaves ***}} section,<br />
you don't have any slaves... right? Scroll down to the<br />
{{Codeline|*** Targets ***}} section. This is where you specify which<br />
hosts to ping. Replace it with a host you would like to collect statistics on,<br />
like so:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Targets ***<br />
<br />
probe = FPing<br />
<br />
menu = Top<br />
title = Network Latency Grapher<br />
remark = Hello World!<br />
<br />
+ ArchLinux<br />
menu = ArchLinux<br />
title = ArchLinux Hosts<br />
host = /ArchLinux/ArchLinux_News /ArchLinux/ArchLinux_BBS /ArchLinux/ArchLinux_Wiki<br />
<br />
++ ArchLinux_News<br />
menu = News<br />
title = ArchLinux Main Site<br />
host = archlinux.org<br />
<br />
++ ArchLinux_BBS<br />
menu = BBS<br />
title = ArchLinux BBS<br />
host = bbs.archlinux.org<br />
<br />
++ ArchLinux_Wiki<br />
menu = Wiki<br />
title = ArchLinux Wiki<br />
host = wiki.archlinux.org <br />
</nowiki>}}<br />
<br />
Each '''+''' character defines a section in our hierarchy. Spaces are<br />
not allowed in the section names. You can define {{Codeline|host}} as<br />
either a real host name or the path to another section to generate a<br />
multiple host chart. These hosts are all on the same machine so the<br />
statistics aren't very interesting.<br />
<br />
You can learn more about the Smokeping config<br />
file with the examples at<br />
http://oss.oetiker.ch/smokeping/doc/smokeping_examples.en.html<br />
<br />
For now let's just try to get things started.<br />
<br />
= Setup =<br />
<br />
Create the directories we specified or else smokeping will error out.<br />
<br />
mkdir -p var/pingdata public/images<br />
<br />
Now we create the PSGI app that will wrap the CGI script. If you open<br />
the htdocs/smokeping.cgi file you will see it is really simple and just<br />
calls the ''Smokeping'' module's ''cgi'' subroutine. We are going to fool<br />
the CGI code into thinking that it is using the CGI environment. Here<br />
is where Plack comes into play.<br />
<br />
Inside the smokeping dir, create a new file called<br />
{{Filename|app.psgi}}. Copy/paste the following into the file:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*-<br />
<br />
use Plack::App::Directory;<br />
use Plack::Builder;<br />
use CGI::Emulate::PSGI;<br />
<br />
use CGI qw();<br />
<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
my $fileapp = Plack::App::Directory->new<br />
({ 'root' => 'public' })->to_app;<br />
<br />
$smokeping = CGI::Emulate::PSGI->handler( $smokeping );<br />
<br />
builder {<br />
mount "/" => $smokeping;<br />
mount "/smokeping/" => $fileapp;<br />
};<br />
</nowiki><br />
}}<br />
<br />
This file does the same thing as {{Filename|smokeping.cgi}}. We are in<br />
effect fooling smokeping to think it is still run with CGI. The<br />
difference is we wrap the CGI app into a PSGI app. This allows it to<br />
run persistently among other things. The concept of SpeedyCGI is<br />
similar. We also add file serving for the static files like images. The<br />
default, empty, or root path is set to the smokeping app itself and<br />
anything under the {{Filename|smokeping/}} URL component serves a<br />
file from the {{Filename|public/}} directory. The only files we<br />
serve are the graph images files.<br />
<br />
= Testing =<br />
<br />
Now we are going to test our webapp. Type the following commands<br />
to start the smokeping daemon and a webserver:<br />
<br />
perl -Ilib bin/smokeping<br />
plackup -Ilib<br />
<br />
Here the '''-I''' switch adds the {{Filename|lib}} directory to perl's<br />
module search path. This does the same thing as {{Codeline|use lib}};<br />
<br />
Our commands start the smokeping daemon and a simple server for the<br />
webapp which listens on port 5000 by default. Go to the webpage<br />
(''yourdomain.com:5000'') and look at the pretty graph. Keep in mind<br />
the default setup pings every 5 minutes so you may have to wait for<br />
some data to appear. If something goes wrong, fix it before<br />
continuing.<br />
<br />
If it works and that is all you wanted feel free to stop here. You can<br />
run your webapp with a better server by installing perl-starman from<br />
the AUR. Starman is a ''fast'' production quality pre-forking<br />
server. I usually set it to a very low number of worker processes though<br />
because I don't receive alot of traffic.<br />
<br />
You should set the plack environment to ''deployment'' if you don't<br />
want/need debugging information like stack traces printed. By default<br />
''Plack'' runs in the ''development'' environment. For example:<br />
<br />
starman -Ilib -p 80 -E deployment --workers 2 &<br />
<br />
The '''-I''' switch does the same thing as ''PERL5LIB''. '''-p''' listens on<br />
port 80, the default http port. '''-E''' sets the plack environment to<br />
''deployment'' which disables bug checking.<br />
<br />
= Deployment =<br />
<br />
{{Note|This section is incomplete and needs a walkthrough written for it}}<br />
<br />
Now you should probably setup a user for smokeping and<br />
create a {{Filename|/etc/rc.d/}} daemon startup script to start the<br />
smokeping daemon as well as the FastCGI webapp daemon. You could also<br />
create a directory under {{Filename|/srv/http}} for smokeping. When<br />
you copy the files, you only need the following files and directories<br />
and you can leave the rest.<br />
<br />
* app.psgi<br />
* lib/<br />
* etc/<br />
* var/<br />
* public/<br />
<br />
Copy those files and directories into the destination. The rest is<br />
junk! Make sure to ''cd'' into the destination before starting the<br />
smokeping daemon and FastCGI webapp.<br />
<br />
You should also setup the webserver to serve the files and remove file<br />
serving code from from {{Filename|app.psgi}} so it looks like this:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*- <br />
<br />
use CGI::Emulate::PSGI;<br />
use CGI qw();<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
CGI::Emulate::PSGI->handler( $smokeping );<br />
</nowiki><br />
}}<br />
<br />
Much simpler!<br />
<br />
== Proxied ==<br />
<br />
You can continue to use a plack web server. If you do please upgrade from plackup<br />
which is designed for testing purposes. The main web server will act as a proxy and<br />
forward requests to the plack server.<br />
<br />
=== nginx ===<br />
<br />
I use nginx so here is a quick walkthrough. I like this method because<br />
it is quick and easy. Make sure that the port that the Plack server is<br />
running on is blocked from outside by a proxy (like<br />
[[iptables]]). Edit your nginx configuration file similar to this:<br />
<br />
{{File|name=nginx.conf|content=<br />
<nowiki><br />
location /smokeping {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
proxy_buffers 8 16k;<br />
proxy_buffer_size 32k;<br />
proxy_pass http://localhost:9003/;<br />
}<br />
<br />
location /smokeping/ {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
alias /srv/http/smokeping/public/;<br />
}<br />
</nowiki><br />
}}<br />
<br />
Nginx will serve our image files for us and will pass any request for<br />
''/smokeping'' to the proxied webapp server. When you start the proxied<br />
server, make sure it has the port set:<br />
<br />
cd /srv/http/smokeping<br />
starman -Ilib -p 9003 -E deployment --workers 2 &<br />
<br />
Feel free to use any port you like instead of 9003.<br />
<br />
== FastCGI ==<br />
<br />
You can easily set up the webapp to use FastCGI. Just use plackup to<br />
start the FastCGI server process:<br />
<br />
plackup -s FCGI --listen /var/run/smokeping.sock --daemonize --nproc 4<br />
<br />
(You will need the perl FCGI module installed via the 'perl-fcgi' package)<br />
<br />
Now just setup your web server (i.e. apache, lighttpd, nginx) to<br />
route traffic to your FastCGI "server" by pointing to the<br />
{{Filename|/var/run/smokeping.sock}} socket.<br />
<br />
= Advanced Configuration =<br />
<br />
{{Note|This section is incomplete.}}<br />
<br />
There are many idiosyncracies to the smokeping configuration file. There is also alot<br />
of power. You can setup many different types of probes. You can setup slave smokeping<br />
servers that can send their statistics and show you probes from other servers. You<br />
can also create your custom probes in perl. I haven't gotten that far along and the<br />
example configuration file above should be a good start.<br />
<br />
== Idiosyncracies ==<br />
<br />
I have found some things to avoid in config files through trial and error. Make sure<br />
you do not use spaces or periods in section names. You should probably avoid forward<br />
slashes too. Sections are defined with '''+'''s.<br />
<br />
This is probably because the RRD files are stored under the data directory with the<br />
same exact names as the sections.<br />
<br />
= Bugs =<br />
<br />
There are a few bugs I have noticed.<br />
<br />
== Tr.cgi ==<br />
<br />
The traceroute CGI script simply doesn't work. This could be a mistake<br />
on my part or a bug in the code. I don't need it or like it so I<br />
simply don't use it.<br />
<br />
== Cropper ==<br />
<br />
I had noticed that if I try to use the javascript cropper it does not work<br />
very well. Click on a graph long enough and it will pop up. If I try to<br />
crop a graph to zoom in, the server crashes. '''Hard'''.<br />
<br />
I decided to remove the cropper until I could track down the bug. To<br />
do this remove the {{Codeline|<script>}} tags inside the<br />
{{Filename|etc/basepage.html}} file. You may have noticed that I<br />
created a new file serving dir called {{Filename|public/}}. This<br />
avoids all the old files I don't use that are needed for the cropper<br />
and the traceroute script. This isn't the most ideal fix and the<br />
server is likely still vulnerable to crashes but at least they won't<br />
happen on '''accident'''.<br />
<br />
== CPU Crunch ==<br />
<br />
Every once and awhile I noticed that the CPU usage goes crazy for the<br />
web interface. When I use Twiggy the CPU usage goes up to 100% and<br />
stays there, locking up the server. I have decided instead to use the<br />
Starman server. That way if one process goes to crap Starman will<br />
spawn another one. This could be caused by a race condition in the<br />
Smokeping module. I haven't really tried to track it down.</div>Justerhttps://wiki.archlinux.org/index.php?title=Smokeping&diff=120470Smokeping2010-11-01T20:01:30Z<p>Juster: /* Installing Packages */ ditto</p>
<hr />
<div>[[Category:Networking (English)]]<br />
<br />
= Introduction =<br />
<br />
Smokeping allows you to probe a list of servers, store that data using<br />
RRDtool, and generate statistical charts based on RRDtool's<br />
output. Smokeping consists of two parts. A daemon runs in the<br />
background pinging and collecting data at set intervals. A web<br />
interface displays that data in the form of graphs.<br />
<br />
;Smokeping Website: http://oss.oetiker.ch/smokeping/index.en.html<br />
<br />
This guide only sets up the smokeping daemon and CGI script. We<br />
do not set up advanced features like the AJAX traceroute or the<br />
JavaScript graph cropper. Why? Because these did not work properly<br />
for me and I don't need these features enough to figure out why.<br />
<br />
= Installation =<br />
<br />
The smokeping CGI script runs under [http://daemoninc.com/SpeedyCGI/ SpeedyCGI].<br />
SpeedyCGI is a modified version of perl that allows<br />
scripts to be run persistently. Without persistence, the smokeping CGI<br />
script must load all modules and data on every webpage view. This<br />
would be too slow.<br />
<br />
SpeedyCGI has not been updated since 2003 (as of Nov 1, 2010) and no<br />
longer compiles with perl, which has since gone through API changes.<br />
Instead of using SpeedyCGI for persistence, we will convert the<br />
{{Filename|smokeping.cgi}} script into a<br />
[http://search.cpan.org/~miyagawa/PSGI-1.03/PSGI.pod PSGI] webapp<br />
which can then be made persistent a variety of ways. More on that<br />
later.<br />
<br />
We will just be installing the smokeping chart interface as a<br />
webapp. The traceroute feature will not be included.<br />
<br />
== Prerequisites ==<br />
<br />
;perl: The smokeping daemon and cgi script are perl scripts. We will use the system-wide perl for this example. You might also consider a perl for only the smokeping app. You may also compile an old version of perl (try 5.8.x) if you choose to use SpeedyCGI.<br />
;fping: Smokeping has many many different ways to probe a host. The simplest and default method is a simple ping probe which requires the fping program.<br />
;rrdtool: RRDTool is created by the same author as smokeping. RRDTool collects and displays statistical information in a disk-efficient manner.<br />
;Plack: Plack is perl's version of Ruby's rack. Plack is the implementation of the PSGI specification. PSGI is like Python's WSGI. By using Plack/PSGI we can run the smokeping.cgi as a webapp on any number of backends (proxied, FreeCGI, mod_perl, CGI, etc).<br />
;perl-cgi-emulate-psgi: The CGI::Emulate::PSGI fools the smokeping.cgi script into thinking it is running in a CGI environment, when instead it is executing inside a PSGI app.<br />
;ttf-dejavu: Without this font the graphs are unreadable and the letters are replaced with blocks.<br />
<br />
=== Optional Prerequisites ===<br />
<br />
If you want to use other probes such as the DNS or http probe you will<br />
need other packages shown below. We will only be setting up the basic<br />
ping probe in this example.<br />
<br />
{| border="1"<br />
! Probe !! Package Needed<br />
|-<br />
| Curl || curl<br />
|-<br />
| DNS || dig<br />
|-<br />
| EchoPing || echoping (AUR)<br />
|-<br />
| SSH || ssh<br />
|-<br />
| TelnetIOSPing || perl-net-telnet<br />
|-<br />
| AnotherDNS || perl-net-dns<br />
|-<br />
| LDAP || perl-net-ldap<br />
|-<br />
| LDAP (tls) || perl-io-socket-ssl<br />
|-<br />
| Authen || perl-authen-radius<br />
|}<br />
<br />
In our example we use a simple Plack-based webserver. You may wish to<br />
install a full-fledged webserver. If you wish to use the master/slave<br />
functionality of Smokeping you will need the ''perl-libwww''<br />
package. If you want to probe IPv6 servers you will need the<br />
''perl-socket6'' package from the AUR. I will not be covering any of<br />
these features and will stick to the bare minimum.<br />
<br />
== Installing Packages ==<br />
<br />
First we can install the packages that are available from the official<br />
repositories:<br />
<br />
sudo pacman -S rrdtool fping perl ttf-dejavu<br />
<br />
Now install packages from the AUR by using an [[AUR Helpers|AUR helper]]<br />
like clyde or packer or even manually if you prefer:<br />
<br />
packer -S perl-cgi-emulate-psgi perl-plack<br />
<br />
(Plack is outdated on the AUR. If you experience problems use a CPAN<br />
packager like pacpan/bauerbill or the CPANPLUS plugin<br />
CPANPLUS::Dist::Arch to get the latest version. See [[Perl Package Guidelines]]<br />
for links.)<br />
<br />
== Downloading Smokeping ==<br />
<br />
We are going to download Smokeping and extract it in our home<br />
directory so we can edit it.<br />
<br />
cd<br />
curl -O http://oss.oetiker.ch/smokeping/pub/smokeping-2.4.2.tar.gz<br />
tar zxf smokeping-2.4.2.tar.gz<br />
<br />
= Configuration =<br />
<br />
Smokeping requires you to edit a few files. The unedited files end<br />
with the {{Filename|.dist}} extension. Rename the {{Filename|.dist}}<br />
files to names without the suffix. The ''find'' command does this and<br />
prints out each file that is being renamed and needs editing:<br />
<br />
cd smokeping-2.4.2<br />
find . -name '*.dist' -print -execdir sh -c 'mv {} $(basename {} .dist)' \;<br />
<br />
== Editing Scripts ==<br />
<br />
The files inside the bin/ directory I call scripts. The script files<br />
contain {{Codeline|use lib}} statements. These add a path to search<br />
for when loading perl modules (similar to {{Codeline|$PATH}}). We don't<br />
need these. We will add to the module search path at runtime.<br />
<br />
You must set the proper config file path. The config file is by<br />
default set to {{Filename|etc/config.dist}. We will remove the<br />
{{Filename|.dist}} suffix. I prefer relative directories so that I<br />
can move the smokeping directory to anywhere I please without re-editing<br />
these files. The downside to using relative paths is you must be sure<br />
to start the daemon and webapp in the proper directory.<br />
<br />
Run this sed command to edit these scripts:<br />
<br />
sed -i -e '/^use lib/d' -e 's/config.dist/config/' bin/*<br />
<br />
== Editing the config file ==<br />
<br />
Next edit the {{Filename|etc/config}} file. The first section of the<br />
{{Filename|etc/config}} file is the easiest to edit. Personalize the<br />
top of the config file to match your information. Replace the absolute<br />
paths to relative paths. The ''General'' section should look similar<br />
to my example below. The comments describe each field.<br />
<br />
{{File|name=config|content=<br />
<nowiki><br />
*** General ***<br />
<br />
owner = Your Name Here # your name<br />
contact = your.email@host.bla # your email<br />
mailhost = your.smtp.server.bla # your mail server<br />
sendmail = /usr/sbin/sendmail # where the sendmail program is<br />
imgcache = public/images # filesystem directory where we store files<br />
imgurl = images # URL directory to find them<br />
datadir = var/pingdata # where we share data between the daemon and webapp<br />
piddir = var # filesystem directory to store PID file<br />
cgiurl = http://yourdomain/smokeping # exterior URL<br />
smokemail = etc/smokemail # new relative dir, remove .dist<br />
tmail = etc/tmail # ditto<br />
syslogfacility = local0<br />
# each probe is now run in its own process<br />
# disable this to revert to the old behaviour<br />
# concurrentprobes = no<br />
</nowiki><br />
}}<br />
<br />
{{Note|If you don't have the sendmail program installed (ie from postfix or sendmail) then use something else instead like {{Filename|/bin/false}}. The file you specify must exist or smokeping will error out.}}<br />
<br />
We are setting up the bare minimum and are not using alerts, so comment out<br />
the {{Codeline|*** Alerts ***}} section. Scroll down to the {{Codeline|*** Presentation ***}} section and replace the '''template''' path with a relative path:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Presentation ***<br />
<br />
template = etc/basepage.html<br />
</nowiki>}}<br />
<br />
The {{Codeline|*** Probes ***}} section specify which probes are<br />
active. By default only the ''FPing'' probe is set. Leave this for<br />
now. Comment out or delete the {{Codeline|*** Slaves ***}} section,<br />
you don't have any slaves... right? Scroll down to the<br />
{{Codeline|*** Targets ***}} section. This is where you specify which<br />
hosts to ping. Replace it with a host you would like to collect statistics on,<br />
like so:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Targets ***<br />
<br />
probe = FPing<br />
<br />
menu = Top<br />
title = Network Latency Grapher<br />
remark = Hello World!<br />
<br />
+ ArchLinux<br />
menu = ArchLinux<br />
title = ArchLinux Hosts<br />
host = /ArchLinux/ArchLinux_News /ArchLinux/ArchLinux_BBS /ArchLinux/ArchLinux_Wiki<br />
<br />
++ ArchLinux_News<br />
menu = News<br />
title = ArchLinux Main Site<br />
host = archlinux.org<br />
<br />
++ ArchLinux_BBS<br />
menu = BBS<br />
title = ArchLinux BBS<br />
host = bbs.archlinux.org<br />
<br />
++ ArchLinux_Wiki<br />
menu = Wiki<br />
title = ArchLinux Wiki<br />
host = wiki.archlinux.org <br />
</nowiki>}}<br />
<br />
Each '''+''' character defines a section in our hierarchy. Spaces are<br />
not allowed in the section names. You can define {{Codeline|host}} as<br />
either a real host name or the path to another section to generate a<br />
multiple host chart. These hosts are all on the same machine so the<br />
statistics aren't very interesting.<br />
<br />
You can learn more about the Smokeping config<br />
file with the examples at<br />
http://oss.oetiker.ch/smokeping/doc/smokeping_examples.en.html<br />
<br />
For now let's just try to get things started.<br />
<br />
= Setup =<br />
<br />
Create the directories we specified or else smokeping will error out.<br />
<br />
mkdir -p var/pingdata public/images<br />
<br />
Now we create the PSGI app that will wrap the CGI script. If you open<br />
the htdocs/smokeping.cgi file you will see it is really simple and just<br />
calls the ''Smokeping'' module's ''cgi'' subroutine. We are going to fool<br />
the CGI code into thinking that it is using the CGI environment. Here<br />
is where Plack comes into play.<br />
<br />
Inside the smokeping dir, create a new file called<br />
{{Filename|app.psgi}}. Copy/paste the following into the file:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*-<br />
<br />
use Plack::App::Directory;<br />
use Plack::Builder;<br />
use CGI::Emulate::PSGI;<br />
<br />
use CGI qw();<br />
<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
my $fileapp = Plack::App::Directory->new<br />
({ 'root' => 'public' })->to_app;<br />
<br />
$smokeping = CGI::Emulate::PSGI->handler( $smokeping );<br />
<br />
builder {<br />
mount "/" => $smokeping;<br />
mount "/smokeping/" => $fileapp;<br />
};<br />
</nowiki><br />
}}<br />
<br />
This file does the same thing as {{Filename|smokeping.cgi}}. We are in<br />
effect fooling smokeping to think it is still run with CGI. The<br />
difference is we wrap the CGI app into a PSGI app. This allows it to<br />
run persistently among other things. The concept of SpeedyCGI is<br />
similar. We also add file serving for the static files like images. The<br />
default, empty, or root path is set to the smokeping app itself and<br />
anything under the {{Filename|smokeping/}} URL component serves a<br />
file from the {{Filename|public/}} directory. The only files we<br />
serve are the graph images files.<br />
<br />
= Testing =<br />
<br />
Now we are going to test our webapp. Type the following commands<br />
to start the smokeping daemon and a webserver:<br />
<br />
perl -Ilib bin/smokeping<br />
plackup -Ilib<br />
<br />
Here the '''-I''' switch adds the {{Filename|lib}} directory to perl's<br />
module search path. This does the same thing as {{Codeline|use lib}};<br />
<br />
Our commands start the smokeping daemon and a simple server for the<br />
webapp which listens on port 5000 by default. Go to the webpage<br />
(''yourdomain.com:5000'') and look at the pretty graph. Keep in mind<br />
the default setup pings every 5 minutes so you may have to wait for<br />
some data to appear. If something goes wrong, fix it before<br />
continuing.<br />
<br />
If it works and that is all you wanted feel free to stop here. You can<br />
run your webapp with a better server by installing perl-starman from<br />
the AUR. Starman is a ''fast'' production quality pre-forking<br />
server. I usually set it to a very low number of worker processes though<br />
because I don't receive alot of traffic.<br />
<br />
You should set the plack environment to ''deployment'' if you don't<br />
want/need debugging information like stack traces printed. By default<br />
''Plack'' runs in the ''development'' environment. For example:<br />
<br />
starman -Ilib -p 80 -E deployment --workers 2 &<br />
<br />
The '''-I''' switch does the same thing as ''PERL5LIB''. '''-p''' listens on<br />
port 80, the default http port. '''-E''' sets the plack environment to<br />
''deployment'' which disables bug checking.<br />
<br />
= Deployment =<br />
<br />
{{Note|This section is incomplete and needs a walkthrough written for it}}<br />
<br />
Now you should probably setup a user for smokeping and<br />
create a {{Filename|/etc/rc.d/}} daemon startup script to start the<br />
smokeping daemon as well as the FastCGI webapp daemon. You could also<br />
create a directory under {{Filename|/srv/http}} for smokeping. When<br />
you copy the files, you only need the following files and directories<br />
and you can leave the rest.<br />
<br />
* app.psgi<br />
* lib/<br />
* etc/<br />
* var/<br />
* public/<br />
<br />
Copy those files and directories into the destination. The rest is<br />
junk! Make sure to ''cd'' into the destination before starting the<br />
smokeping daemon and FastCGI webapp.<br />
<br />
You should also setup the webserver to serve the files and remove file<br />
serving code from from {{Filename|app.psgi}} so it looks like this:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*- <br />
<br />
use CGI::Emulate::PSGI;<br />
use CGI qw();<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
CGI::Emulate::PSGI->handler( $smokeping );<br />
</nowiki><br />
}}<br />
<br />
Much simpler!<br />
<br />
== Proxied ==<br />
<br />
You can continue to use a plack web server. If you do please upgrade from plackup<br />
which is designed for testing purposes. The main web server will act as a proxy and<br />
forward requests to the plack server.<br />
<br />
=== nginx ===<br />
<br />
I use nginx so here is a quick walkthrough. I like this method because<br />
it is quick and easy. Make sure that the port that the Plack server is<br />
running on is blocked from outside by a proxy (like<br />
[[iptables]]). Edit your nginx configuration file similar to this:<br />
<br />
{{File|name=nginx.conf|content=<br />
<nowiki><br />
location /smokeping {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
proxy_buffers 8 16k;<br />
proxy_buffer_size 32k;<br />
proxy_pass http://localhost:9003/;<br />
}<br />
<br />
location /smokeping/ {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
alias /srv/http/smokeping/public/;<br />
}<br />
</nowiki><br />
}}<br />
<br />
Nginx will serve our image files for us and will pass any request for<br />
''/smokeping'' to the proxied webapp server. When you start the proxied<br />
server, make sure it has the port set:<br />
<br />
cd /srv/http/smokeping<br />
starman -Ilib -p 9003 -E deployment --workers 2 &<br />
<br />
Feel free to use any port you like instead of 9003.<br />
<br />
== FastCGI ==<br />
<br />
You can easily set up the webapp to use FastCGI. Just use plackup to<br />
start the FastCGI server process:<br />
<br />
plackup -s FCGI --listen /var/run/smokeping.sock --daemonize --nproc<br />
<br />
(You will need the perl FCGI module installed via the 'perl-fcgi' package)<br />
<br />
Now just setup your web server (i.e. apache, lighttpd, nginx) to<br />
route traffic to your FastCGI "server" by pointing to the<br />
{{Filename|/var/run/smokeping.sock}} socket.<br />
<br />
= Advanced Configuration =<br />
<br />
{{Note|This section is incomplete.}}<br />
<br />
There are many idiosyncracies to the smokeping configuration file. There is also alot<br />
of power. You can setup many different types of probes. You can setup slave smokeping<br />
servers that can send their statistics and show you probes from other servers. You<br />
can also create your custom probes in perl. I haven't gotten that far along and the<br />
example configuration file above should be a good start.<br />
<br />
== Idiosyncracies ==<br />
<br />
I have found some things to avoid in config files through trial and error. Make sure<br />
you do not use spaces or periods in section names. You should probably avoid forward<br />
slashes too. Sections are defined with '''+'''s.<br />
<br />
This is probably because the RRD files are stored under the data directory with the<br />
same exact names as the sections.<br />
<br />
= Bugs =<br />
<br />
There are a few bugs I have noticed.<br />
<br />
== Tr.cgi ==<br />
<br />
The traceroute CGI script simply doesn't work. This could be a mistake<br />
on my part or a bug in the code. I don't need it or like it so I<br />
simply don't use it.<br />
<br />
== Cropper ==<br />
<br />
I had noticed that if I try to use the javascript cropper it does not work<br />
very well. Click on a graph long enough and it will pop up. If I try to<br />
crop a graph to zoom in, the server crashes. '''Hard'''.<br />
<br />
I decided to remove the cropper until I could track down the bug. To<br />
do this remove the {{Codeline|<script>}} tags inside the<br />
{{Filename|etc/basepage.html}} file. You may have noticed that I<br />
created a new file serving dir called {{Filename|public/}}. This<br />
avoids all the old files I don't use that are needed for the cropper<br />
and the traceroute script. This isn't the most ideal fix and the<br />
server is likely still vulnerable to crashes but at least they won't<br />
happen on '''accident'''.<br />
<br />
== CPU Crunch ==<br />
<br />
Every once and awhile I noticed that the CPU usage goes crazy for the<br />
web interface. When I use Twiggy the CPU usage goes up to 100% and<br />
stays there, locking up the server. I have decided instead to use the<br />
Starman server. That way if one process goes to crap Starman will<br />
spawn another one. This could be caused by a race condition in the<br />
Smokeping module. I haven't really tried to track it down.</div>Justerhttps://wiki.archlinux.org/index.php?title=Smokeping&diff=120469Smokeping2010-11-01T19:59:34Z<p>Juster: Fix whitespace issue with SpeedyCGI link</p>
<hr />
<div>[[Category:Networking (English)]]<br />
<br />
= Introduction =<br />
<br />
Smokeping allows you to probe a list of servers, store that data using<br />
RRDtool, and generate statistical charts based on RRDtool's<br />
output. Smokeping consists of two parts. A daemon runs in the<br />
background pinging and collecting data at set intervals. A web<br />
interface displays that data in the form of graphs.<br />
<br />
;Smokeping Website: http://oss.oetiker.ch/smokeping/index.en.html<br />
<br />
This guide only sets up the smokeping daemon and CGI script. We<br />
do not set up advanced features like the AJAX traceroute or the<br />
JavaScript graph cropper. Why? Because these did not work properly<br />
for me and I don't need these features enough to figure out why.<br />
<br />
= Installation =<br />
<br />
The smokeping CGI script runs under [http://daemoninc.com/SpeedyCGI/ SpeedyCGI].<br />
SpeedyCGI is a modified version of perl that allows<br />
scripts to be run persistently. Without persistence, the smokeping CGI<br />
script must load all modules and data on every webpage view. This<br />
would be too slow.<br />
<br />
SpeedyCGI has not been updated since 2003 (as of Nov 1, 2010) and no<br />
longer compiles with perl, which has since gone through API changes.<br />
Instead of using SpeedyCGI for persistence, we will convert the<br />
{{Filename|smokeping.cgi}} script into a<br />
[http://search.cpan.org/~miyagawa/PSGI-1.03/PSGI.pod PSGI] webapp<br />
which can then be made persistent a variety of ways. More on that<br />
later.<br />
<br />
We will just be installing the smokeping chart interface as a<br />
webapp. The traceroute feature will not be included.<br />
<br />
== Prerequisites ==<br />
<br />
;perl: The smokeping daemon and cgi script are perl scripts. We will use the system-wide perl for this example. You might also consider a perl for only the smokeping app. You may also compile an old version of perl (try 5.8.x) if you choose to use SpeedyCGI.<br />
;fping: Smokeping has many many different ways to probe a host. The simplest and default method is a simple ping probe which requires the fping program.<br />
;rrdtool: RRDTool is created by the same author as smokeping. RRDTool collects and displays statistical information in a disk-efficient manner.<br />
;Plack: Plack is perl's version of Ruby's rack. Plack is the implementation of the PSGI specification. PSGI is like Python's WSGI. By using Plack/PSGI we can run the smokeping.cgi as a webapp on any number of backends (proxied, FreeCGI, mod_perl, CGI, etc).<br />
;perl-cgi-emulate-psgi: The CGI::Emulate::PSGI fools the smokeping.cgi script into thinking it is running in a CGI environment, when instead it is executing inside a PSGI app.<br />
;ttf-dejavu: Without this font the graphs are unreadable and the letters are replaced with blocks.<br />
<br />
=== Optional Prerequisites ===<br />
<br />
If you want to use other probes such as the DNS or http probe you will<br />
need other packages shown below. We will only be setting up the basic<br />
ping probe in this example.<br />
<br />
{| border="1"<br />
! Probe !! Package Needed<br />
|-<br />
| Curl || curl<br />
|-<br />
| DNS || dig<br />
|-<br />
| EchoPing || echoping (AUR)<br />
|-<br />
| SSH || ssh<br />
|-<br />
| TelnetIOSPing || perl-net-telnet<br />
|-<br />
| AnotherDNS || perl-net-dns<br />
|-<br />
| LDAP || perl-net-ldap<br />
|-<br />
| LDAP (tls) || perl-io-socket-ssl<br />
|-<br />
| Authen || perl-authen-radius<br />
|}<br />
<br />
In our example we use a simple Plack-based webserver. You may wish to<br />
install a full-fledged webserver. If you wish to use the master/slave<br />
functionality of Smokeping you will need the ''perl-libwww''<br />
package. If you want to probe IPv6 servers you will need the<br />
''perl-socket6'' package from the AUR. I will not be covering any of<br />
these features and will stick to the bare minimum.<br />
<br />
== Installing Packages ==<br />
<br />
First we can install the packages that are available from the official<br />
repositories:<br />
<br />
sudo pacman -S rrdtool fping perl ttf-dejavu<br />
<br />
Now install packages from the AUR by using an [[AUR Helpers|AUR<br />
helper]] like clyde or packer or even manually if you prefer:<br />
<br />
packer -S perl-cgi-emulate-psgi perl-plack<br />
<br />
(Plack is outdated on the AUR. If you experience problems use a CPAN<br />
packager like pacpan/bauerbill or the CPANPLUS plugin<br />
CPANPLUS::Dist::Arch to get the latest version. See [[Perl Package<br />
Guidelines]] for links.)<br />
<br />
== Downloading Smokeping ==<br />
<br />
We are going to download Smokeping and extract it in our home<br />
directory so we can edit it.<br />
<br />
cd<br />
curl -O http://oss.oetiker.ch/smokeping/pub/smokeping-2.4.2.tar.gz<br />
tar zxf smokeping-2.4.2.tar.gz<br />
<br />
= Configuration =<br />
<br />
Smokeping requires you to edit a few files. The unedited files end<br />
with the {{Filename|.dist}} extension. Rename the {{Filename|.dist}}<br />
files to names without the suffix. The ''find'' command does this and<br />
prints out each file that is being renamed and needs editing:<br />
<br />
cd smokeping-2.4.2<br />
find . -name '*.dist' -print -execdir sh -c 'mv {} $(basename {} .dist)' \;<br />
<br />
== Editing Scripts ==<br />
<br />
The files inside the bin/ directory I call scripts. The script files<br />
contain {{Codeline|use lib}} statements. These add a path to search<br />
for when loading perl modules (similar to {{Codeline|$PATH}}). We don't<br />
need these. We will add to the module search path at runtime.<br />
<br />
You must set the proper config file path. The config file is by<br />
default set to {{Filename|etc/config.dist}. We will remove the<br />
{{Filename|.dist}} suffix. I prefer relative directories so that I<br />
can move the smokeping directory to anywhere I please without re-editing<br />
these files. The downside to using relative paths is you must be sure<br />
to start the daemon and webapp in the proper directory.<br />
<br />
Run this sed command to edit these scripts:<br />
<br />
sed -i -e '/^use lib/d' -e 's/config.dist/config/' bin/*<br />
<br />
== Editing the config file ==<br />
<br />
Next edit the {{Filename|etc/config}} file. The first section of the<br />
{{Filename|etc/config}} file is the easiest to edit. Personalize the<br />
top of the config file to match your information. Replace the absolute<br />
paths to relative paths. The ''General'' section should look similar<br />
to my example below. The comments describe each field.<br />
<br />
{{File|name=config|content=<br />
<nowiki><br />
*** General ***<br />
<br />
owner = Your Name Here # your name<br />
contact = your.email@host.bla # your email<br />
mailhost = your.smtp.server.bla # your mail server<br />
sendmail = /usr/sbin/sendmail # where the sendmail program is<br />
imgcache = public/images # filesystem directory where we store files<br />
imgurl = images # URL directory to find them<br />
datadir = var/pingdata # where we share data between the daemon and webapp<br />
piddir = var # filesystem directory to store PID file<br />
cgiurl = http://yourdomain/smokeping # exterior URL<br />
smokemail = etc/smokemail # new relative dir, remove .dist<br />
tmail = etc/tmail # ditto<br />
syslogfacility = local0<br />
# each probe is now run in its own process<br />
# disable this to revert to the old behaviour<br />
# concurrentprobes = no<br />
</nowiki><br />
}}<br />
<br />
{{Note|If you don't have the sendmail program installed (ie from postfix or sendmail) then use something else instead like {{Filename|/bin/false}}. The file you specify must exist or smokeping will error out.}}<br />
<br />
We are setting up the bare minimum and are not using alerts, so comment out<br />
the {{Codeline|*** Alerts ***}} section. Scroll down to the {{Codeline|*** Presentation ***}} section and replace the '''template''' path with a relative path:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Presentation ***<br />
<br />
template = etc/basepage.html<br />
</nowiki>}}<br />
<br />
The {{Codeline|*** Probes ***}} section specify which probes are<br />
active. By default only the ''FPing'' probe is set. Leave this for<br />
now. Comment out or delete the {{Codeline|*** Slaves ***}} section,<br />
you don't have any slaves... right? Scroll down to the<br />
{{Codeline|*** Targets ***}} section. This is where you specify which<br />
hosts to ping. Replace it with a host you would like to collect statistics on,<br />
like so:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Targets ***<br />
<br />
probe = FPing<br />
<br />
menu = Top<br />
title = Network Latency Grapher<br />
remark = Hello World!<br />
<br />
+ ArchLinux<br />
menu = ArchLinux<br />
title = ArchLinux Hosts<br />
host = /ArchLinux/ArchLinux_News /ArchLinux/ArchLinux_BBS /ArchLinux/ArchLinux_Wiki<br />
<br />
++ ArchLinux_News<br />
menu = News<br />
title = ArchLinux Main Site<br />
host = archlinux.org<br />
<br />
++ ArchLinux_BBS<br />
menu = BBS<br />
title = ArchLinux BBS<br />
host = bbs.archlinux.org<br />
<br />
++ ArchLinux_Wiki<br />
menu = Wiki<br />
title = ArchLinux Wiki<br />
host = wiki.archlinux.org <br />
</nowiki>}}<br />
<br />
Each '''+''' character defines a section in our hierarchy. Spaces are<br />
not allowed in the section names. You can define {{Codeline|host}} as<br />
either a real host name or the path to another section to generate a<br />
multiple host chart. These hosts are all on the same machine so the<br />
statistics aren't very interesting.<br />
<br />
You can learn more about the Smokeping config<br />
file with the examples at<br />
http://oss.oetiker.ch/smokeping/doc/smokeping_examples.en.html<br />
<br />
For now let's just try to get things started.<br />
<br />
= Setup =<br />
<br />
Create the directories we specified or else smokeping will error out.<br />
<br />
mkdir -p var/pingdata public/images<br />
<br />
Now we create the PSGI app that will wrap the CGI script. If you open<br />
the htdocs/smokeping.cgi file you will see it is really simple and just<br />
calls the ''Smokeping'' module's ''cgi'' subroutine. We are going to fool<br />
the CGI code into thinking that it is using the CGI environment. Here<br />
is where Plack comes into play.<br />
<br />
Inside the smokeping dir, create a new file called<br />
{{Filename|app.psgi}}. Copy/paste the following into the file:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*-<br />
<br />
use Plack::App::Directory;<br />
use Plack::Builder;<br />
use CGI::Emulate::PSGI;<br />
<br />
use CGI qw();<br />
<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
my $fileapp = Plack::App::Directory->new<br />
({ 'root' => 'public' })->to_app;<br />
<br />
$smokeping = CGI::Emulate::PSGI->handler( $smokeping );<br />
<br />
builder {<br />
mount "/" => $smokeping;<br />
mount "/smokeping/" => $fileapp;<br />
};<br />
</nowiki><br />
}}<br />
<br />
This file does the same thing as {{Filename|smokeping.cgi}}. We are in<br />
effect fooling smokeping to think it is still run with CGI. The<br />
difference is we wrap the CGI app into a PSGI app. This allows it to<br />
run persistently among other things. The concept of SpeedyCGI is<br />
similar. We also add file serving for the static files like images. The<br />
default, empty, or root path is set to the smokeping app itself and<br />
anything under the {{Filename|smokeping/}} URL component serves a<br />
file from the {{Filename|public/}} directory. The only files we<br />
serve are the graph images files.<br />
<br />
= Testing =<br />
<br />
Now we are going to test our webapp. Type the following commands<br />
to start the smokeping daemon and a webserver:<br />
<br />
perl -Ilib bin/smokeping<br />
plackup -Ilib<br />
<br />
Here the '''-I''' switch adds the {{Filename|lib}} directory to perl's<br />
module search path. This does the same thing as {{Codeline|use lib}};<br />
<br />
Our commands start the smokeping daemon and a simple server for the<br />
webapp which listens on port 5000 by default. Go to the webpage<br />
(''yourdomain.com:5000'') and look at the pretty graph. Keep in mind<br />
the default setup pings every 5 minutes so you may have to wait for<br />
some data to appear. If something goes wrong, fix it before<br />
continuing.<br />
<br />
If it works and that is all you wanted feel free to stop here. You can<br />
run your webapp with a better server by installing perl-starman from<br />
the AUR. Starman is a ''fast'' production quality pre-forking<br />
server. I usually set it to a very low number of worker processes though<br />
because I don't receive alot of traffic.<br />
<br />
You should set the plack environment to ''deployment'' if you don't<br />
want/need debugging information like stack traces printed. By default<br />
''Plack'' runs in the ''development'' environment. For example:<br />
<br />
starman -Ilib -p 80 -E deployment --workers 2 &<br />
<br />
The '''-I''' switch does the same thing as ''PERL5LIB''. '''-p''' listens on<br />
port 80, the default http port. '''-E''' sets the plack environment to<br />
''deployment'' which disables bug checking.<br />
<br />
= Deployment =<br />
<br />
{{Note|This section is incomplete and needs a walkthrough written for it}}<br />
<br />
Now you should probably setup a user for smokeping and<br />
create a {{Filename|/etc/rc.d/}} daemon startup script to start the<br />
smokeping daemon as well as the FastCGI webapp daemon. You could also<br />
create a directory under {{Filename|/srv/http}} for smokeping. When<br />
you copy the files, you only need the following files and directories<br />
and you can leave the rest.<br />
<br />
* app.psgi<br />
* lib/<br />
* etc/<br />
* var/<br />
* public/<br />
<br />
Copy those files and directories into the destination. The rest is<br />
junk! Make sure to ''cd'' into the destination before starting the<br />
smokeping daemon and FastCGI webapp.<br />
<br />
You should also setup the webserver to serve the files and remove file<br />
serving code from from {{Filename|app.psgi}} so it looks like this:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*- <br />
<br />
use CGI::Emulate::PSGI;<br />
use CGI qw();<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
CGI::Emulate::PSGI->handler( $smokeping );<br />
</nowiki><br />
}}<br />
<br />
Much simpler!<br />
<br />
== Proxied ==<br />
<br />
You can continue to use a plack web server. If you do please upgrade from plackup<br />
which is designed for testing purposes. The main web server will act as a proxy and<br />
forward requests to the plack server.<br />
<br />
=== nginx ===<br />
<br />
I use nginx so here is a quick walkthrough. I like this method because<br />
it is quick and easy. Make sure that the port that the Plack server is<br />
running on is blocked from outside by a proxy (like<br />
[[iptables]]). Edit your nginx configuration file similar to this:<br />
<br />
{{File|name=nginx.conf|content=<br />
<nowiki><br />
location /smokeping {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
proxy_buffers 8 16k;<br />
proxy_buffer_size 32k;<br />
proxy_pass http://localhost:9003/;<br />
}<br />
<br />
location /smokeping/ {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
alias /srv/http/smokeping/public/;<br />
}<br />
</nowiki><br />
}}<br />
<br />
Nginx will serve our image files for us and will pass any request for<br />
''/smokeping'' to the proxied webapp server. When you start the proxied<br />
server, make sure it has the port set:<br />
<br />
cd /srv/http/smokeping<br />
starman -Ilib -p 9003 -E deployment --workers 2 &<br />
<br />
Feel free to use any port you like instead of 9003.<br />
<br />
== FastCGI ==<br />
<br />
You can easily set up the webapp to use FastCGI. Just use plackup to<br />
start the FastCGI server process:<br />
<br />
plackup -s FCGI --listen /var/run/smokeping.sock --daemonize --nproc<br />
<br />
(You will need the perl FCGI module installed via the 'perl-fcgi' package)<br />
<br />
Now just setup your web server (i.e. apache, lighttpd, nginx) to<br />
route traffic to your FastCGI "server" by pointing to the<br />
{{Filename|/var/run/smokeping.sock}} socket.<br />
<br />
= Advanced Configuration =<br />
<br />
{{Note|This section is incomplete.}}<br />
<br />
There are many idiosyncracies to the smokeping configuration file. There is also alot<br />
of power. You can setup many different types of probes. You can setup slave smokeping<br />
servers that can send their statistics and show you probes from other servers. You<br />
can also create your custom probes in perl. I haven't gotten that far along and the<br />
example configuration file above should be a good start.<br />
<br />
== Idiosyncracies ==<br />
<br />
I have found some things to avoid in config files through trial and error. Make sure<br />
you do not use spaces or periods in section names. You should probably avoid forward<br />
slashes too. Sections are defined with '''+'''s.<br />
<br />
This is probably because the RRD files are stored under the data directory with the<br />
same exact names as the sections.<br />
<br />
= Bugs =<br />
<br />
There are a few bugs I have noticed.<br />
<br />
== Tr.cgi ==<br />
<br />
The traceroute CGI script simply doesn't work. This could be a mistake<br />
on my part or a bug in the code. I don't need it or like it so I<br />
simply don't use it.<br />
<br />
== Cropper ==<br />
<br />
I had noticed that if I try to use the javascript cropper it does not work<br />
very well. Click on a graph long enough and it will pop up. If I try to<br />
crop a graph to zoom in, the server crashes. '''Hard'''.<br />
<br />
I decided to remove the cropper until I could track down the bug. To<br />
do this remove the {{Codeline|<script>}} tags inside the<br />
{{Filename|etc/basepage.html}} file. You may have noticed that I<br />
created a new file serving dir called {{Filename|public/}}. This<br />
avoids all the old files I don't use that are needed for the cropper<br />
and the traceroute script. This isn't the most ideal fix and the<br />
server is likely still vulnerable to crashes but at least they won't<br />
happen on '''accident'''.<br />
<br />
== CPU Crunch ==<br />
<br />
Every once and awhile I noticed that the CPU usage goes crazy for the<br />
web interface. When I use Twiggy the CPU usage goes up to 100% and<br />
stays there, locking up the server. I have decided instead to use the<br />
Starman server. That way if one process goes to crap Starman will<br />
spawn another one. This could be caused by a race condition in the<br />
Smokeping module. I haven't really tried to track it down.</div>Justerhttps://wiki.archlinux.org/index.php?title=Smokeping&diff=120468Smokeping2010-11-01T19:58:13Z<p>Juster: Complete rewrite that should actually be useful</p>
<hr />
<div>[[Category:Networking (English)]]<br />
<br />
= Introduction =<br />
<br />
Smokeping allows you to probe a list of servers, store that data using<br />
RRDtool, and generate statistical charts based on RRDtool's<br />
output. Smokeping consists of two parts. A daemon runs in the<br />
background pinging and collecting data at set intervals. A web<br />
interface displays that data in the form of graphs.<br />
<br />
;Smokeping Website: http://oss.oetiker.ch/smokeping/index.en.html<br />
<br />
This guide only sets up the smokeping daemon and CGI script. We<br />
do not set up advanced features like the AJAX traceroute or the<br />
JavaScript graph cropper. Why? Because these did not work properly<br />
for me and I don't need these features enough to figure out why.<br />
<br />
= Installation =<br />
<br />
The smokeping CGI script runs under [http://daemoninc.com/SpeedyCGI/<br />
SpeedyCGI]. SpeedyCGI is a modified version of perl that allows<br />
scripts to be run persistently. Without persistence, the smokeping CGI<br />
script must load all modules and data on every webpage view. This<br />
would be too slow.<br />
<br />
SpeedyCGI has not been updated since 2003 (as of Nov 1, 2010) and no<br />
longer compiles with perl, which has since gone through API changes.<br />
Instead of using SpeedyCGI for persistence, we will convert the<br />
{{Filename|smokeping.cgi}} script into a<br />
[http://search.cpan.org/~miyagawa/PSGI-1.03/PSGI.pod PSGI] webapp<br />
which can then be made persistent a variety of ways. More on that<br />
later.<br />
<br />
We will just be installing the smokeping chart interface as a<br />
webapp. The traceroute feature will not be included.<br />
<br />
== Prerequisites ==<br />
<br />
;perl: The smokeping daemon and cgi script are perl scripts. We will use the system-wide perl for this example. You might also consider a perl for only the smokeping app. You may also compile an old version of perl (try 5.8.x) if you choose to use SpeedyCGI.<br />
;fping: Smokeping has many many different ways to probe a host. The simplest and default method is a simple ping probe which requires the fping program.<br />
;rrdtool: RRDTool is created by the same author as smokeping. RRDTool collects and displays statistical information in a disk-efficient manner.<br />
;Plack: Plack is perl's version of Ruby's rack. Plack is the implementation of the PSGI specification. PSGI is like Python's WSGI. By using Plack/PSGI we can run the smokeping.cgi as a webapp on any number of backends (proxied, FreeCGI, mod_perl, CGI, etc).<br />
;perl-cgi-emulate-psgi: The CGI::Emulate::PSGI fools the smokeping.cgi script into thinking it is running in a CGI environment, when instead it is executing inside a PSGI app.<br />
;ttf-dejavu: Without this font the graphs are unreadable and the letters are replaced with blocks.<br />
<br />
=== Optional Prerequisites ===<br />
<br />
If you want to use other probes such as the DNS or http probe you will<br />
need other packages shown below. We will only be setting up the basic<br />
ping probe in this example.<br />
<br />
{| border="1"<br />
! Probe !! Package Needed<br />
|-<br />
| Curl || curl<br />
|-<br />
| DNS || dig<br />
|-<br />
| EchoPing || echoping (AUR)<br />
|-<br />
| SSH || ssh<br />
|-<br />
| TelnetIOSPing || perl-net-telnet<br />
|-<br />
| AnotherDNS || perl-net-dns<br />
|-<br />
| LDAP || perl-net-ldap<br />
|-<br />
| LDAP (tls) || perl-io-socket-ssl<br />
|-<br />
| Authen || perl-authen-radius<br />
|}<br />
<br />
In our example we use a simple Plack-based webserver. You may wish to<br />
install a full-fledged webserver. If you wish to use the master/slave<br />
functionality of Smokeping you will need the ''perl-libwww''<br />
package. If you want to probe IPv6 servers you will need the<br />
''perl-socket6'' package from the AUR. I will not be covering any of<br />
these features and will stick to the bare minimum.<br />
<br />
== Installing Packages ==<br />
<br />
First we can install the packages that are available from the official<br />
repositories:<br />
<br />
sudo pacman -S rrdtool fping perl ttf-dejavu<br />
<br />
Now install packages from the AUR by using an [[AUR Helpers|AUR<br />
helper]] like clyde or packer or even manually if you prefer:<br />
<br />
packer -S perl-cgi-emulate-psgi perl-plack<br />
<br />
(Plack is outdated on the AUR. If you experience problems use a CPAN<br />
packager like pacpan/bauerbill or the CPANPLUS plugin<br />
CPANPLUS::Dist::Arch to get the latest version. See [[Perl Package<br />
Guidelines]] for links.)<br />
<br />
== Downloading Smokeping ==<br />
<br />
We are going to download Smokeping and extract it in our home<br />
directory so we can edit it.<br />
<br />
cd<br />
curl -O http://oss.oetiker.ch/smokeping/pub/smokeping-2.4.2.tar.gz<br />
tar zxf smokeping-2.4.2.tar.gz<br />
<br />
= Configuration =<br />
<br />
Smokeping requires you to edit a few files. The unedited files end<br />
with the {{Filename|.dist}} extension. Rename the {{Filename|.dist}}<br />
files to names without the suffix. The ''find'' command does this and<br />
prints out each file that is being renamed and needs editing:<br />
<br />
cd smokeping-2.4.2<br />
find . -name '*.dist' -print -execdir sh -c 'mv {} $(basename {} .dist)' \;<br />
<br />
== Editing Scripts ==<br />
<br />
The files inside the bin/ directory I call scripts. The script files<br />
contain {{Codeline|use lib}} statements. These add a path to search<br />
for when loading perl modules (similar to {{Codeline|$PATH}}). We don't<br />
need these. We will add to the module search path at runtime.<br />
<br />
You must set the proper config file path. The config file is by<br />
default set to {{Filename|etc/config.dist}. We will remove the<br />
{{Filename|.dist}} suffix. I prefer relative directories so that I<br />
can move the smokeping directory to anywhere I please without re-editing<br />
these files. The downside to using relative paths is you must be sure<br />
to start the daemon and webapp in the proper directory.<br />
<br />
Run this sed command to edit these scripts:<br />
<br />
sed -i -e '/^use lib/d' -e 's/config.dist/config/' bin/*<br />
<br />
== Editing the config file ==<br />
<br />
Next edit the {{Filename|etc/config}} file. The first section of the<br />
{{Filename|etc/config}} file is the easiest to edit. Personalize the<br />
top of the config file to match your information. Replace the absolute<br />
paths to relative paths. The ''General'' section should look similar<br />
to my example below. The comments describe each field.<br />
<br />
{{File|name=config|content=<br />
<nowiki><br />
*** General ***<br />
<br />
owner = Your Name Here # your name<br />
contact = your.email@host.bla # your email<br />
mailhost = your.smtp.server.bla # your mail server<br />
sendmail = /usr/sbin/sendmail # where the sendmail program is<br />
imgcache = public/images # filesystem directory where we store files<br />
imgurl = images # URL directory to find them<br />
datadir = var/pingdata # where we share data between the daemon and webapp<br />
piddir = var # filesystem directory to store PID file<br />
cgiurl = http://yourdomain/smokeping # exterior URL<br />
smokemail = etc/smokemail # new relative dir, remove .dist<br />
tmail = etc/tmail # ditto<br />
syslogfacility = local0<br />
# each probe is now run in its own process<br />
# disable this to revert to the old behaviour<br />
# concurrentprobes = no<br />
</nowiki><br />
}}<br />
<br />
{{Note|If you don't have the sendmail program installed (ie from postfix or sendmail) then use something else instead like {{Filename|/bin/false}}. The file you specify must exist or smokeping will error out.}}<br />
<br />
We are setting up the bare minimum and are not using alerts, so comment out<br />
the {{Codeline|*** Alerts ***}} section. Scroll down to the {{Codeline|*** Presentation ***}} section and replace the '''template''' path with a relative path:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Presentation ***<br />
<br />
template = etc/basepage.html<br />
</nowiki>}}<br />
<br />
The {{Codeline|*** Probes ***}} section specify which probes are<br />
active. By default only the ''FPing'' probe is set. Leave this for<br />
now. Comment out or delete the {{Codeline|*** Slaves ***}} section,<br />
you don't have any slaves... right? Scroll down to the<br />
{{Codeline|*** Targets ***}} section. This is where you specify which<br />
hosts to ping. Replace it with a host you would like to collect statistics on,<br />
like so:<br />
<br />
{{File|name=config|content=<nowiki><br />
*** Targets ***<br />
<br />
probe = FPing<br />
<br />
menu = Top<br />
title = Network Latency Grapher<br />
remark = Hello World!<br />
<br />
+ ArchLinux<br />
menu = ArchLinux<br />
title = ArchLinux Hosts<br />
host = /ArchLinux/ArchLinux_News /ArchLinux/ArchLinux_BBS /ArchLinux/ArchLinux_Wiki<br />
<br />
++ ArchLinux_News<br />
menu = News<br />
title = ArchLinux Main Site<br />
host = archlinux.org<br />
<br />
++ ArchLinux_BBS<br />
menu = BBS<br />
title = ArchLinux BBS<br />
host = bbs.archlinux.org<br />
<br />
++ ArchLinux_Wiki<br />
menu = Wiki<br />
title = ArchLinux Wiki<br />
host = wiki.archlinux.org <br />
</nowiki>}}<br />
<br />
Each '''+''' character defines a section in our hierarchy. Spaces are<br />
not allowed in the section names. You can define {{Codeline|host}} as<br />
either a real host name or the path to another section to generate a<br />
multiple host chart. These hosts are all on the same machine so the<br />
statistics aren't very interesting.<br />
<br />
You can learn more about the Smokeping config<br />
file with the examples at<br />
http://oss.oetiker.ch/smokeping/doc/smokeping_examples.en.html<br />
<br />
For now let's just try to get things started.<br />
<br />
= Setup =<br />
<br />
Create the directories we specified or else smokeping will error out.<br />
<br />
mkdir -p var/pingdata public/images<br />
<br />
Now we create the PSGI app that will wrap the CGI script. If you open<br />
the htdocs/smokeping.cgi file you will see it is really simple and just<br />
calls the ''Smokeping'' module's ''cgi'' subroutine. We are going to fool<br />
the CGI code into thinking that it is using the CGI environment. Here<br />
is where Plack comes into play.<br />
<br />
Inside the smokeping dir, create a new file called<br />
{{Filename|app.psgi}}. Copy/paste the following into the file:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*-<br />
<br />
use Plack::App::Directory;<br />
use Plack::Builder;<br />
use CGI::Emulate::PSGI;<br />
<br />
use CGI qw();<br />
<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
my $fileapp = Plack::App::Directory->new<br />
({ 'root' => 'public' })->to_app;<br />
<br />
$smokeping = CGI::Emulate::PSGI->handler( $smokeping );<br />
<br />
builder {<br />
mount "/" => $smokeping;<br />
mount "/smokeping/" => $fileapp;<br />
};<br />
</nowiki><br />
}}<br />
<br />
This file does the same thing as {{Filename|smokeping.cgi}}. We are in<br />
effect fooling smokeping to think it is still run with CGI. The<br />
difference is we wrap the CGI app into a PSGI app. This allows it to<br />
run persistently among other things. The concept of SpeedyCGI is<br />
similar. We also add file serving for the static files like images. The<br />
default, empty, or root path is set to the smokeping app itself and<br />
anything under the {{Filename|smokeping/}} URL component serves a<br />
file from the {{Filename|public/}} directory. The only files we<br />
serve are the graph images files.<br />
<br />
= Testing =<br />
<br />
Now we are going to test our webapp. Type the following commands<br />
to start the smokeping daemon and a webserver:<br />
<br />
perl -Ilib bin/smokeping<br />
plackup -Ilib<br />
<br />
Here the '''-I''' switch adds the {{Filename|lib}} directory to perl's<br />
module search path. This does the same thing as {{Codeline|use lib}};<br />
<br />
Our commands start the smokeping daemon and a simple server for the<br />
webapp which listens on port 5000 by default. Go to the webpage<br />
(''yourdomain.com:5000'') and look at the pretty graph. Keep in mind<br />
the default setup pings every 5 minutes so you may have to wait for<br />
some data to appear. If something goes wrong, fix it before<br />
continuing.<br />
<br />
If it works and that is all you wanted feel free to stop here. You can<br />
run your webapp with a better server by installing perl-starman from<br />
the AUR. Starman is a ''fast'' production quality pre-forking<br />
server. I usually set it to a very low number of worker processes though<br />
because I don't receive alot of traffic.<br />
<br />
You should set the plack environment to ''deployment'' if you don't<br />
want/need debugging information like stack traces printed. By default<br />
''Plack'' runs in the ''development'' environment. For example:<br />
<br />
starman -Ilib -p 80 -E deployment --workers 2 &<br />
<br />
The '''-I''' switch does the same thing as ''PERL5LIB''. '''-p''' listens on<br />
port 80, the default http port. '''-E''' sets the plack environment to<br />
''deployment'' which disables bug checking.<br />
<br />
= Deployment =<br />
<br />
{{Note|This section is incomplete and needs a walkthrough written for it}}<br />
<br />
Now you should probably setup a user for smokeping and<br />
create a {{Filename|/etc/rc.d/}} daemon startup script to start the<br />
smokeping daemon as well as the FastCGI webapp daemon. You could also<br />
create a directory under {{Filename|/srv/http}} for smokeping. When<br />
you copy the files, you only need the following files and directories<br />
and you can leave the rest.<br />
<br />
* app.psgi<br />
* lib/<br />
* etc/<br />
* var/<br />
* public/<br />
<br />
Copy those files and directories into the destination. The rest is<br />
junk! Make sure to ''cd'' into the destination before starting the<br />
smokeping daemon and FastCGI webapp.<br />
<br />
You should also setup the webserver to serve the files and remove file<br />
serving code from from {{Filename|app.psgi}} so it looks like this:<br />
<br />
{{File|name=app.psgi|content=<br />
<nowiki><br />
# -*- cperl -*- <br />
<br />
use CGI::Emulate::PSGI;<br />
use CGI qw();<br />
use warnings;<br />
use strict;<br />
<br />
use Smokeping 2.004002;<br />
<br />
my $smokeping = sub {<br />
CGI::initialize_globals();<br />
Smokeping::cgi("etc/config");<br />
};<br />
<br />
CGI::Emulate::PSGI->handler( $smokeping );<br />
</nowiki><br />
}}<br />
<br />
Much simpler!<br />
<br />
== Proxied ==<br />
<br />
You can continue to use a plack web server. If you do please upgrade from plackup<br />
which is designed for testing purposes. The main web server will act as a proxy and<br />
forward requests to the plack server.<br />
<br />
=== nginx ===<br />
<br />
I use nginx so here is a quick walkthrough. I like this method because<br />
it is quick and easy. Make sure that the port that the Plack server is<br />
running on is blocked from outside by a proxy (like<br />
[[iptables]]). Edit your nginx configuration file similar to this:<br />
<br />
{{File|name=nginx.conf|content=<br />
<nowiki><br />
location /smokeping {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
proxy_buffers 8 16k;<br />
proxy_buffer_size 32k;<br />
proxy_pass http://localhost:9003/;<br />
}<br />
<br />
location /smokeping/ {<br />
error_log /srv/http/smokeping/var/error.log info;<br />
access_log /srv/http/smokeping/var/access.log combined;<br />
<br />
alias /srv/http/smokeping/public/;<br />
}<br />
</nowiki><br />
}}<br />
<br />
Nginx will serve our image files for us and will pass any request for<br />
''/smokeping'' to the proxied webapp server. When you start the proxied<br />
server, make sure it has the port set:<br />
<br />
cd /srv/http/smokeping<br />
starman -Ilib -p 9003 -E deployment --workers 2 &<br />
<br />
Feel free to use any port you like instead of 9003.<br />
<br />
== FastCGI ==<br />
<br />
You can easily set up the webapp to use FastCGI. Just use plackup to<br />
start the FastCGI server process:<br />
<br />
plackup -s FCGI --listen /var/run/smokeping.sock --daemonize --nproc<br />
<br />
(You will need the perl FCGI module installed via the 'perl-fcgi' package)<br />
<br />
Now just setup your web server (i.e. apache, lighttpd, nginx) to<br />
route traffic to your FastCGI "server" by pointing to the<br />
{{Filename|/var/run/smokeping.sock}} socket.<br />
<br />
= Advanced Configuration =<br />
<br />
{{Note|This section is incomplete.}}<br />
<br />
There are many idiosyncracies to the smokeping configuration file. There is also alot<br />
of power. You can setup many different types of probes. You can setup slave smokeping<br />
servers that can send their statistics and show you probes from other servers. You<br />
can also create your custom probes in perl. I haven't gotten that far along and the<br />
example configuration file above should be a good start.<br />
<br />
== Idiosyncracies ==<br />
<br />
I have found some things to avoid in config files through trial and error. Make sure<br />
you do not use spaces or periods in section names. You should probably avoid forward<br />
slashes too. Sections are defined with '''+'''s.<br />
<br />
This is probably because the RRD files are stored under the data directory with the<br />
same exact names as the sections.<br />
<br />
= Bugs =<br />
<br />
There are a few bugs I have noticed.<br />
<br />
== Tr.cgi ==<br />
<br />
The traceroute CGI script simply doesn't work. This could be a mistake<br />
on my part or a bug in the code. I don't need it or like it so I<br />
simply don't use it.<br />
<br />
== Cropper ==<br />
<br />
I had noticed that if I try to use the javascript cropper it does not work<br />
very well. Click on a graph long enough and it will pop up. If I try to<br />
crop a graph to zoom in, the server crashes. '''Hard'''.<br />
<br />
I decided to remove the cropper until I could track down the bug. To<br />
do this remove the {{Codeline|<script>}} tags inside the<br />
{{Filename|etc/basepage.html}} file. You may have noticed that I<br />
created a new file serving dir called {{Filename|public/}}. This<br />
avoids all the old files I don't use that are needed for the cropper<br />
and the traceroute script. This isn't the most ideal fix and the<br />
server is likely still vulnerable to crashes but at least they won't<br />
happen on '''accident'''.<br />
<br />
== CPU Crunch ==<br />
<br />
Every once and awhile I noticed that the CPU usage goes crazy for the<br />
web interface. When I use Twiggy the CPU usage goes up to 100% and<br />
stays there, locking up the server. I have decided instead to use the<br />
Starman server. That way if one process goes to crap Starman will<br />
spawn another one. This could be caused by a race condition in the<br />
Smokeping module. I haven't really tried to track it down.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=117814Perl package guidelines2010-09-21T19:48:33Z<p>Juster: Add mention of possible problems with user-compiled perl.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
[[Category:Guidelines (English)]]<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{Filename|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Codeline|INSTALLDIRS}} variable as shown below). No files should be stored in {{Filename|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{Filename|perllocal.pod}} and {{Filename|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{Filename|/usr/share/pacman/PKGBUILD-perl.proto}} which is present in the {{Package Official|abs}} package. It is also reproduced below (without the comments):<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url=""<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor || return 1<br />
make || return 1<br />
make install DESTDIR="$pkgdir/" || return 1<br />
<br />
## for packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
# perl Build install<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name perllocal.pod -delete<br />
find "$pkgdir" -name .packlist -delete<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the {{Codeline|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
The more perlish method is to use a {{Codeline|CPANPLUS::Dist}} plugin for installing CPAN modules as dynamically generated pacman packages, available at http://aur.archlinux.org/packages.php?ID=24971<br />
<br />
There is also a script called {{Codeline|pacpan}}, which can recursively generate PKGBUILDs for a module: http://www.archlinux.org/packages/community/any/pacpan/<br />
<br />
It is worth mentioning that [[Bauerbill | Bauerbill]] has similar support for generating PKGBUILDs to {{Codeline|pacpan}}. As well as adding the ability to upgrade all installed CPAN modules directly from CPAN via a pacman interface. Make sure to read the Bauerbill man file for usage instructions.<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Codeline|package}} keyword in perl. Modules are contained inside a {{Filename|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Codeline|package}}) is in the file. Modules have namespaces separated with {{Codeline|::}} (double colons), like: {{Codeline|Archlinux::Module}}. When loading a module, the {{Codeline|::}}s are replaced with directory separators. For example: {{Filename|Archlinux/Module.pm}} will be loaded for the module {{Codeline|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{Filename|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{Filename|Template-Toolkit-2.22.tar.gz}}, for the {{Codeline|Template-Toolkit}} dist, contains no {{Codeline|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===User-Installed perl===<br />
A subtle problem is that advanced perl programmers may like to have multiple versions of perl installed. This is useful for testing backwards-compatibility in created programs. There are also speed benefits to compiling your own custom perl interpreter (i.e. without threads). Another reason for a custom ''perl'' is simply because the official perl ArchLinux package sometimes lags behind perl releases. The user may be trying out the latest perl... who knows?<br />
<br />
If the user has the custom perl executable in their {{Codeline|$PATH}}, the custom perl will be run when the user types the ''perl'' command on the shell. In fact the custom perl will run inside the {{Filename|PKGBUILD}} as well! This can lead to insidious problems that are difficult to understand.<br />
<br />
The problem lies in compiled XS modules. These modules bridge perl and C. As such they must use perl's internal C API to accomplish this bridge. Perl's C API changes slightly with different versions of perl. If the user has a different version of perl than the system perl ({{Filename|/usr/bin/perl}}) then any XS module compiled with the user's perl will be incompatible with the system-wide perl. When trying to use the compiled XS module with the system perl, the module will fail to load with a link error.<br />
<br />
A simple solution is to always use the absolute path of the system-wide perl interpreter ({{Filename|/usr/bin/perl}}) when running perl in the {{Filename|PKGBUILD}}.<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Codeline|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{Filename|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{Filename|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{Filename|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Codeline|Module::Build}} was not already installed, you could not run the bundled {{Filename|Build.PL}} script! This is not a problem with recent versions of perl because {{Codeline|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Codeline|Module::Install}} still requires the {{Filename|make}} program be installed to function. It was designed as a drop-in replacement for {{Codeline|ExtUtils::MakeMaker}}, to address some of {{Codeline|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Codeline|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Codeline|MakeMaker}} or {{Codeline|M::B}}, you do not need {{Codeline|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Codeline|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{Filename|Makefile.PL}} is executed. This feature is skipped when {{Codeline|Module::Install}} detects it is being run by {{Codeline|CPAN}} or {{Codeline|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{Filename|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Codeline|Module::Install}}'s {{Filename|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Codeline|--skipdeps}} to this.<br />
<br />
<pre>export PERL_AUTOINSTALL='--skipdeps'</pre><br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{Filename|Makefile.PL}} and/or {{Filename|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
<pre>export PERL_MM_OPT=INSTALLBASE=~/perl5</pre><br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT except it is only for {{Codeline|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
<pre>export PERL_MB_OPT=--install_base=~/perl5</pre><br />
<br />
====MODULEBUILDRC====<br />
{{Codeline|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{Filename|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Codeline|MODULEBUILDRC}}. The paranoid might set {{Codeline|MODULEBUILDRC}} to {{Filename|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ /usr/bin/perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ /usr/bin/perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</pre></div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=107068Perl package guidelines2010-05-23T19:26:19Z<p>Juster: Fix PERL_MM_OPT I discovered Module::Build uses it as well.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
[[Category:Guidelines (English)]]<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{Filename|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Codeline|INSTALLDIRS}} variable as shown below). No files should be stored in {{Filename|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{Filename|perllocal.pod}} and {{Filename|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{Filename|/usr/share/pacman/PKGBUILD-perl.proto}} which is present in the {{Package Official|abs}} package. It is also reproduced below (without the comments):<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url=""<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor || return 1<br />
make || return 1<br />
make install DESTDIR="$pkgdir/" || return 1<br />
<br />
## for packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
# perl Build install<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name perllocal.pod -delete<br />
find "$pkgdir" -name .packlist -delete<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the {{Codeline|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
The more perlish method is to use a {{Codeline|CPANPLUS::Dist}} plugin for installing CPAN modules as dynamically generated pacman packages, available at http://aur.archlinux.org/packages.php?ID=24971<br />
<br />
There is also a script called {{Codeline|pacpan}}, which can recursively generate PKGBUILDs for a module: http://aur.archlinux.org/packages.php?ID=23495<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Codeline|package}} keyword in perl. Modules are contained inside a {{Filename|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Codeline|package}}) is in the file. Modules have namespaces separated with {{Codeline|::}} (double colons), like: {{Codeline|Archlinux::Module}}. When loading a module, the {{Codeline|::}}s are replaced with directory separators. For example: {{Filename|Archlinux/Module.pm}} will be loaded for the module {{Codeline|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{Filename|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{Filename|Template-Toolkit-2.22.tar.gz}}, for the {{Codeline|Template-Toolkit}} dist, contains no {{Codeline|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Codeline|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{Filename|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{Filename|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{Filename|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Codeline|Module::Build}} was not already installed, you could not run the bundled {{Filename|Build.PL}} script! This is not a problem with recent versions of perl because {{Codeline|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Codeline|Module::Install}} still requires the {{Filename|make}} program be installed to function. It was designed as a drop-in replacement for {{Codeline|ExtUtils::MakeMaker}}, to address some of {{Codeline|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Codeline|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Codeline|MakeMaker}} or {{Codeline|M::B}}, you do not need {{Codeline|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Codeline|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{Filename|Makefile.PL}} is executed. This feature is skipped when {{Codeline|Module::Install}} detects it is being run by {{Codeline|CPAN}} or {{Codeline|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{Filename|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Codeline|Module::Install}}'s {{Filename|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Codeline|--skipdeps}} to this.<br />
<br />
<pre>export PERL_AUTOINSTALL='--skipdeps'</pre><br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{Filename|Makefile.PL}} and/or {{Filename|Build.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
<pre>export PERL_MM_OPT=INSTALLBASE=~/perl5</pre><br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT except it is only for {{Codeline|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
<pre>export PERL_MB_OPT=--install_base=~/perl5</pre><br />
<br />
====MODULEBUILDRC====<br />
{{Codeline|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{Filename|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Codeline|MODULEBUILDRC}}. The paranoid might set {{Codeline|MODULEBUILDRC}} to {{Filename|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR='$pkgdir'" \<br />
PERL_MB_OPT="--installdirs vendor --destdir '$pkgdir'" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</pre></div>Justerhttps://wiki.archlinux.org/index.php?title=User:Juster&diff=106143User:Juster2010-05-11T16:42:35Z<p>Juster: Created page with 'I am a hobbyist progammer who uses mostly perl. I have created a few Archlinux-related perl modules and released them on CPAN. They are also available for easy install on the A…'</p>
<hr />
<div>I am a hobbyist progammer who uses mostly perl. I have created a few Archlinux-related perl modules and released them on CPAN. They are also available for easy install on the AUR.<br />
<br />
==Modules==<br />
;[http://search.cpan.org/dist/CPANPLUS-Dist-Arch CPANPLUS::Dist::Arch]: a plugin for CPANPLUS that creates pacman packages on the fly for modules CPANPLUS installs.<br />
;[http://search.cpan.org/dist/ALPM ALPM]: a module for interfacing with libalpm, the library backend for pacman.<br />
<br />
==Other==<br />
Git repositories for these modules and other projects are available at http://github.com/juster.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=106097Perl package guidelines2010-05-11T01:58:06Z<p>Juster: /* Hardened Example */ using perl Build after perl Build.PL bugs me... switched to standard "mantra".</p>
<hr />
<div>[[Category:Package development (English)]]<br />
[[Category:Guidelines (English)]]<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{Filename|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Codeline|INSTALLDIRS}} variable as shown below). No files should be stored in {{Filename|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{Filename|perllocal.pod}} and {{Filename|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{Filename|/usr/share/pacman/PKGBUILD-perl.proto}} which is present in the {{Package Official|abs}} package. It is also reproduced below (without the comments):<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url=""<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor || return 1<br />
make || return 1<br />
make install DESTDIR="$pkgdir/" || return 1<br />
<br />
## for packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
# perl Build install<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name perllocal.pod -delete<br />
find "$pkgdir" -name .packlist -delete<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the {{Codeline|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
The more perlish method is to use a {{Codeline|CPANPLUS::Dist}} plugin for installing CPAN modules as dynamically generated pacman packages, available at http://aur.archlinux.org/packages.php?ID=24971<br />
<br />
There is also a script called {{Codeline|pacpan}}, which can recursively generate PKGBUILDs for a module: http://aur.archlinux.org/packages.php?ID=23495<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Codeline|package}} keyword in perl. Modules are contained inside a {{Filename|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Codeline|package}}) is in the file. Modules have namespaces separated with {{Codeline|::}} (double colons), like: {{Codeline|Archlinux::Module}}. When loading a module, the {{Codeline|::}}s are replaced with directory separators. For example: {{Filename|Archlinux/Module.pm}} will be loaded for the module {{Codeline|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{Filename|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{Filename|Template-Toolkit-2.22.tar.gz}}, for the {{Codeline|Template-Toolkit}} dist, contains no {{Codeline|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Codeline|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{Filename|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{Filename|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{Filename|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Codeline|Module::Build}} was not already installed, you could not run the bundled {{Filename|Build.PL}} script! This is not a problem with recent versions of perl because {{Codeline|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Codeline|Module::Install}} still requires the {{Filename|make}} program be installed to function. It was designed as a drop-in replacement for {{Codeline|ExtUtils::MakeMaker}}, to address some of {{Codeline|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Codeline|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Codeline|MakeMaker}} or {{Codeline|M::B}}, you do not need {{Codeline|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Codeline|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{Filename|Makefile.PL}} is executed. This feature is skipped when {{Codeline|Module::Install}} detects it is being run by {{Codeline|CPAN}} or {{Codeline|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{Filename|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Codeline|Module::Install}}'s {{Filename|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Codeline|--skipdeps}} to this.<br />
<br />
<pre>export PERL_AUTOINSTALL='--skipdeps'</pre><br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{Filename|Makefile.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
<pre>export PERL_MM_OPT=INSTALLBASE=~/perl5</pre><br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT, except for {{Codeline|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
<pre>export PERL_MB_OPT=--install_base=~/perl5</pre><br />
<br />
====MODULEBUILDRC====<br />
{{Codeline|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{Filename|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Codeline|MODULEBUILDRC}}. The paranoid might set {{Codeline|MODULEBUILDRC}} to {{Filename|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
<br />
# If using Makefile.PL (ExtUtils::MakeMaker or Module::Install)<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR=$pkgdir"<br />
<br />
# If using Build.PL (Module::Build)<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MB_OPT="--installdirs vendor --destdir $pkgdir" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ perl Build.PL &&<br />
./Build &&<br />
./Build test &&<br />
./Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</pre></div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=106096Perl package guidelines2010-05-11T01:56:06Z<p>Juster: Add an advanced example PKGBUILD after all the info.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
[[Category:Guidelines (English)]]<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{Filename|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Codeline|INSTALLDIRS}} variable as shown below). No files should be stored in {{Filename|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{Filename|perllocal.pod}} and {{Filename|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{Filename|/usr/share/pacman/PKGBUILD-perl.proto}} which is present in the {{Package Official|abs}} package. It is also reproduced below (without the comments):<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url=""<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor || return 1<br />
make || return 1<br />
make install DESTDIR="$pkgdir/" || return 1<br />
<br />
## for packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
# perl Build install<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name perllocal.pod -delete<br />
find "$pkgdir" -name .packlist -delete<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the {{Codeline|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
The more perlish method is to use a {{Codeline|CPANPLUS::Dist}} plugin for installing CPAN modules as dynamically generated pacman packages, available at http://aur.archlinux.org/packages.php?ID=24971<br />
<br />
There is also a script called {{Codeline|pacpan}}, which can recursively generate PKGBUILDs for a module: http://aur.archlinux.org/packages.php?ID=23495<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Codeline|package}} keyword in perl. Modules are contained inside a {{Filename|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Codeline|package}}) is in the file. Modules have namespaces separated with {{Codeline|::}} (double colons), like: {{Codeline|Archlinux::Module}}. When loading a module, the {{Codeline|::}}s are replaced with directory separators. For example: {{Filename|Archlinux/Module.pm}} will be loaded for the module {{Codeline|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{Filename|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{Filename|Template-Toolkit-2.22.tar.gz}}, for the {{Codeline|Template-Toolkit}} dist, contains no {{Codeline|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Codeline|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{Filename|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{Filename|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{Filename|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Codeline|Module::Build}} was not already installed, you could not run the bundled {{Filename|Build.PL}} script! This is not a problem with recent versions of perl because {{Codeline|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Codeline|Module::Install}} still requires the {{Filename|make}} program be installed to function. It was designed as a drop-in replacement for {{Codeline|ExtUtils::MakeMaker}}, to address some of {{Codeline|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Codeline|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Codeline|MakeMaker}} or {{Codeline|M::B}}, you do not need {{Codeline|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Codeline|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{Filename|Makefile.PL}} is executed. This feature is skipped when {{Codeline|Module::Install}} detects it is being run by {{Codeline|CPAN}} or {{Codeline|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{Filename|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Codeline|Module::Install}}'s {{Filename|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Codeline|--skipdeps}} to this.<br />
<br />
<pre>export PERL_AUTOINSTALL='--skipdeps'</pre><br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{Filename|Makefile.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
<pre>export PERL_MM_OPT=INSTALLBASE=~/perl5</pre><br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT, except for {{Codeline|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
<pre>export PERL_MB_OPT=--install_base=~/perl5</pre><br />
<br />
====MODULEBUILDRC====<br />
{{Codeline|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{Filename|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Codeline|MODULEBUILDRC}}. The paranoid might set {{Codeline|MODULEBUILDRC}} to {{Filename|/dev/null}}... just in case.<br />
<br />
===Hardened Example===<br />
Using all of our new accumulated knowledge, we can create a more hardened PKGBUILD that will resist any environment variables' attempts to sabotage it:<br />
<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc='This is the awesome Foo::Bar module!'<br />
arch=('any')<br />
url='http://search.cpan.org/dist/Foo-Bar'<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=("http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz")<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# Setting these env variables overwrites any command-line-options we don't want...<br />
<br />
# If using Makefile.PL (ExtUtils::MakeMaker or Module::Install)<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MM_OPT="INSTALLDIRS=vendor DESTDIR=$pkgdir"<br />
<br />
# If using Build.PL (Module::Build)<br />
export PERL_MM_USE_DEFAULT=1 PERL_AUTOINSTALL=--skipdeps \<br />
PERL_MB_OPT="--installdirs vendor --destdir $pkgdir" \<br />
MODULEBUILDRC=/dev/null<br />
<br />
# If using Makefile.PL<br />
{ perl Makefile.PL &&<br />
make &&<br />
make test &&<br />
make install; } || return 1<br />
<br />
# If using Build.PL<br />
{ perl Build.PL &&<br />
perl Build test &&<br />
perl Build install; } || return 1<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name .packlist -o -name perllocal.pod -delete<br />
</pre></div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=106095Perl package guidelines2010-05-11T01:41:33Z<p>Juster: /* PERL_MB_OPT */ Fix bad bash.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
[[Category:Guidelines (English)]]<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{Filename|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Codeline|INSTALLDIRS}} variable as shown below). No files should be stored in {{Filename|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{Filename|perllocal.pod}} and {{Filename|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{Filename|/usr/share/pacman/PKGBUILD-perl.proto}} which is present in the {{Package Official|abs}} package. It is also reproduced below (without the comments):<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url=""<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor || return 1<br />
make || return 1<br />
make install DESTDIR="$pkgdir/" || return 1<br />
<br />
## for packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
# perl Build install<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name perllocal.pod -delete<br />
find "$pkgdir" -name .packlist -delete<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the {{Codeline|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
The more perlish method is to use a {{Codeline|CPANPLUS::Dist}} plugin for installing CPAN modules as dynamically generated pacman packages, available at http://aur.archlinux.org/packages.php?ID=24971<br />
<br />
There is also a script called {{Codeline|pacpan}}, which can recursively generate PKGBUILDs for a module: http://aur.archlinux.org/packages.php?ID=23495<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Codeline|package}} keyword in perl. Modules are contained inside a {{Filename|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Codeline|package}}) is in the file. Modules have namespaces separated with {{Codeline|::}} (double colons), like: {{Codeline|Archlinux::Module}}. When loading a module, the {{Codeline|::}}s are replaced with directory separators. For example: {{Filename|Archlinux/Module.pm}} will be loaded for the module {{Codeline|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{Filename|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{Filename|Template-Toolkit-2.22.tar.gz}}, for the {{Codeline|Template-Toolkit}} dist, contains no {{Codeline|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Codeline|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{Filename|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{Filename|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{Filename|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Codeline|Module::Build}} was not already installed, you could not run the bundled {{Filename|Build.PL}} script! This is not a problem with recent versions of perl because {{Codeline|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Codeline|Module::Install}} still requires the {{Filename|make}} program be installed to function. It was designed as a drop-in replacement for {{Codeline|ExtUtils::MakeMaker}}, to address some of {{Codeline|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Codeline|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Codeline|MakeMaker}} or {{Codeline|M::B}}, you do not need {{Codeline|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Codeline|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{Filename|Makefile.PL}} is executed. This feature is skipped when {{Codeline|Module::Install}} detects it is being run by {{Codeline|CPAN}} or {{Codeline|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{Filename|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Codeline|Module::Install}}'s {{Filename|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Codeline|--skipdeps}} to this.<br />
<br />
<pre>export PERL_AUTOINSTALL='--skipdeps'</pre><br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{Filename|Makefile.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
<pre>export PERL_MM_OPT=INSTALLBASE=~/perl5</pre><br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT, except for {{Codeline|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
<pre>export PERL_MB_OPT=--install_base=~/perl5</pre><br />
<br />
====MODULEBUILDRC====<br />
{{Codeline|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{Filename|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Codeline|MODULEBUILDRC}}. The paranoid might set {{Codeline|MODULEBUILDRC}} to {{Filename|/dev/null}}... just in case.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=106094Perl package guidelines2010-05-11T01:32:21Z<p>Juster: Add information for advanced packagers, how things work, environment variables.</p>
<hr />
<div>[[Category:Package development (English)]]<br />
[[Category:Guidelines (English)]]<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{Filename|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Codeline|INSTALLDIRS}} variable as shown below). No files should be stored in {{Filename|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{Filename|perllocal.pod}} and {{Filename|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{Filename|/usr/share/pacman/PKGBUILD-perl.proto}} which is present in the {{Package Official|abs}} package. It is also reproduced below (without the comments):<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url=""<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor || return 1<br />
make || return 1<br />
make install DESTDIR="$pkgdir/" || return 1<br />
<br />
## for packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
# perl Build install<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name perllocal.pod -delete<br />
find "$pkgdir" -name .packlist -delete<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the {{Codeline|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
The more perlish method is to use a {{Codeline|CPANPLUS::Dist}} plugin for installing CPAN modules as dynamically generated pacman packages, available at http://aur.archlinux.org/packages.php?ID=24971<br />
<br />
There is also a script called {{Codeline|pacpan}}, which can recursively generate PKGBUILDs for a module: http://aur.archlinux.org/packages.php?ID=23495<br />
<br />
==Advanced Topics==<br />
If the packager has become comfortable enough with creating perl packages, the below sections may offer some new ideas to consider. This information might also help troubleshooting packaging problems.<br />
<br />
===Glossary===<br />
<br />
You should be familiar with the following terms.<br />
<br />
====Module====<br />
Modules are declared with the {{Codeline|package}} keyword in perl. Modules are contained inside a {{Filename|.pm}} ("dot-pee-em") file. Though it's possible more than one module ({{Codeline|package}}) is in the file. Modules have namespaces separated with {{Codeline|::}} (double colons), like: {{Codeline|Archlinux::Module}}. When loading a module, the {{Codeline|::}}s are replaced with directory separators. For example: {{Filename|Archlinux/Module.pm}} will be loaded for the module {{Codeline|Archlinux::Module}}.<br />
<br />
====Core Module====<br />
Core modules are included with an installation of perl. Some core modules are ''only'' available bundled with perl. Other modules can still be downloaded and installed separately from CPAN.<br />
<br />
====Distributions====<br />
(aka dist, package) This is the equivalent of an Archlinux package in CPAN-lingo. Distributions are {{Filename|.tar.gz}} archives full of files. These archives contain primarily .pm module files, tests for the included modules, documentation for the modules, and whatever else is deemed necessary.<br />
<br />
Usually a distribution contains a primary module with the same name. Sometimes this is not true, like with the Template-Toolkit distribution. The latest package, {{Filename|Template-Toolkit-2.22.tar.gz}}, for the {{Codeline|Template-Toolkit}} dist, contains no {{Codeline|Template::Toolkit}} module!<br />
<br />
Sometimes because distributions are named after a main module, their names are used interchangeably and they get muddled together. However it is sometimes useful to consider them a separate entity (like in Template-Toolkit's case).<br />
<br />
===Installation Modules===<br />
One of perl's greatest advantages is the sheer number of modules[/dists] available on CPAN. Not too surprisingly, there are also several different modules used for installing... well... modules! TMTOWTDI! I am not aware of a standard name for these types of modules, so I just called them "Installation Modules".<br />
<br />
All these modules are concerned with is building the package and installing wherever the user wants. This seems straightforward, but considering the number of different systems perl runs on, this can get complex. These modules all place a perl code file inside the dist tarball. Running this perl script will initiate the build/installation process. I have called this the "Build script" in the below list.<br />
<br />
====ExtUtils::MakeMaker====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/ExtUtils-MakeMaker<br />
<br />
The original, oldest module for installing modules is {{Codeline|ExtUtils::MakeMaker}}. The major downside to this module is that it requires the {{Filename|make}} program to build and install everything. This may not seem like a big deal to linux users but is a real hassle for Windows people! In the name of progress the perl community is trying to encourage people to use the newer modules instead.<br />
<br />
====Module::Build====<br />
<br />
;Build script: {{Filename|Build.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Build<br />
<br />
The main advantage of Module::Build is that it is pure-perl. This means it does not require a {{Filename|make}} program to be installed for you to build/install modules. Its adoption was rocky because if {{Codeline|Module::Build}} was not already installed, you could not run the bundled {{Filename|Build.PL}} script! This is not a problem with recent versions of perl because {{Codeline|Module::Build}} is a core module.<br />
<br />
====Module::Install====<br />
<br />
;Build script: {{Filename|Makefile.PL}}<br />
;CPAN link: http://search.cpan.org/dist/Module-Install<br />
<br />
Another modern build/installation module, {{Codeline|Module::Install}} still requires the {{Filename|make}} program be installed to function. It was designed as a drop-in replacement for {{Codeline|ExtUtils::MakeMaker}}, to address some of {{Codeline|MakeMaker}}'s shortcomings. <br />
<br />
One very interesting feature is that {{Codeline|Module::Install}} bundles a ''complete'' ''copy'' of itself into the distribution file. Because of this, unlike {{Codeline|MakeMaker}} or {{Codeline|M::B}}, you do not need {{Codeline|Module::Install}} to be installed on your system.<br />
<br />
Another very unique feature is auto-install. ''This appears to be not recommended, but seems used quite often.'' When the module author enables auto-install for his distribution, {{Codeline|Module::Install}} will search for and install any pre-requisite modules that are not installed when {{Filename|Makefile.PL}} is executed. This feature is skipped when {{Codeline|Module::Install}} detects it is being run by {{Codeline|CPAN}} or {{Codeline|CPANPLUS}}. However, this feature is not skipped when run inside... oh I don't know... a '''PKGBUILD'''! I hope you can see how a rogue perl program downloading and installing modules willy-nilly ''inside a PKGBUILD'' can be a problem. See the [[#PERL_AUTOINSTALL]] environment variable to see how to fix this.<br />
<br />
===Environment Variables===<br />
A number of environment variables can affect the way the modules are built or installed. Some have a very dramatic effect and can cause problems if misunderstood. An advanced user could be using these environment variables. Some of these will break an unsuspecting {{Filename|PKGBUILD}}; or cause unexpected behavior.<br />
<br />
====PERL_MM_USE_DEFAULT====<br />
When this variable is set to a true value, the installation module will pretend the default answer was given to any question it would normally ask. This does not ''always'' work, but all of the installation modules honour it. ''That doesn't mean the module author will!''<br />
<br />
====PERL_AUTOINSTALL====<br />
You can pass additional command-line arguments to {{Codeline|Module::Install}}'s {{Filename|Makefile.PL}} with this variable. In order to turn off auto-install (''highly recommended''), assign {{Codeline|--skipdeps}} to this.<br />
<br />
<pre>export PERL_AUTOINSTALL='--skipdeps'</pre><br />
<br />
====PERL_MM_OPT====<br />
You can pass additional command-line arguments to {{Filename|Makefile.PL}} with this variable. For example, you can install modules into your home-dir by using:<br />
<br />
<pre>export PERL_MM_OPT=INSTALLBASE=~/perl5</pre><br />
<br />
====PERL_MB_OPT====<br />
This is the same thing as PERL_MM_OPT, except for {{Codeline|Module::Build}}. For example, you could install modules into your home-dir by using: <br />
<br />
<pre>export PERL_MB_OPT=--install_base ~/perl5</pre><br />
<br />
====MODULEBUILDRC====<br />
{{Codeline|Module::Build}} allows you to override its command-line-arguments with an rcfile. This defaults to {{Filename|~/.modulebuildrc}}. You can override which file it uses by setting the path to the rcfile in {{Codeline|MODULEBUILDRC}}. The paranoid might set {{Codeline|MODULEBUILDRC}} to {{Filename|/dev/null}}... just in case.</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=106082Perl package guidelines2010-05-10T23:38:37Z<p>Juster: Remove the legacy pre-5.10 perl info. If people need it they can look at history!</p>
<hr />
<div>[[Category:Package development (English)]]<br />
[[Category:Guidelines (English)]]<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in {{Filename|/usr/lib/perl5/vendor_perl/}} (this is done by setting the {{Codeline|INSTALLDIRS}} variable as shown below). No files should be stored in {{Filename|/usr/lib/perl5/site_perl/}} as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files {{Filename|perllocal.pod}} and {{Filename|.packlist}} also should not be present; this is taken care of by the example [[PKGBUILD]] given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at {{Filename|/usr/share/pacman/PKGBUILD-perl.proto}} which is present in the {{Package Official|abs}} package. It is also reproduced below (without the comments):<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url=""<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor || return 1<br />
make || return 1<br />
make install DESTDIR="$pkgdir/" || return 1<br />
<br />
## for packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
# perl Build install<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name perllocal.pod -delete<br />
find "$pkgdir" -name .packlist -delete<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the {{Codeline|arch}} array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
The more perlish method is to use a {{Codeline|CPANPLUS::Dist}} plugin for installing CPAN modules as dynamically generated pacman packages, available at http://aur.archlinux.org/packages.php?ID=24971<br />
<br />
There is also a script called {{Codeline|pacpan}}, which can recursively generate PKGBUILDs for a module: http://aur.archlinux.org/packages.php?ID=23495</div>Justerhttps://wiki.archlinux.org/index.php?title=Perl_package_guidelines&diff=83330Perl package guidelines2009-11-12T22:06:29Z<p>Juster: added my own CPANPLUS::Dist plugin to the end of Automation</p>
<hr />
<div>[[Category:Package development (English)]]<br />
[[Category:Guidelines (English)]]<br />
==Package Naming==<br />
For modules the package name should begin with '''perl-''' and the rest of the name should be constructed from the module name by converting it to lowercase and then replacing colons with hyphens. For example the package name corresponding to HTML::Parser will be '''perl-html-parser'''. Perl applications should have the same name as that of the application but in lowercase.<br />
<br />
==File Placement==<br />
Perl modules should install module files in ''/usr/lib/perl5/vendor_perl/'' (this is done by setting the ''INSTALLDIRS'' variable as shown below). No files should be stored in ''/usr/lib/perl5/site_perl/'' as that directory is reserved for use by the system administrator to install Perl packages outside the package management system. The files ''perllocal.pod'' and ''.packlist'' also should not be present; this is taken care of by the example PKGBUILD given below.<br />
<br />
==Example==<br />
An example PKGBUILD can be found at ''/usr/share/pacman/PKGBUILD-perl.proto'' which is present in the '''abs''' package. It is also reproduced below (without the comments)<br />
<br />
<pre><br />
# Contributor: Your Name <youremail@domain.com><br />
pkgname=perl-foo-bar<br />
pkgver=VERSION<br />
pkgrel=1<br />
pkgdesc=""<br />
arch=()<br />
url=""<br />
license=('GPL' 'PerlArtistic')<br />
depends=('perl>=5.10.0')<br />
makedepends=()<br />
provides=()<br />
conflicts=()<br />
replaces=()<br />
backup=()<br />
options=(!emptydirs)<br />
install=<br />
source=(http://search.cpan.org/CPAN/authors/id/***/***-$pkgver.tar.gz)<br />
md5sums=()<br />
<br />
build() {<br />
cd "$srcdir/***-$pkgver"<br />
<br />
# install module in vendor directories.<br />
PERL_MM_USE_DEFAULT=1 perl Makefile.PL INSTALLDIRS=vendor || return 1<br />
make || return 1<br />
make install DESTDIR="$pkgdir/" || return 1<br />
<br />
## for packages with Build.PL, do this instead:<br />
# perl Build.PL installdirs=vendor destdir="$pkgdir/"<br />
# perl Build<br />
# perl Build install<br />
<br />
# remove perllocal.pod and .packlist<br />
find "$pkgdir" -name perllocal.pod -delete<br />
find "$pkgdir" -name .packlist -delete<br />
}<br />
<br />
# vim:set ts=2 sw=2 et:<br />
</pre><br />
<br />
In most cases, you should put '''any''' in the ''arch'' array since most Perl packages are architecture independent.<br />
<br />
==Automation==<br />
As Perl is centered around the [http://www.cpan.org CPAN], there are a few scripts to make the most of this, and save you writing PKGBUILDs by hand.<br />
<br />
There is a CPANPLUS::Dist plugin which adds support for pacman, available on the AUR: http://aur.archlinux.org/packages.php?ID=5954<br />
<br />
There is also a script called pacpan, which can generate (recursively) PKGBUILDs for a module: http://aur.archlinux.org/packages.php?ID=23495<br />
<br />
A second CPANPLUS::Dist plugin for installing CPAN modules as dynamically generated pacman packages is available at http://aur.archlinux.org/packages.php?ID=24971<br />
<br />
==Before Perl 5.10.0-1 (legacy)==<br />
'''This section refers to the old Perl guidelines and is kept for historical purposes only.'''<br />
<br />
<br />
Packages before perl 5.10.0-1 installed modules into /usr/lib/perl5/current and /usr/lib/perl5/site_perl/current.<br />
<br />
<br />
=== Example Makefile.PL PKGBUILD ===<br />
<br />
<pre><br />
# Contributor: Your Name <your_email@foobar.org><br />
pkgname=perl-dbd-pg<br />
pkgver=1.49<br />
pkgrel=1<br />
pkgdesc="Postgres Driver for DBI"<br />
url="http://search.cpan.org/~DBDPG/DBD-Pg"<br />
depends=('perl-dbi>=1.45')<br />
license=('GPL')<br />
options=('!emptydirs')<br />
arch=('i686' 'x86_64')<br />
source=(http://www.cpan.org/authors/id/D/DB/DBDPG/DBD-Pg-$pkgver.tar.gz) <br />
md5sums=('76b9d6a2f4cbaefcba23380f83998215')<br />
<br />
build() {<br />
cd ${srcdir}/DBD-Pg-$pkgver<br />
eval `perl -V:archname`<br />
/usr/bin/perl Makefile.PL \<br />
INSTALLARCHLIB=/usr/lib/perl5/current/${archname} \<br />
INSTALLSITELIB=/usr/lib/perl5/site_perl/current \<br />
INSTALLSITEARCH=/usr/lib/perl5/site_perl/current/${archname}<br />
/usr/bin/make || return 1<br />
/usr/bin/make DESTDIR=${pkgdir} install<br />
/usr/bin/find ${pkgdir} -name '.packlist' -delete<br />
/usr/bin/find ${pkgdir} -name '*.pod' -delete<br />
}<br />
</pre><br />
<br />
===Example Build.PL PKGBUILD ===<br />
<pre><br />
# Contributor: Your Name <your_email@foobar.org><br />
pkgname=perl-string-random<br />
pkgver=0.22<br />
pkgrel=1<br />
pkgdesc="Generate random strings"<br />
url="http://search.cpan.org/~STEVE/String-Random"<br />
makedepends=('perl-module-build')<br />
license=('GPL')<br />
options=('!emptydirs')<br />
arch=('i686' 'x86_64')<br />
source=(http://www.cpan.org/authors/id/S/ST/STEVE/String-Random-$pkgver.tar.gz) <br />
md5sums=('c0319f95c56450624cc646f7425e327e')<br />
<br />
build() {<br />
cd ${srcdir}/String-Random-$pkgver<br />
eval `perl -V:archname`<br />
perl Build.PL destdir=${pkgdir} \<br />
--install_path lib=/usr/lib/perl5/site_perl/current \<br />
--install_path arch=/usr/lib/perl5/site_perl/current/${archname}<br />
./Build<br />
./Build install<br />
/usr/bin/find ${pkgdir} -name '.packlist' -delete<br />
/usr/bin/find ${pkgdir} -name '*.pod' -delete<br />
}<br />
</pre></div>Justerhttps://wiki.archlinux.org/index.php?title=OpenSSH&diff=51643OpenSSH2008-10-23T00:51:27Z<p>Juster: /* Step 2: Configure your Browser */ fixed typos</p>
<hr />
<div>[[Category:Daemons_and_system_services (English)]]<br />
<br />
= Introduction =<br />
Secure Shell or SSH is a network protocol that allows data to be exchanged over a secure channel between two computers. Encryption provides confidentiality and integrity of data. SSH uses public-key cryptography to authenticate the remote computer and allow the remote computer to authenticate the user, if necessary.<br />
<br />
SSH is typically used to log into a remote machine and execute commands, but it also supports tunneling, forwarding arbitrary TCP ports and X11 connections; it can transfer files using the associated SFTP or SCP protocols.<br />
<br />
An SSH server, by default, listens on the standard TCP port 22. An ssh client program is typically used for establishing connections to an sshd daemon accepting remote connections. Both are commonly present on most modern operating systems, including Mac OS X, Linux, Solaris and OpenVMS. Proprietary, freeware and open source versions of various levels of complexity and completeness exist.<br />
<br />
==OpenSSH==<br />
<br />
OpenSSH (OpenBSD Secure Shell) is a set of computer programs providing encrypted communication sessions over a computer network using the ssh protocol. It was created as an open source alternative to the proprietary Secure Shell software suite offered by SSH Communications Security. OpenSSH is developed as part of the OpenBSD project, which is led by Theo de Raadt.<br />
<br />
OpenSSH is occasionally confused with the similarly-named OpenSSL; however, the projects have different purposes and are developed by different teams, the similar name is drawn only from similar goals.<br />
<br />
=Installing OpenSSH=<br />
<br />
<pre><br />
pacman -Sy openssh<br />
</pre><br />
<br><br />
<br />
==Configuring the SSH server==<br />
<br />
To configure you must edit the configuration file:<br />
<br />
<pre><br />
su -c 'nano /etc/ssh/sshd_config'<br />
</pre><br />
<br />
You may want to change the default port from 22 to any higher port (see [http://en.wikipedia.org/wiki/Security_through_obscurity security through obscurity]). <br />
<br />
Even though the port ssh is running on, could be detected by using a port-scanner like nmap, changing it will reduce the number of log entries caused by automated authentication attempts.<br />
<br />
===Adjust the configuration===<br />
<br />
The configuration file can be found at ''/etc/ssh/ssh_config'' and the basic version looks like this:<br />
<br />
<pre><br />
# $OpenBSD: sshd_config,v 1.75 2007/03/19 01:01:29 djm Exp $<br />
<br />
# This is the ssh client system-wide configuration file. See<br />
# ssh_config(5) for more information. This file provides defaults for<br />
# users, and the values can be changed in per-user configuration files<br />
# or on the command line.<br />
<br />
# Configuration data is parsed as follows:<br />
# 1. command line options<br />
# 2. user-specific file<br />
# 3. system-wide file<br />
# Any configuration value is only changed the first time it is set.<br />
# Thus, host-specific definitions should be at the beginning of the<br />
# configuration file, and defaults at the end.<br />
<br />
# Site-wide defaults for various options<br />
<br />
# Host *<br />
# ForwardAgent no<br />
# ForwardX11 no<br />
# RhostsRSAAuthentication no<br />
# RSAAuthentication yes<br />
# PasswordAuthentication yes<br />
# HostbasedAuthentication no<br />
# BatchMode no<br />
# CheckHostIP yes<br />
# AddressFamily any<br />
# ConnectTimeout 0<br />
# StrictHostKeyChecking ask<br />
# IdentityFile ~/.ssh/identity<br />
# IdentityFile ~/.ssh/id_rsa<br />
# IdentityFile ~/.ssh/id_dsa<br />
# Port 22<br />
# Protocol 2,1<br />
# Cipher 3des<br />
# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc<br />
# EscapeChar ~<br />
</pre><br />
<br><br />
It is recommended to change the Protocol line into this:<br><br />
<pre><br />
Protocol 2<br />
</pre><br />
<br><br />
That means that only Protocol 2 will be used, since Protocol 1 is considered somewhat insecure.<br><br />
Of course there is also a configuration file for the SSH daemon. It's called ''/etc/ssh/sshd_config'' and looks like this:<br><br />
<pre><br />
# $OpenBSD: sshd_config,v 1.75 2007/03/19 01:01:29 djm Exp $<br />
<br />
# This is the sshd server system-wide configuration file. See<br />
# sshd_config(5) for more information.<br />
<br />
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin<br />
<br />
# The strategy used for options in the default sshd_config shipped with<br />
# OpenSSH is to specify options with their default value where<br />
# possible, but leave them commented. Uncommented options change a<br />
# default value.<br />
<br />
#Port 22<br />
#Protocol 2,1<br />
ListenAddress 0.0.0.0<br />
#ListenAddress ::<br />
<br />
# HostKey for protocol version 1<br />
#HostKey /etc/ssh/ssh''host''key<br />
# HostKeys for protocol version 2<br />
#HostKey /etc/ssh/ssh''host''rsa_key<br />
#HostKey /etc/ssh/ssh''host''dsa_key<br />
<br />
# Lifetime and size of ephemeral version 1 server key<br />
#KeyRegenerationInterval 1h<br />
#ServerKeyBits 768<br />
<br />
# Logging<br />
#obsoletes ~QuietMode and ~FascistLogging<br />
#SyslogFacility AUTH<br />
#LogLevel INFO<br />
<br />
# Authentication:<br />
<br />
#LoginGraceTime 2m<br />
#PermitRootLogin yes<br />
#StrictModes yes<br />
#MaxAuthTries 6<br />
<br />
#RSAAuthentication yes<br />
#PubkeyAuthentication yes<br />
#AuthorizedKeysFile .ssh/authorized_keys<br />
<br />
# For this to work you will also need host keys in /etc/ssh/ssh''known''hosts<br />
#RhostsRSAAuthentication no<br />
# similar for protocol version 2<br />
#HostbasedAuthentication no<br />
# Change to yes if you don't trust ~/.ssh/known_hosts for<br />
# RhostsRSAAuthentication and HostbasedAuthentication<br />
#IgnoreUserKnownHosts no<br />
# Don't read the user's ~/.rhosts and ~/.shosts files<br />
#IgnoreRhosts yes<br />
<br />
# To disable tunneled clear text passwords, change to no here!<br />
#PasswordAuthentication yes<br />
#PermitEmptyPasswords no<br />
<br />
# Change to no to disable s/key passwords<br />
#ChallengeResponseAuthentication yes<br />
<br />
# Kerberos options<br />
#KerberosAuthentication no<br />
#KerberosOrLocalPasswd yes<br />
#KerberosTicketCleanup yes<br />
#KerberosGetAFSToken no<br />
<br />
# GSSAPI options<br />
#GSSAPIAuthentication no<br />
#GSSAPICleanupCredentials yes<br />
<br />
# Set this to 'yes' to enable PAM authentication, account processing,<br />
# and session processing. If this is enabled, PAM authentication will<br />
# be allowed through the ~ChallengeResponseAuthentication mechanism.<br />
# Depending on your PAM configuration, this may bypass the setting of<br />
# PasswordAuthentication, ~PermitEmptyPasswords, and<br />
# "PermitRootLogin without-password". If you just want the PAM account and<br />
# session checks to run without PAM authentication, then enable this but set<br />
# ChallengeResponseAuthentication=no<br />
#UsePAM no<br />
<br />
#AllowTcpForwarding yes<br />
#GatewayPorts no<br />
#X11Forwarding no<br />
#X11DisplayOffset 10<br />
#X11UseLocalhost yes<br />
#PrintMotd yes<br />
#PrintLastLog yes<br />
#TCPKeepAlive yes<br />
#UseLogin no<br />
#UsePrivilegeSeparation yes<br />
#PermitUserEnvironment no<br />
#Compression yes<br />
#ClientAliveInterval 0<br />
#ClientAliveCountMax 3<br />
#UseDNS yes<br />
#PidFile /var/run/sshd.pid<br />
#MaxStartups 10<br />
<br />
# no default banner path<br />
#Banner /some/path<br />
<br />
# override default of no subsystems<br />
Subsystem sftp /usr/lib/ssh/sftp-server<br />
<br />
</pre><br />
<br><br />
To allow access only for some users add this line:<br><br />
<pre><br />
AllowUsers user1 user2<br />
</pre><br />
<br><br />
You might want to change some lines so that they look as following :<br><br />
<pre><br />
Protocol 2<br />
.<br />
.<br />
.<br />
LoginGraceTime 120<br />
.<br />
.<br />
.<br />
PermitRootLogin no # ( put yes here if you want root login )<br />
</pre><br />
<br><br />
You could also uncomment the BANNER option and edit ''/etc/issue'' for a nice welcome message.<br />
<br />
===Allowing others in===<br />
<br />
{{Box Note | You have to adjust this file to remotely connect to your machine since the file is empty by default}}<br />
<br />
To let other people ssh to your machine you need to adjust ''/etc/hosts.allow'', add the following: <br><br />
<br />
<pre><br />
# let everyone connect to you<br />
sshd: ALL<br />
<br />
# OR you can restrict it to a certain ip<br />
sshd: 192.168.0.1<br />
<br />
# OR restrict for an IP range<br />
sshd: 10.0.0.0/255.255.255.0<br />
<br />
# OR restrict for an IP match<br />
sshd: 192.168.1.<br />
</pre><br />
<br><br />
Now you should check your ''/etc/hosts.deny'' for the following line and make sure it looks like this<br />
<br><br />
<pre><br />
ALL: ALL: DENY<br />
</pre><br />
<br><br />
That's it. You can SSH out and others should be able to SSH in :)<br><br />
<br />
<br />
To start using the new configuration, restart the daemon:<br />
<br />
<pre><br />
su -c '/etc/rc.d/sshd restart'<br />
</pre><br />
<br />
==Managing SSHD Daemon==<br />
<br />
Just add sshd to the "DAEMONS" section of your /etc/rc.conf:<br />
<br />
<pre><br />
DAEMONS=(... ... ... ... ... sshd ... ... ...)<br />
</pre><br />
<br><br />
<br />
To start/restart/stop the daemon, use the following:<br />
<br />
<pre><br />
/etc/rc.d/sshd {start|stop|restart}<br />
</pre><br />
<br><br />
<br />
<br />
==Connecting to the server==<br />
<br />
To connect to a server, run:<br />
<br />
<pre><br />
ssh -p port user@server-address<br />
</pre><br />
<br />
==Links & References==<br />
<br />
[[A Cure for the Common SSH Login Attack]] <br><br />
[http://www.la-samhna.de/library/brutessh.html Defending against brute force ssh attacks]<br />
<br />
<br />
= Tips and Tricks =<br />
<br />
== Encrypted Socks Tunnel ==<br />
<br />
This is highly useful for laptop users connected to various unsafe wireless connections. The only thing you need is an SSH server running at a somewhat secure location, like your home or at work. It might be useful to use a dynamic DNS service like [http://www.dyndns.org/ DynDNS] so you don't have to remember your IP-address.<br />
<br />
=== Step 1: Start the Connection ===<br />
<br />
You only have to execute this single command in your favorite terminal to start the connection:<br />
<pre><br />
ssh -ND 4711 user@host<br />
</pre><br />
where "user" is your username at the SSH server running at the "host". It will ask for your password, and then you're connected! The "N" flag disables the interactive prompt, and the "D" flag specifies the local port on wich to listen on (you can choose any port number if you want).<br />
<br />
One way to make this easier is to put an alias line in your ~/.bashrc file as following:<br />
<pre><br />
alias sshtunnel="ssh -ND 4711 -v user@host"<br />
</pre><br />
It's nice to add the verbose "-v" flag, because then you can verify that it's actually connected from that output. Now you just have to execute the "sshtunnel" command :)<br />
<br />
=== Step 2: Configure your Browser ===<br />
<br />
The above step is completely useless if you don't configure your web browser to use this newly created socks tunnel. <br />
<br />
For Firefox it's quite easy: go to the Edit menu, and choose Preferences. Go to Advanced -> Network -> Connection -> Settings. Check the "Manual proxy configuration" radio button, and enter "localhost" in the "SOCKS host" text field, and then enter your port number in the next text field (I used 4711 above).<br />
<br />
Enjoy your secure tunnel!</div>Juster