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. 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. 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: [GETEUMM616] Get ExtUtils::MakeMaker 6.16 here: [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):