
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 will hopefully be replaced by
Module::Build one day) 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.

SpamAssassin needs some directories which normally aren't supported by
ExtUtils::MakeMaker. So we had to extend its logic quite a bit. And to
make it worse did the internal logic change extremely between the 5.x
and 6.x series, especially for packaging stuff. We had to "backport"
(ie. hack into) some of the functionality ExtUtils::MakeMaker 6.11 and
later offers. It's obvious how error-prone this is. So the recommended
version of ExtUtils::MakeMaker is 6.16 or later.

The following ressources might help understanding this stuff:
[MANEUMM616], [MM00779], [P5P94113].

It's also possible to build SpamAssassin with a current version of
ExtUtils::MakeMaker without upgrading the system. See the section
"Building with another ExtUtils::MakeMaker" for details.


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 said to be buggy
till 6.11) 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

ATTENTION: This method heavily depends on a feature introduced with a newer
version of ExtUtils::MakeMaker. So it's *strongly* recommended to use
  ExtUtils::MakeMaker 6.16 or later
when building packages. That module is available here [GETEUMM616]. If any
problems occur with previous versions, please report them to [BUGZILLA].
See also "Building with another ExtUtils::MakeMaker".


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

PERL_VERSION:
  The build system has to know the version of the Perl which will actually
  call SpamAssassin. Normally the app given by PERL_BIN is executed and asked
  for its version. If that fails, the version of the perl which called
  Makefile.PL is used. Sometimes one might have to correct this.

  Sample:
    Building with Perl 5.8.0 for Perl 5.6.2:
    	perl-5.8.0 Makefile.PL PERL_VERSION=5.6.2


Building with another ExtUtils::MakeMaker
-----------------------------------------

It is possible to use a different version than the one which is installed.
This is very useful if one wants to package SpamAssassin but can't or doesn't
want to upgrade the module installed on his machine. Follow these steps to
success:

1. Go to CPAN and look for the latest ExtUtils::MakeMaker available.
     <http://search.cpan.org/search?query=ExtUtils::MakeMaker>
   The standalone package (currently maintained by Michael G. Schwern)
   is needed.

2. Get the tarball and extract it in some temporary directory. For
   version 6.16:
   	cd /tmp
   	wget http://search.cpan.org/CPAN/authors/id/M/MS/MSCHWERN/ExtUtils-MakeMaker-6.16.tar.gz
   	tar xvfz ExtUtils-MakeMaker-6.16.tar.gz

3. You will now have a directory ExtUtils-MakeMaker-X.YY (where X.YY is the
   version). Inside is a subdirectory 'lib'. Add that one to the environment
   variable PERL5LIB, like this (when you use the Bash):
   	export PERL5LIB="/tmp/ExtUtils-MakeMaker-6.16/lib:$PERL5LIB"

4. Now build SpamAssassin. As long as the PERL5LIB variable is set, the
   updated ExtUtils::MakeMaker is used.  (SpamAssassin will use PERL5LIB
   during building, but the built scripts ignore it due to taint-mode
   security features.)


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>

[GETEUMM616] Get ExtUtils::MakeMaker 6.16 here:
  <http://search.cpan.org/author/MSCHWERN/ExtUtils-MakeMaker-6.16/>

[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>
