Introduction
------------
The Makefile which is used to build SpamAssassin is created by calling
perl Makefile.PL
This is the standard Perl way of building packages. It involves the
Perl module ExtUtils::MakeMaker which creates a Makefile.
ExtUtils::MakeMaker recognizes several variables which can be set at
the command line to give the user the possibility to influence the
contents of the generated Makefile. All macros written to the Makefile
can be changed on the command line like this:
perl Makefile.PL FOO="bar"
This would give the (exemplary) macro 'FOO' the value 'bar'.
Now has the internal structure of ExtUtils::MakeMaker and that of the
generated Makefiles changed over the years. For a description of the
features your version supports, please read
perldoc ExtUtils::MakeMaker
One important thing to know when you're building packages is that Perl
uses three different "repositories" for installed modules and their
corresponding files: 'perl', 'site' and 'vendor' (the latter was
introduced with Perl 5.6.0). These have the following meanings:
perl: This should be used only by essential modules shipped with
Perl or modules required by one of these. And maybe for some
other important modules chosen by some obscure selection
process. Only one thing is sure about this set of directories:
SpamAssassin doesn't belong there.
site: This is the default. The libs (.pm files) of the modules are
installed into the site_perl subdir in the Perl lib dir.
Everything installed via the CPAN shell or directly from
sources should go there.
vendor: This repository was officially introduced some time after
Perl 5.005_03 (maybe with 5.6.0). It's intended to be the
target for all modules installed from distribution specific
packages; that means RPMs, debs, ebuilds, etc. The rationale
behind this is that this prevents modules installed by the
user from being overwritten by packaged ones.
The wanted repository can be chosen by setting the variable INSTALLDIRS.
So according to the description above should packages probably use
perl Makefile.PL INSTALLDIRS=vendor
That's definitely the correct way to go for Debian, according to their
Perl Policy [DEBPERL]. But I've heard that the vendor stuff is either
broken or not set on many other systems, especially Red Hat ones. Google
might help to find out more on this topic.
The following resources might help understanding this stuff:
[MANEUMM616], [MM00779], [P5P94113].
Changing paths in the Makefile
------------------------------
Internally the Makefile defined quite some paths for the different settings
of INSTALLDIRS. One can change them directly but to be independent of the
version of ExtUtils::MakeMaker the following variables should be used:
PREFIX:
Sets the prefix below which SpamAssassin is installed. Please note the
exceptions for SYSCONFDIR.
Default is the prefix Perl was built with (call
perl -V:prefix
to see the value). Normally something like /usr or /usr/local.
Samples:
This will install the spamassassin apps in /foo/bin, the libs in
/foo/lib/perl5, the shared stuff in /foo/share/spamassassin and make
SpamAssassin look for config files in /foo/etc/mail/spamassassin:
perl Makefile.PL PREFIX=/foo
LIB:
This will change the directory where the SpamAssassin libraries (.pm files)
are installed. The module's architecture-independent files will be put into
the given directory, the architecture-dependent files into a subdirectory
with the name of the current architecture.
The default is something like PREFIX/lib/perl5/site_perl/PERL_VERSION (for
INSTALLDIRS=site).
Samples:
Under i686-Linux, put the architecture-independent files below ~/.libs
and the architecture-dependent ones below ~/.libs/i686-linux:
perl Makefile.PL LIB=~/.libs
DATADIR (DEFRULESDIR):
SpamAssassin's real logic lies in its shipped rule definitions and the
corresponding scores. The files with these settings have to be saved
somewhere, normally below PREFIX/share/spamassassin. The full path to
that directory can be changed with this variable (DEFRULESDIR is a
synonym).
ATTENTION: All files within this directory are removed when SpamAssassin
is installed!
Samples:
Install everything into the default locations but put the rules in
/tmp/sa-rules (for whatever reason):
perl Makefile.PL DATADIR=/tmp/sa-rules
SYSCONFDIR:
Sets the base dir for the config files. See also CONFDIR.
The default depends on the PREFIX and is compliant to the FHS:
- if PREFIX is either /usr or /usr/local:
/etc
- if PREFIX starts with /opt:
/etc/opt
- else:
PREFIX/etc
Samples:
This will (on Windows) install below 'C:\Program Files\SpamAssassin' but
look for the config files in 'C:\Program Files\Shared Files\SpamAssassin':
perl Makefile.PL PREFIX="C:/Program Files/SpamAssassin"
SYSCONFDIR="C:/Program Files/Shared Files/SpamAssassin"
To put the apps and libs below ~/.sa-bin but the config below ~/.sa-etc
try the following:
perl Makefile.PL PREFIX=$HOME/.sa-bin SYSCONFDIR=$HOME/.sa-etc
And the following installs SpamAssassin in /usr/local and forces the
config files to be below /usr/local, too:
perl Makefile.PL PREFIX=/usr/local SYSCONFDIR=/usr/local/etc
CONFDIR (LOCALRULESDIR):
SpamAssassin looks for its config files in SYSCONFDIR/mail/spamassassin.
(There is also a sample local.cf created if such a file doesn't exist yet.)
Some people didn't like this path for various reasons so the full path to
the config files can be changed here (this more or less makes SYSCONFDIR
obsolete). A synonym for this variable is LOCALRULESDIR.
Samples:
If you'd like to have the config files directly in /etc/spamassassin
try this:
perl Makefile.PL CONFDIR=/etc/spamassassin
LOCALSTATEDIR:
"sa-update" will download rule updates into LOCALSTATEDIR/spamassassin.
The default depends on the PREFIX and is compliant to the FHS:
- if PREFIX is either /usr or /usr/local:
/var/lib
- if PREFIX starts with /opt:
/var/opt
- else:
PREFIX/var
Samples:
If you'd like to have the downloaded rules files in /var/spamassassin
try this:
perl Makefile.PL LOCALSTATEDIR=/var
Installing to a directory different from the final destination
--------------------------------------------------------------
When you're building packages, it's often needed to install the stuff to
some temporary directory and then build the package from there. The problem
with this approach is that the build system of SpamAssassin needs to write
some final paths to the libs and the applications.
Previous versions offered some complicated variables to achieve this. Those
hacks weren't compatible to current versions of ExtUtils::MakeMaker. But
ExtUtils::MakeMaker 6.06 introduced a feature which is well known from the GNU
build tools [GNUMAKECMD]: The variable DESTDIR.
The value of DESTDIR is simply prepended to all other paths on make install.
So if you wanted to create a SpamAssassin package for a system which will
have it installed in /usr but you want to create that package from some temp
dir, you would do something like this:
perl Makefile.PL Makefile.PL PREFIX=/usr DESTDIR=/tmp/sa-build
make
make disttest
make install
cd /tmp/sa-build
build_some_package
Setting further options on the command line
-------------------------------------------
Besides the directories, the build process of SpamAssassin supports several
other settings to set or enable some features. For some of these settings
the user is asked before the Makefile is created. To avoid these questions
(and accept the defaults, whatever they are) it is possible to redirect
STDIN from the null device like this:
perl Makefile.PL < /dev/null
Or, under Windows:
perl Makefile.PL < nul
The following variables are supported:
ENABLE_SSL:
Can be set to either "yes" or "no" (default). Makes it possible to use SSL
encryption on the (TCP) connection between spamc and spamd.
Sample:
Build spamc with SSL, use defaults for all other questions:
perl Makefile.PL ENABLE_SSL=yes < /dev/null
CONTACT_ADDRESS:
Each reported spam contains an address under which the confused user/client
can request more information about the tagging of his mail. That address can
be set here. The default is to query the buildung user, falling back to the
string "the administrator of that system".
Sample:
The user can find some information on the page http://example.com/tag/:
perl Makefile.PL CONTACT_ADDRESS="http://example.com/tag/"
RUN_NET_TESTS:
Vipul's Razor and Net::DNS are optional modules. If one of those modules is
found to be installed, some special tests can be performed when 'make test'
is run. The builder is asked if he wants to do so. Default is "no" (because
those tests can fail if there are problems with the network connection or
the servers).
Sample:
Run only the Razor tests:
perl Makefile.PL RUN_NET_TESTS=yes < /dev/null
make test TEST_FILES="t/razor*.t"
Twisting Perl details
---------------------
The build process of SpamAssassin has to know several details of the Perl
calling it later. This is used to work around some Perl bugs and make it
all actually work :o) The following additional variables are supported to
modify these settings:
PERL_BIN:
The path to the perl application which will be used to call the scripts
(like spamassassin and spamd). It makes sense to set this if you build
SpamAssassin on some weird build host which happen to have Perl in
/some/weird/location which is definitely not the location on the end
user's box. The default is the value of the macro FULLPERL which should
be the path to the perl processing Makefile.PL.
Sample:
Building with some weird perl:
/local/buildsys/perl-5.6.1/bin/perl Makefile.PL PERL_BIN=/usr/bin/perl
Obsolete Variables
------------------
The following list shows variables recognized by the old build system and
their new counterparts (no, the ones in the end aren't in the wrong order,
it actually was that complicated):
old: PREFIX=/bar/foo INST_PREFIX=/foo
new: PREFIX=/foo DESTDIR=/bar
old: INST_SITELIB=/foo
new: LIB=/foo
old: SYSCONFDIR=/bar/foo INST_SYSCONFDIR=/foo
new: SYSCONFDIR=/foo DESTDIR=/bar
old: LOCAL_RULES_DIR=/foo PKG_LOCAL_RULES_DIR=/bar/foo
new: LOCALRULESDIR=/foo DESTDIR=/bar
old: DEF_RULES_DIR=/foo PKG_DEF_RULES_DIR=/bar/foo
new: DEFRULESDIR=/foo DESTDIR=/bar
Using one of the following variables will make the Makefile generation
process die:
INST_PREFIX
INST_SITELIB
INST_SYSCONFDIR
LOCAL_RULES_DIR
DEF_RULES_DIR
If you think you need to use one of those nevertheless, you can set the
variable IGNORE_CRUFT to "yes".
Resources
---------
[BUGZILLA] SpamAssassin bug database:
[DEBPERL] Debian Perl Policy, Chapter 3: Packaged Modules:
[GNUMAKECMD] GNU make manual: Make Conventions: Variables for Specifying
Commands
[MANEUMM616] The man page for ExtUtils::MakeMaker 6.16:
[MM00779] makemaker-at-perl-dot-org: Michael G Schwern: "Re: MakeMaker
problems with relocation" (PREFIX was broken):
[P5P94113] perl5-porters: Michael G Schwern: "Re: OS X's vendorlib default
seems wrong" (description of different repositoreis):
[RHBUG78053] Red Hat bug 78053: "incompatible changes in behavior of
MakeMaker; affects rpm build process" (introduction of DESTDIR):