The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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 ressources 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:
  <http://issues.apache.org/SpamAssassin/>

[DEBPERL] Debian Perl Policy, Chapter 3: Packaged Modules:
  <http://www.debian.org/doc/packaging-manuals/perl-policy/ch-module_packages.html>

[GNUMAKECMD] GNU make manual: Make Conventions: Variables for Specifying
  Commands
  <http://www.gnu.org/manual/make-3.79.1/html_chapter/make_14.html#SEC119>

[MANEUMM616] The man page for ExtUtils::MakeMaker 6.16:
  <http://search.cpan.org/author/MSCHWERN/ExtUtils-MakeMaker-6.16/lib/ExtUtils/MakeMaker.pm#Default_Makefile_Behaviour>

[MM00779] makemaker-at-perl-dot-org: Michael G Schwern: "Re: MakeMaker
  problems with relocation" (PREFIX was broken):
  <http://www.mail-archive.com/makemaker@perl.org/msg00779.html>

[P5P94113] perl5-porters: Michael G Schwern: "Re: OS X's vendorlib default
  seems wrong" (description of different repositoreis):
  <http://archive.develooper.com/perl5-porters@perl.org/msg94113.html>

[RHBUG78053] Red Hat bug 78053: "incompatible changes in behavior of
  MakeMaker; affects rpm build process" (introduction of DESTDIR):
  <https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=78053>