]> git.proxmox.com Git - proxmox-spamassassin.git/blob - upstream/Makefile.PL
buildsys: track debug package
[proxmox-spamassassin.git] / upstream / Makefile.PL
1 #!/usr/bin/perl
2 require 5.6.1;
3
4 use strict;
5 use warnings;
6 use Config;
7
8 use ExtUtils::MakeMaker;
9
10 # avoid stupid 'Argument "6.30_01" isn't numeric in numeric ge (>=)' warnings;
11 my $mm_version = eval $ExtUtils::MakeMaker::VERSION;
12
13 # raising the version of makemaker to 6.46 per bug 6598 & 6131
14 if ($mm_version < 6.46) {
15 die "Apache SpamAssassin Makefile.PL requires at least ExtUtils::MakeMaker v6.46";
16 }
17
18 use constant RUNNING_ON_WINDOWS => ($^O =~ /^(mswin|dos|os2)/oi);
19 use constant HAS_DBI => eval { require DBI; };
20
21 my @ATT_KEYS = (
22 # PLEASE READ THE FILE 'PACKAGING' FOR INFORMATION ON THESE VARIABLES.
23 #
24 # (Current) EU::MMs make a difference between these three possible general
25 # install destinations. One can set INSTALLDIRS to 'perl', 'site' or
26 # 'vendor' to choose one explicitly (the default is 'site'). They have the
27 # following meaning:
28 # * PERL: Only essential modules shipped with Perl should be installed
29 # there. Don't put Apache SpamAssassin there.
30 # * SITE: The default. Normal installations via CPAN or from the sources
31 # should use these dirs.
32 # * VENDOR: A special set of paths for packaged (RPM, deb, portage, ...)
33 # Perl modules. Not always (correctly) used but the intention
34 # is to keep the system from overwriting the modules installed
35 # by the user.
36 #
37 # See also
38 # <http://search.cpan.org/author/MSCHWERN/ExtUtils-MakeMaker-6.16/lib/ExtUtils/MakeMaker.pm#Default_Makefile_Behaviour>
39 # <http://www.debian.org/doc/packaging-manuals/perl-policy/ch-module_packages.html#s-vendor_dirs>
40 # <http://archive.develooper.com/perl5-porters@perl.org/msg94113.html>
41 # <https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=78053>
42 # <http://www.mail-archive.com/makemaker@perl.org/msg00779.html>
43 #
44 # The options SYSCONFDIR, DATADIR and CONFDIR all support those three
45 # possibilities. The '*' in the following comments refers to those.
46
47 'SYSCONFDIR', # Overwrite all $*SYSCONFDIRs; normally determined
48 'PERLSYSCONFDIR', # based on $*PREFIX.
49 'SITESYSCONFDIR', #
50 'VENDORSYSCONFDIR', #
51
52 'DATADIR', # Overwrite all INSTALL*DATAs; normally determined
53 'INSTALLDATA', # based on $*PREFIX.
54 'INSTALLSITEDATA', #
55 'INSTALLVENDORDATA',#
56
57 'CONFDIR', # Overwrite all INSTALL*CONFs; normally determined
58 'INSTALLCONF', # based on $*SYSCONFDIR.
59 'INSTALLSITECONF', #
60 'INSTALLVENDORCONF',#
61
62 'DEFRULESDIR', # A synonym for 'DATADIR'.
63 'LOCALRULESDIR', # " " " 'CONFDIR'.
64
65 'LOCALSTATEDIR', # normally determined based on $*PREFIX.
66 'PERLLOCALSTATEDIR',
67 'SITELOCALSTATEDIR',
68 'VENDORLOCALSTATEDIR',
69
70 'RE2C_BIN', # hard code the path for re2c if possible
71
72 'PERL_BIN', # Sets the Perl interpreter used by the scripts.
73 'PERL_WARN', # Can be used to disable warnings in the scripts
74 'PERL_TAINT', # " " " " " taint mode for the scripts (DON'T)
75
76
77 'BUILD_SPAMC' , # Set to 'no' to skip build of spamc on Windows.
78 'BUILD_SPAMD', # Set to 'no' to skip build of spamd on Windows.
79 'ENABLE_SSL', # Set to 'yes' to build spamc with SSL support.
80 'CONTACT_ADDRESS', # To not ask for the contact address, use this.
81 );
82
83
84 sub parse_arg {
85 my($val, $name) = (@_);
86 if ($val =~ /^($name)=["']?(.*?)["']?$/) {
87 return $2;
88 } else {
89 return undef;
90 }
91 }
92
93 sub bool {
94 my($val, $def) = (@_, undef, undef);
95 $def = 0 unless defined $def;
96 return bool($def) unless defined $val;
97
98 $val =~ s/^\s+|\s+$//g;
99 return 0 if $val =~ /^(0|N(o)?|Off)$/i;
100 return 1 if $val =~ /^(1|Y(es)?|On)$/i;
101 return bool($def);
102 }
103 sub yesno {
104 my($val, $def) = (@_, undef, undef);
105 return 'yes' if bool($val, $def);
106 return 'no';
107 }
108
109
110 my %opt = (
111 'build_spamc' => undef,
112 'build_spamd' => undef,
113 'enable_ssl' => undef,
114 'contact_address' => undef,
115 'destdir' => undef,
116 're2c_bin' => 're2c',
117 );
118 ARGV: foreach (@ARGV) {
119 foreach my $key (keys %opt) {
120 my $val = parse_arg($_, uc($key));
121 if (defined $val) {
122 $opt{$key} = $val;
123 next ARGV;
124 }
125 }
126 }
127
128
129 # See lib/ExtUtils/MakeMaker.pm for details of how to influence
130 # the contents of the Makefile that is written.
131 my %makefile = (
132 'NAME' => 'Mail::SpamAssassin',
133 'VERSION_FROM' => 'lib/Mail/SpamAssassin.pm', # finds $VERSION
134
135 # This is not the standard EU::MM array, we use a hash instead (which
136 # will be converted later on). Use the source file name as the key and
137 # the executable as the value.
138 'EXE_FILES' => {
139 'spamassassin.raw' => 'spamassassin',
140 'sa-learn.raw' => 'sa-learn',
141 'sa-update.raw' => 'sa-update',
142 'sa-compile.raw' => 'sa-compile',
143 'sa-awl.raw' => 'sa-awl',
144 'sa-check_spamd.raw' => 'sa-check_spamd',
145 'spamc/spamc.c' => 'spamc/spamc$(EXE_EXT)',
146 'spamd/spamd.raw' => 'spamd/spamd',
147 },
148
149 # TODO: the rule compilation is hooked into the build step for "sa-update"
150 # as the make target "build_rules".
151 # This is kludgy, and it'd be nice to find a cleaner way to do this.
152
153 'MAN1PODS' => {
154 'spamassassin' => '$(INST_MAN1DIR)/spamassassin.$(MAN1EXT)',
155 'lib/spamassassin-run.pod' => '$(INST_MAN1DIR)/spamassassin-run.$(MAN1EXT)',
156 'sa-learn' => '$(INST_MAN1DIR)/sa-learn.$(MAN1EXT)',
157 'sa-update' => '$(INST_MAN1DIR)/sa-update.$(MAN1EXT)',
158 'sa-compile' => '$(INST_MAN1DIR)/sa-compile.$(MAN1EXT)',
159 'sa-awl' => '$(INST_MAN1DIR)/sa-awl.$(MAN1EXT)',
160 'sa-check_spamd' => '$(INST_MAN1DIR)/sa-check_spamd.$(MAN1EXT)',
161 'spamc/spamc.pod' => '$(INST_MAN1DIR)/spamc.$(MAN1EXT)',
162 'spamd/spamd' => '$(INST_MAN1DIR)/spamd.$(MAN1EXT)',
163 },
164
165 'PL_FILES' => { },
166
167 'PMLIBDIRS' => [ 'lib' ],
168
169 'PM_FILTER' => '$(PREPROCESS) -Mconditional -Mvars -DVERSION="$(VERSION)" \
170 -DPREFIX="$(I_PREFIX)" \
171 -DDEF_RULES_DIR="$(I_DATADIR)" \
172 -DLOCAL_RULES_DIR="$(I_CONFDIR)" \
173 -DLOCAL_STATE_DIR="$(I_LOCALSTATEDIR)"',
174
175 'macro' => {
176 DATAFILES => 'user_prefs.template languages sa-update-pubkey.txt'
177 },
178
179 # be quite explicit about this; afaik CPAN.pm is sensible using this
180 # also see CURRENT_PM below
181 'PREREQ_PM' => {
182 'Digest::SHA1' => 0, # 2.0 is oldest tested version
183 'File::Spec' => 0.8, # older versions lack some routines we need
184 'File::Copy' => 2.02, # this version is shipped with 5.005_03, the oldest version known to work
185 'Pod::Usage' => 1.10, # all versions prior to this do seem to be buggy
186 'HTML::Parser' => 3.43, # the HTML code is based on this parser, older versions have utf-8 bugs
187 'Archive::Tar' => 1.23, # for sa-update
188 'IO::Zlib' => 1.04, # for sa-update
189 'Mail::DKIM' => 0.31,
190 'Net::DNS' => (RUNNING_ON_WINDOWS ? 0.46 : 0.34), # bugs in older revs
191 'NetAddr::IP' => 4.010,
192 'Sys::Hostname' => 0,
193 'Test::More' => 0,
194 'Time::HiRes' => 0,
195 'Time::Local' => 0,
196 'Errno' => 0,
197 },
198
199 'dist' => {
200 COMPRESS => 'gzip -9f',
201 SUFFIX => 'gz',
202 DIST_DEFAULT => 'tardist',
203
204 CI => 'svn commit',
205 RCS_LABEL => 'true',
206 },
207
208 'clean' => { FILES => join(' ' =>
209 'sa-learn', 'sa-update', 'spamassassin', 'sa-compile', 'sa-awl', 'sa-check_spamd',
210
211 'spamd/spamd',
212
213 'spamc/spamc$(EXE_EXT)',
214 'spamc/spamc.h',
215 'spamc/qmail-spamc$(EXE_EXT)',
216 'spamc/*.o*', 'spamc/replace/*.o*',
217 'spamc/*.so',
218 'spamc/Makefile',
219 'spamc/config.h', 'spamc/version.h', 'spamc/spamc.h',
220 'spamc/config.status', 'spamc/*.cache', 'spamc/config.log',
221 'spamd/*spamc*', 'qmail',
222
223 'doc', 'pod2htm*', '*.cache',
224
225 'version.env',
226
227 't/bayessql.cf', 't/do_net', 't/log', 't/sql_based_whitelist.cf',
228
229 'rules/*.pm',
230
231 # don't remove these. they are built from 'rulesrc' in SVN, but
232 # in a distribution tarball, they're not
233 # 'rules/70_sandbox.cf',
234 # 'rules/72_active.cf',
235
236 # this file is no longer built, or used
237 'rules/70_inactive.cf',
238
239 )
240
241 },
242
243 'AUTHOR' => 'The Apache SpamAssassin Project <dev at spamassassin.apache.org>',
244 'ABSTRACT' => 'Apache SpamAssassin is an extensible email filter which is used to identify spam',
245
246 # We have only this Makefile.PL and this option keeps MakeMaker from
247 # asking all questions twice after a 'make dist*'.
248 'NORECURS' => 1,
249 );
250
251 # rules/72_active.cf is built from "rulesrc", but *must* exist before
252 # WriteMakefile() is called due to shortcomings in MakeMaker.
253 my @FILES_THAT_MUST_EXIST = qw(
254 rules/72_active.cf
255 );
256
257 # make sure certain optional modules are up-to-date if they are installed
258 # also see PREREQ_PM above
259 my %CURRENT_PM = (
260 'Net::DNS' => (RUNNING_ON_WINDOWS ? 0.46 : 0.34),
261 'Razor2::Client::Agent' => 2.40,
262 );
263
264
265 # All the $(*MAN1*) stuff is empty/zero if Perl was Configured with -Dman1dir=none;
266 # however, support site/vendor man1 dirs (bug 5338)
267 unless($Config{installman1dir}
268 || $Config{installsiteman1dir}
269 || $Config{installvendorman1dir})
270 {
271 warn "not installing man pages in man1; no man1 dir found";
272 delete $makefile{MAN1PODS};
273 }
274
275
276 # Windows platforms need some adjustments
277 if (RUNNING_ON_WINDOWS) {
278 # Building spamd is optional on Windows because it still is somewhat
279 # experimental.
280 if (!defined $opt{'build_spamd'}) {
281 $opt{'build_spamd'} = bool(prompt(
282 "Build spamd.exe (experimental on windows platforms)? (y/n)",
283 'n'));
284 } else {
285 $opt{'build_spamd'} = bool($opt{'build_spamd'});
286 }
287 if (!$opt{'build_spamd'}) {
288 delete $makefile{EXE_FILES}{'spamd/spamd.raw'};
289 delete $makefile{MAN1PODS}{'spamd/spamd'};
290 }
291 # building spamc is optional under Win32 because not everyone has compiler
292 if (!defined $opt{'build_spamc'}) {
293 $opt{'build_spamc'} = bool(prompt(
294 "Build spamc.exe (environment must be set up for C compiler)? (y/n)",
295 'n'));
296 } else {
297 $opt{'build_spamc'} = bool($opt{'build_spamc'});
298 }
299 if (!$opt{'build_spamc'}) {
300 delete $makefile{EXE_FILES}{'spamc/spamc.c'};
301 delete $makefile{MAN1PODS}{'spamc/spamc.pod'};
302 }
303 }
304
305
306 $makefile{'macro'}{'ENABLE_SSL'} = yesno($opt{'enable_ssl'});
307
308 if (!defined $opt{'contact_address'}) {
309 $opt{'contact_address'} = prompt(
310 "What email address or URL should be used in the suspected-spam report\n".
311 "text for users who want more information on your filter installation?\n".
312 "(In particular, ISPs should change this to a local Postmaster contact)\n".
313 "default text:", "the administrator of that system"
314 );
315 print "\n";
316 }
317 $makefile{'macro'}{'CONTACT_ADDRESS'} = $opt{'contact_address'};
318
319 print
320 'NOTE: settings for "make test" are now controlled using "t/config.dist".
321 See that file if you wish to customize what tests are run, and how.
322
323 ';
324
325 # check optional module versions
326 use lib 'lib';
327 use Mail::SpamAssassin::Util::DependencyInfo;
328 if (Mail::SpamAssassin::Util::DependencyInfo::long_diagnostics() != 0) {
329 # missing required module? die!
330 # bug 5908: http://cpantest.grango.org/wiki/CPANAuthorNotes says
331 # we should exit with a status of 0, but without creating Makefile
332 exit 0;
333 }
334
335 foreach my $file (@FILES_THAT_MUST_EXIST) {
336 open (TOUCH, ">>$file") or die "cannot touch '$file'";
337 close TOUCH;
338 }
339
340 #######################################################################
341
342 # See Bug 6131 & 6598 for changes to META_MERGE and increased requirement
343 # for MakeMaker version
344 #
345 $makefile{META_MERGE} = {
346
347 'meta-spec' => {
348 version => '2',
349 url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec',
350 },
351
352 license => 'apache_2_0',
353
354 resources => {
355 license => 'http://www.apache.org/licenses/LICENSE-2.0.html',
356 homepage => 'https://spamassassin.apache.org/',
357 bugtracker => 'https://issues.apache.org/SpamAssassin/',
358 repository => {
359 url=>'http://svn.apache.org/repos/asf/spamassassin/',
360 type=>'svn'
361 },
362 MailingList => 'http://wiki.apache.org/spamassassin/MailingLists',
363 },
364
365 recommends => {
366 'MIME::Base64' => 0,
367 'DB_File' => 0,
368 'Net::SMTP' => 0,
369 'Mail::SPF' => 0,
370 'Geo::IP' => 0,
371 'Razor2::Client::Agent' => 2.61,
372 'Net::Ident' => 0,
373 'IO::Socket::INET6' => 0,
374 'IO::Socket::SSL' => 1.76,
375 'Compress::Zlib' => 0,
376 'Mail::DKIM' => 0.37,
377 'DBI' => 0,
378 'Getopt::Long' => 2.32,
379 'LWP::UserAgent' => 0,
380 'HTTP::Date' => 0,
381 'Archive::Tar' => 1.23,
382 'IO::Zlib' => 1.04,
383 'Encode::Detect' => 0
384 }
385 };
386
387 #######################################################################
388
389 # Now finish the meta hash and dump the Makefile
390 $makefile{EXE_FILES} = [ values %{$makefile{EXE_FILES}} ];
391 $makefile{AUTHOR} =~ s/(<.+) at (.+>)/$1\@$2/;
392 WriteMakefile(%makefile);
393 print "Makefile written by ExtUtils::MakeMaker $mm_version\n";
394
395 #######################################################################
396
397 package MY;
398
399 our ($MY_GLOBALS_ARE_SANE,
400 $RUNNING_ON_WINDOWS,
401 @REPOSITORIES,
402 $MACRO_RE,
403 $EQ_RE,
404 $EQ,
405 $SELF);
406
407 # For some reason initializing the vars on the global scope doesn't work;
408 # guess its some weird Perl behaviour in combination with bless().
409 sub init_MY_globals {
410 my $self = shift;
411
412 # Keep a reference to ourselves so we don't have to feed it to the helper
413 # scripts.
414 $SELF = $self;
415
416 return if $MY_GLOBALS_ARE_SANE;
417 $MY_GLOBALS_ARE_SANE = 1;
418
419 # (Current) EU::MMs make a difference between these three possible general
420 # install destinations. See also
421 # <http://archive.develooper.com/perl5-porters@perl.org/msg94113.html>
422 # <https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=78053>
423 # <http://www.mail-archive.com/makemaker@perl.org/msg00779.html>
424 # <http://www.debian.org/doc/packaging-manuals/perl-policy/ch-module_packages.html#s-vendor_dirs>
425 @REPOSITORIES = qw(
426 PERL
427 SITE
428 VENDOR
429 );
430
431 # Macro names follow this RE -- at least stricly enough for our purposes.
432 $MACRO_RE = qr/[A-Z0-9_]+/;
433 # Normally macros are assigned via FOO = bar. But the part with the equal
434 # sign might differ from platform to platform. So we use this RE:
435 $EQ_RE = qr/\s*:?=\s*/;
436 # To assign or own macros we'll follow the first assignment string we find;
437 # normally " = ".
438 $EQ = undef;
439
440 # Inherit our Windows-Flag.
441 $RUNNING_ON_WINDOWS = ::RUNNING_ON_WINDOWS;
442 }
443
444 # Unset $SELF to avoid any leaking memory.
445 sub clean_MY_globals {
446 my $self = shift;
447
448 $SELF = undef;
449 }
450
451 sub set_EQ_from_line {
452 my($line) = (@_);
453
454 return if defined($EQ);
455
456 $line =~ /\S(${EQ_RE})/;
457 $EQ = $1;
458 }
459
460
461 # Converts a version represented as a float to a real three-part version,
462 # eg.:
463 # 5.006001 -> 5.6.1
464 # 5.005_03 -> 5.5.30
465 #
466 # The first parameter should be a version, in what format ever.
467 sub float_to_version {
468 my($ver) = (@_);
469
470 if ($ver =~ /^\d\.\d+$/) {
471 $ver = sprintf("%1.6f", $ver);
472 $ver =~ s/[.0]+([1-9]+)/.$1/g;
473 }
474
475 return $ver;
476 }
477
478
479 # Generates a Makefile-reference to another macro; something like $(FOO).
480 #
481 # The first and only parameter should be the name of the referred macro,
482 # eg. 'FOO' (will return '$(FOO)').
483 sub macro_ref {
484 my($name) = (@_);
485
486 return sprintf('$(%s)', $name);
487 }
488
489 # Generates a line which defines a Makefile macro. Something like FOO = bar.
490 # The line is *not* followed by a newline!
491 #
492 # The first parameter must be the name of the macro. The second is optional.
493 # If it is omitted, the value set in the current EU::MM instance is used.
494 sub macro_def {
495 my($name, $val) = (@_, undef);
496 my $MUST_NOT_HAPPEN = "THIS MUST NOT HAPPEN. PLEASE REPORT A BUG VIA <https://issues.apache.org/SpamAssassin/>";
497 die $MUST_NOT_HAPPEN unless defined $name;
498 die $MUST_NOT_HAPPEN unless defined $EQ;
499 $val = $SELF->{$name} unless defined $val;
500
501 return $name . $EQ . $val;
502 }
503
504 # Returns true if the given line defines a macro.
505 #
506 # The first parameter must be the line to inspect. With the second optional
507 # parameter the name of a specific macro might be given. If its omitted, any
508 # macro matching the MACRO_RE pattern will fit.
509 sub line_has_macro_def {
510 my($line, $name) = (@_, undef);
511 $name = $MACRO_RE unless defined $name;
512
513 return $line =~ /^($name)${EQ_RE}/;
514 }
515
516 # Reads the name of the macro defined on the given line.
517 #
518 # The first parameter must be the line to be expected. If the line doesn't
519 # contain a macro definition, weird things may happen. So check with
520 # line_has_macro_def() before!
521 sub get_macro_name_from_line {
522 my($line) = (@_);
523
524 $line =~ /^(${MACRO_RE})${EQ_RE}/;
525 return $1;
526 }
527
528 # Reads the value of the given macro from the current instance of EU::MM.
529 #
530 # The first parameter must be the name of a macro.
531 sub get_macro {
532 my($name) = (@_);
533
534 return $SELF->{$name};
535 }
536
537 # Reads the value of the given macro from the current instance of EU::MM and
538 # expands all contained macros. So reading BAZ with these declarations
539 # FOO = blah
540 # BAR = $(FOO)
541 # BAZ = $(BAR)
542 # gives 'blah'.
543 #
544 # The first parameter must be the name of a macro.
545 sub get_expanded_macro {
546 my($name) = (@_);
547
548 my($val);
549 $val = get_macro($name);
550 # Now expand all macros...
551 while ($val =~ s/\Q$(\E(${MACRO_RE})\Q)\E/$SELF->{$1} || ''/ge) {};
552
553 return $val;
554 }
555
556 # Sets the value of the macro with the given name to the given value in the
557 # current instance of EU::MM. Just sets, doesn't write to the Makefile!
558 #
559 # The first parameter must be the macro's name, the second the value.
560 sub set_macro {
561 my($name, $val) = (@_);
562
563 $SELF->{$name} = $val;
564 }
565
566
567 # Returns the actual "repository" name used in macro names; the point is that
568 # EU::MM leaves out the name if the repository is 'PERL'. But only for macros
569 # which don't start with the repository name (like the INSTALL* ones). So the
570 # following mapping should be made:
571 # PERLPREFIX -> PERLPREFIX
572 # PERLSYSCONFDIR -> PERLSYSCONFDIR
573 # INSTALLSITECONF -> INSTALLSITECONF
574 # INSTALLPERLCONF -> INSTALLCONF
575 # Actually, its a bit more complex than that but we follow that simple mapping
576 # for our vars; one also has to know when to call this function and when not.
577 # If the second parameter is set, always the PERL variant is used.
578 sub repository {
579 my($repository, $default) = (@_);
580
581 return '' if $default;
582 return '' if $repository eq 'PERL';
583 return $repository;
584 }
585
586
587 # This routine determines the correct SYSCONFDIR to use for the given
588 # repository.
589 #
590 # The first parameter must be one value from @REPOSITORIES.
591 #
592 # *SYSCONFDIR can be overwritten with:
593 # *SYSCONFDIR
594 # SYSCONFDIR
595 # If none of those is specified, it will chose an FHS-compliant dir
596 # based on the corresponding *PREFIX:
597 # *PREFIX *SYSCONFDIR
598 # /usr /etc
599 # /usr/local /etc
600 # /opt/* /etc/opt
601 # /foo/* /foo/*/etc
602 sub _set_macro_SYSCONFDIR {
603 my($repository) = (@_);
604
605 my($macro);
606 $macro = $repository . "SYSCONFDIR";
607
608 # Is this macro already set?
609 return if get_macro($macro);
610
611 # Is this macro supposed to be overwritten?
612 if (get_macro('SYSCONFDIR')) {
613 set_macro($macro, macro_ref('SYSCONFDIR'));
614 return;
615 }
616
617 my($rprefix);
618 $rprefix = get_expanded_macro("${repository}PREFIX");
619
620 # Set the default, depending on the corresponding full PREFIX
621 set_macro($macro,
622 ($rprefix =~ m{^$}) ? '' :
623 ($rprefix =~ m{^/usr(/local)?/?$}) ? '/etc' :
624 ($rprefix =~ m{^/opt(/|$)}) ? '/etc/opt' :
625 macro_ref("${repository}PREFIX") . '/etc'
626 );
627 }
628
629 # This routine determines the correct LOCALSTATEDIR to use for the given
630 # repository.
631 #
632 # The first parameter must be one value from @REPOSITORIES.
633 #
634 # *LOCALSTATEDIR can be overwritten with:
635 # *LOCALSTATEDIR
636 # LOCALSTATEDIR
637 # If none of those is specified, it will chose an FHS-compliant dir
638 # based on the corresponding *PREFIX:
639 # *PREFIX *LOCALSTATEDIR
640 # /usr /etc
641 # /usr/local /etc
642 # /opt/* /etc/opt
643 # /foo/* /foo/*/etc
644 sub _set_macro_LOCALSTATEDIR {
645 my($repository) = (@_);
646
647 my($macro);
648 $macro = $repository . "LOCALSTATEDIR";
649
650 # Is this macro already set?
651 return if get_macro($macro);
652
653 # Is this macro supposed to be overwritten?
654 if (get_macro('LOCALSTATEDIR')) {
655 set_macro($macro, macro_ref('LOCALSTATEDIR'));
656 return;
657 }
658
659 my($rprefix);
660 $rprefix = get_expanded_macro("${repository}PREFIX");
661
662 # Set the default, depending on the corresponding full PREFIX
663 set_macro($macro,
664 ($rprefix =~ m{^$}) ? '' :
665 ($rprefix =~ m{^/usr(/local)?/?$}) ? '/var/lib/spamassassin' :
666 ($rprefix =~ m{^/opt(/|$)}) ? '/var/opt/spamassassin' :
667 macro_ref("${repository}PREFIX") . '/var/spamassassin'
668 );
669 }
670
671 # This routine determines the correct INSTALLDATADIR (aka DEFRULESDIR)
672 # to use for the given repository.
673 #
674 # The first parameter must be one value from @REPOSITORIES.
675 #
676 # INSTALL*DATADIR can be overwritten with:
677 # INSTALL*DATADIR
678 # DATADIR
679 # DEFRULESDIR
680 # If none of those is specified, it will chose an FHS-compliant dir,
681 # namely *PREFIX/share/spamassassin.
682 sub _set_macro_DATADIR {
683 my($repository) = (@_);
684
685 my($macro);
686 $macro = "INSTALL" . repository($repository) . "DATA";
687
688 # Is this macro already set?
689 return if get_macro($macro);
690
691 # Is this macro supposed to be overwritten?
692 foreach my $omacro (qw(DATADIR DEFRULESDIR)) {
693 if (get_macro($omacro)) {
694 set_macro($macro, get_macro($omacro));
695 return;
696 }
697 }
698
699 # Set the default value based on the corresponding PREFIX
700 set_macro($macro,
701 macro_ref("${repository}PREFIX") . '/share/spamassassin'
702 );
703 }
704
705 # This routine determines the correct INSTALLCONFDIR (aka LOCALRULESDIR)
706 # to use for the given repository.
707 #
708 # The first parameter must be one value from @REPOSITORIES.
709 #
710 # INSTALL*CONFDIR can be overwritten with:
711 # INSTALL*CONFDIR
712 # CONFDIR
713 # LOCALRULESDIR
714 # If none of those is specified, it will chose an FHS-compliant dir,
715 # namely *SYSCONFDIR/mail/spamassassin.
716 sub _set_macro_CONFDIR {
717 my($repository) = (@_);
718
719 my($macro);
720 $macro = "INSTALL" . repository($repository) . "CONF";
721
722 # Is this macro already set?
723 return if get_macro($macro);
724
725 # Is this macro supposed to be overwritten?
726 foreach my $omacro (qw(CONFDIR LOCALRULESDIR)) {
727 if (get_macro($omacro)) {
728 set_macro($macro, get_macro($omacro));
729 return;
730 }
731 }
732
733 # Set the default value based on the corresponding SYSCONFDIR
734 set_macro($macro,
735 macro_ref("${repository}SYSCONFDIR") . '/mail/spamassassin'
736 );
737 }
738
739 # This routine determines the correct value for PERL_BIN.
740 #
741 # There are no parameters.
742 #
743 # If PERL_BIN wasn't set at the command line, it will fall back to
744 # $(FULLPERL) which should refer to the current Perl interpreter.
745 sub _set_macro_PERL_BIN {
746
747 return if get_macro('PERL_BIN');
748 set_macro('PERL_BIN', macro_ref('FULLPERL'));
749 }
750
751 # This is a helper routine for PERL_WARN and PERL_TAINT.
752 #
753 # The first parameter must be either 'WARN' or 'TAINT'.
754 sub _set_macro_PERL_yesno {
755 my($macro) = (@_);
756
757 my($val);
758 $macro = 'PERL_' . $macro;
759 $val = "";
760 if (get_macro($macro)) {
761 $val = ::yesno(get_macro($macro));
762 }
763
764 set_macro($macro, $val);
765 }
766
767 # This routine sets the value for PERL_WARN.
768 #
769 # There are no parameters.
770 #
771 # If PERL_WARN wasn't set at the command line, PERL_WARN will be left
772 # empty (ie: the default is used). If it was set, the value is fed to
773 # yesno().
774 sub _set_macro_PERL_WARN {
775 _set_macro_PERL_yesno('WARN');
776 }
777
778 # This routine sets the value for PERL_TAINT.
779 #
780 # There are no parameters.
781 #
782 # If PERL_TAINT wasn't set at the command line, PERL_TAINT will be left
783 # empty (ie: the default is used). If it was set, the value is fed to
784 # yesno().
785 sub _set_macro_PERL_TAINT {
786 _set_macro_PERL_yesno('TAINT');
787 }
788
789 # This routine sets the value for PREPROCESS.
790 #
791 # There are no parameters.
792 #
793 # If PREPROCESS wasn't set at the command line, it chooses our default
794 # perl-called preprocessor.
795 sub _set_macro_PREPROCESS {
796
797 return if get_macro('PREPROCESS');
798 set_macro('PREPROCESS', join(' ', macro_ref('PERL_BIN'), qq{build/preprocessor}));
799 }
800
801 # This routine sets the value for CONFIGURE (spamc only).
802 #
803 # There are no parameters.
804 #
805 # If CONFIGURE wasn't set at the command line, it chooses our default
806 # perl-wrapped configure.
807 sub _set_macro_CONFIGURE {
808
809 return if get_macro('CONFIGURE');
810 set_macro('CONFIGURE', join(' ', macro_ref('PERL_BIN'), qq{spamc/configure.pl}));
811 }
812
813 # This routine sets the value for the SYMLINK command.
814 #
815 # There are no parameters.
816 #
817 # $(SYMLINK) calls Perl's symlink() function if available, else falls back
818 # to $(CP).
819 sub _set_macro_SYMLINK {
820
821 return if get_macro('SYMLINK');
822
823 if (eval { symlink("", "") or 1 }) {
824 my $code = q{symlink((splitpath($ARGV[0]))[2], $ARGV[1]) || die qq{$!\n}};
825 $code =~ s/(\$)/$1$1/g;
826 $code = qq{'$code'};
827 set_macro('SYMLINK', join(' ', macro_ref('PERL_BIN'), q{-MFile::Spec::Functions=splitpath}, q{-e}, $code));
828 }
829 else {
830 set_macro('SYMLINK', macro_ref('CP'));
831 }
832 }
833
834
835 # Override the libscan routine so it skips SVN/CVS stuff and some common
836 # patch/backup extensions.
837 sub MY::libscan {
838 my $self = shift;
839 my($path) = @_;
840 init_MY_globals($self);
841
842 return q{} if $path =~ m{
843 (^|/)(CVS|\.svn)(/|$)|
844 [/.](orig|old|rej|r\d+|diff|patch|bak|backup|mine|my|swp)$
845 }ix;
846
847 clean_MY_globals($self);
848 return $path; #/
849 }
850
851 # Override the install routine to add our additional install dirs and
852 # hack DESTDIR support into old EU::MMs.
853 sub MY::install {
854 my $self = shift;
855 my @code = split(/\n/, $self->SUPER::install(@_));
856 init_MY_globals($self);
857
858 foreach (@code) {
859 # Add our install targets as a dependency to all top-level install targets
860 s/^(install(?:_[a-z]+)?\s*::?\s*.*)$/$1 conf__install data__install/;
861 }
862
863 clean_MY_globals($self);
864 return join("\n", @code);
865 }
866
867
868 # Now override the constants routine to add our own macros.
869 sub MY::constants {
870 my $self = shift;
871 my @code = split(/\n/, $self->SUPER::constants(@_));
872 init_MY_globals($self);
873
874 foreach my $line (@code) {
875 # Skip comments
876 next if $line =~ /^\s*#/;
877 # Skip everything which isn't a var assignment.
878 next unless line_has_macro_def($line);
879
880 # Store the assignment string if necessary.
881 set_EQ_from_line($line);
882
883 # Store a nicer version string for later use.
884 if (line_has_macro_def($line, 'VERSION')) {
885 get_macro('VERSION') =~ /^(\d)\.(\d\d\d)_?(\d\d\d)/;
886 set_macro('VERSION_COOL', join(".", $1*1, $2*1, $3*1));
887 $line .= "\n" . macro_def('VERSION_COOL');
888 }
889
890 # Add some "dummy" (PERL|SITE|VENDOR)PREFIX macros for later use (only if
891 # necessary for old EU::MMs of course)
892 if (line_has_macro_def($line, 'PREFIX')) {
893 foreach my $r (@REPOSITORIES) {
894 my $rprefix = "${r}PREFIX";
895
896 if (!defined(get_macro($rprefix))) {
897 set_macro($rprefix, macro_ref('PREFIX'));
898 $line .= "\n" . macro_def($rprefix);
899 }
900 }
901 }
902 }
903 push(@code, qq{});
904
905 # Add some additional target dirs
906 {
907 set_macro('SYSCONFDIR', "") unless get_macro('SYSCONFDIR');
908 set_macro('LOCALSTATEDIR', "") unless get_macro('LOCALSTATEDIR');
909 set_macro('RE2C_BIN', $opt{'re2c_bin'});
910
911 # Determine the correct settings for each repository...
912 foreach my $r (@REPOSITORIES) {
913 _set_macro_SYSCONFDIR($r);
914 _set_macro_LOCALSTATEDIR($r);
915 _set_macro_DATADIR($r);
916 _set_macro_CONFDIR($r);
917 }
918
919 # ... and add it to the Makefile.
920 push(@code, qq{});
921 push(@code, qq{# Where to install config files});
922 push(@code, macro_def('SYSCONFDIR'));
923 foreach my $r (@REPOSITORIES) {
924 push(@code, macro_def($r . 'SYSCONFDIR'));
925 }
926
927 push(@code, qq{});
928 push(@code, qq{# Where to install local state files});
929 push(@code, macro_def('LOCALSTATEDIR'));
930 foreach my $r (@REPOSITORIES) {
931 push(@code, macro_def($r . 'LOCALSTATEDIR'));
932 }
933
934 foreach my $m (qw(DATA CONF)) {
935 foreach my $r (@REPOSITORIES) {
936 my $macro = 'INSTALL' . repository($r) . $m;
937 # The INSTALL* macros.
938 push(@code, macro_def($macro));
939 # The DESTINSTALL* macros.
940 push(@code, macro_def('DEST' . $macro, macro_ref('DESTDIR') . macro_ref($macro)));
941 }
942 }
943 }
944
945 # Set the PERL_* stuff
946 {
947 _set_macro_PERL_BIN;
948 _set_macro_PERL_WARN;
949 _set_macro_PERL_TAINT;
950
951 # Add it to the Makefile.
952 push(@code, qq{});
953 push(@code, qq{# Some details about our Perl});
954 foreach my $m (qw(BIN WARN TAINT)) {
955 push(@code, macro_def('PERL_' . $m));
956 }
957 }
958
959 # Set the preprocessor and configure scripts
960 {
961 _set_macro_PREPROCESS;
962 _set_macro_CONFIGURE;
963 _set_macro_SYMLINK;
964
965 # Add it to the Makefile.
966 push(@code, qq{});
967 push(@code, macro_def('PREPROCESS'));
968 push(@code, macro_def('CONFIGURE'));
969 push(@code, macro_def('SYMLINK'));
970 push(@code, macro_def('RE2C_BIN'));
971 }
972
973 # Set some additional helper/shortcut macros; the B_FOO are the ones which
974 # can be temporary locations if DESTDIR is used, I_FOO are the final
975 # destinations.
976 {
977 my($repository);
978 $repository = uc($SELF->{INSTALLDIRS}) || 'SITE';
979
980 # For these the install paths are needed only.
981 foreach my $macro (qw(PREFIX SYSCONFDIR LOCALSTATEDIR)) {
982 push(@code, macro_def('I_' . $macro,
983 macro_ref($repository . $macro)));
984 }
985 # For the following we need bot the B_- and the I_-variants. But the
986 # SCRIPT macro is the same for all repositories.
987 foreach my $macro (qw(SCRIPT DATA CONF LIB)) {
988 push(@code, macro_def('I_' . $macro . 'DIR',
989 macro_ref('INSTALL' . repository($repository, $macro eq 'SCRIPT') . $macro)));
990
991 push(@code, macro_def('B_' . $macro . 'DIR',
992 macro_ref('DESTINSTALL' . repository($repository, $macro eq 'SCRIPT') . $macro)));
993 }
994 }
995
996 clean_MY_globals($self);
997 return join("\n", @code);
998 }
999
1000 # Override some vars in the dist section.
1001 sub MY::dist {
1002 my $self = shift;
1003 my @code = split(/\n/, $self->SUPER::dist(@_));
1004 init_MY_globals($self);
1005
1006 foreach my $line (@code) {
1007 # Skip comments
1008 next if $line =~ /^\s*#/;
1009 # Skip everything which isn't a var assignment.
1010 next unless line_has_macro_def($line);
1011
1012 # Store the assignment string if necessary.
1013 set_EQ_from_line($line);
1014
1015 if (line_has_macro_def($line, 'DISTVNAME') && get_macro('VERSION_COOL')) {
1016 set_macro('DISTVNAME', '$(DISTNAME)-$(VERSION_COOL)');
1017 $line = macro_def('DISTVNAME');
1018 }
1019 }
1020
1021 clean_MY_globals($self);
1022 return join("\n", @code);
1023 }
1024
1025 sub MY::postamble {
1026 my $self = shift;
1027 my $code = "";
1028 init_MY_globals($self);
1029
1030 $code .= <<' EOD';
1031
1032 FIXVARS = -Mvars \
1033 -DVERSION="$(VERSION)" \
1034 -DPREFIX="$(I_PREFIX)" \
1035 -DDEF_RULES_DIR="$(I_DATADIR)" \
1036 -DLOCAL_RULES_DIR="$(I_CONFDIR)" \
1037 -DLOCAL_STATE_DIR="$(I_LOCALSTATEDIR)" \
1038 -DINSTALLSITELIB="$(I_LIBDIR)" \
1039 -DCONTACT_ADDRESS="$(CONTACT_ADDRESS)" \
1040 -DRE2C_BIN="$(RE2C_BIN)"
1041
1042 FIXBANG = -Msharpbang \
1043 -Mconditional \
1044 -DPERL_BIN="$(PERL_BIN)" \
1045 -DPERL_WARN="$(PERL_WARN)" \
1046 -DPERL_TAINT="$(PERL_TAINT)"
1047
1048 spamassassin: spamassassin.raw
1049 $(PREPROCESS) $(FIXBYTES) $(FIXVARS) $(FIXBANG) -m$(PERM_RWX) -i$? -o$@
1050
1051 sa-learn: sa-learn.raw
1052 $(PREPROCESS) $(FIXBYTES) $(FIXVARS) $(FIXBANG) -m$(PERM_RWX) -i$? -o$@
1053
1054 sa-update: sa-update.raw build_rules
1055 $(PREPROCESS) $(FIXBYTES) $(FIXVARS) $(FIXBANG) -m$(PERM_RWX) -isa-update.raw -osa-update
1056
1057 sa-compile: sa-compile.raw
1058 $(PREPROCESS) $(FIXBYTES) $(FIXVARS) $(FIXBANG) -m$(PERM_RWX) -isa-compile.raw -osa-compile
1059
1060 sa-awl: sa-awl.raw
1061 $(PREPROCESS) $(FIXBYTES) $(FIXVARS) $(FIXBANG) -m$(PERM_RWX) -isa-awl.raw -osa-awl
1062
1063 sa-check_spamd: sa-check_spamd.raw
1064 $(PREPROCESS) $(FIXBYTES) $(FIXVARS) $(FIXBANG) -m$(PERM_RWX) -isa-check_spamd.raw -osa-check_spamd
1065
1066 spamd/spamd: spamd/spamd.raw
1067 $(PREPROCESS) $(FIXBYTES) $(FIXVARS) $(FIXBANG) -m$(PERM_RWX) -i$? -o$@
1068
1069 build_rules:
1070 $(PERL) build/mkrules --exit_on_no_src --src rulesrc --out rules --manifest MANIFEST --manifestskip MANIFEST.SKIP
1071
1072 SPAMC_MAKEFILE = spamc/Makefile
1073 MAKE_SPAMC = $(MAKE) -f $(SPAMC_MAKEFILE)
1074 MAKE_SPAMC_OLD = $(MAKE) SOURCE=$< TARGET=$@ spamc_has_moved
1075
1076 SPAMC_SRC = spamc/spamc.c spamc/utils.c
1077 QSPAMC_SRC = spamc/qmail-spamc.c spamc/utils.c
1078 LIBSPAMC_SRC = spamc/libspamc.c spamc/utils.c
1079
1080 $(SPAMC_MAKEFILE): $(SPAMC_MAKEFILE).in $(SPAMC_MAKEFILE).win spamc/spamc.h.in
1081 $(CONFIGURE) --prefix="$(I_PREFIX)" --sysconfdir="$(I_CONFDIR)" --datadir="$(I_DATADIR)" --enable-ssl="$(ENABLE_SSL)"
1082
1083 spamc_has_moved:
1084 $(NOECHO) echo "***"
1085 $(NOECHO) echo "*** spamc now has its own directory: $(TARGET) is $(SOURCE)"
1086 $(NOECHO) echo "***"
1087 $(PERL) -MFile::Spec -MFile::Copy \
1088 -e "copy(q[$(SOURCE)], q[$(TARGET)]);"
1089
1090 spamc/libspamc.so: $(SPAMC_MAKEFILE) $(LIBSPAMC_SRC)
1091 $(MAKE_SPAMC) $@
1092
1093 spamd/libspamc.so: spamc/libspamc.so
1094 $(MAKE_SPAMC_OLD)
1095
1096 spamc/libsslspamc.so: $(SPAMC_MAKEFILE) $(LIBSPAMC_SRC)
1097 $(MAKE_SPAMC) $@
1098
1099 spamd/libsslspamc.so: spamc/libsslspamc.so
1100 $(MAKE_SPAMC_OLD)
1101
1102 spamc/spamc$(EXE_EXT): $(SPAMC_MAKEFILE) $(SPAMC_SRC) $(LIBSPAMC_SRC)
1103 $(MAKE_SPAMC) $@
1104
1105 spamd/spamc$(EXE_EXT): spamc/spamc$(EXE_EXT)
1106 $(MAKE_SPAMC_OLD)
1107 $(CHMOD) $(PERM_RWX) $@
1108
1109 spamc/qmail-spamc$(EXE_EXT): $(SPAMC_MAKEFILE) $(QSPAMC_SRC)
1110 $(MAKE_SPAMC) $@
1111
1112 qmail/qmail-spamc$(EXE_EXT): spamc/qmail-spamc$(EXE_EXT)
1113 $(MKPATH) qmail
1114 $(MAKE_SPAMC_OLD)
1115 $(CHMOD) $(PERM_RWX) $@
1116
1117 # needs to be added to MY::install if used
1118 #bin__install: $(INST_SCRIPT)/sa-filter
1119 # # $(RM_F) $(B_SCRIPTDIR)/spamassassin
1120 # # $(SYMLINK) $(INST_SCRIPT)/sa-filter $(B_SCRIPTDIR)/spamassassin
1121
1122 conf__install:
1123 -$(MKPATH) $(B_CONFDIR)
1124 $(PERL) -MFile::Copy -e "copy(q[rules/local.cf], q[$(B_CONFDIR)/local.cf]) unless -f q[$(B_CONFDIR)/local.cf]"
1125 $(PERL) -MFile::Copy -e "copy(q[rules/init.pre], q[$(B_CONFDIR)/init.pre]) unless -f q[$(B_CONFDIR)/init.pre]"
1126 $(PERL) -MFile::Copy -e "copy(q[rules/v310.pre], q[$(B_CONFDIR)/v310.pre]) unless -f q[$(B_CONFDIR)/v310.pre]"
1127 $(PERL) -MFile::Copy -e "copy(q[rules/v312.pre], q[$(B_CONFDIR)/v312.pre]) unless -f q[$(B_CONFDIR)/v312.pre]"
1128 $(PERL) -MFile::Copy -e "copy(q[rules/v320.pre], q[$(B_CONFDIR)/v320.pre]) unless -f q[$(B_CONFDIR)/v320.pre]"
1129 $(PERL) -MFile::Copy -e "copy(q[rules/v330.pre], q[$(B_CONFDIR)/v330.pre]) unless -f q[$(B_CONFDIR)/v330.pre]"
1130 $(PERL) -MFile::Copy -e "copy(q[rules/v340.pre], q[$(B_CONFDIR)/v340.pre]) unless -f q[$(B_CONFDIR)/v340.pre]"
1131 $(PERL) -MFile::Copy -e "copy(q[rules/v341.pre], q[$(B_CONFDIR)/v341.pre]) unless -f q[$(B_CONFDIR)/v341.pre]"
1132 $(PERL) -MFile::Copy -e "copy(q[rules/v342.pre], q[$(B_CONFDIR)/v342.pre]) unless -f q[$(B_CONFDIR)/v342.pre]"
1133 $(PERL) -MFile::Copy -e "copy(q[rules/v343.pre], q[$(B_CONFDIR)/v343.pre]) unless -f q[$(B_CONFDIR)/v343.pre]"
1134
1135 data__install:
1136 -$(MKPATH) $(B_DATADIR)
1137 $(PERL) -e "map unlink, <$(B_DATADIR)/*>"
1138 $(PREPROCESS) $(FIXVARS) -m$(PERM_RW) -Irules -O$(B_DATADIR) $(DATAFILES)
1139 $(CHMOD) $(PERM_RWX) $(B_DATADIR)
1140
1141 text_html_doc: made-doc-stamp
1142 $(NOOP)
1143
1144 doc:
1145 $(MKPATH) $@
1146
1147 made-doc-stamp: doc $(MAN1PODS) $(MAN3PODS) $(EXTRAPODS)
1148 $(PERL) build/convert_pods_to_doc $(MAN1PODS) $(MAN3PODS) $(EXTRAPODS)
1149 $(TOUCH) made-doc-stamp
1150 $(RM_F) pod2htm*
1151
1152
1153 version.env: lib/Mail/SpamAssassin.pm Makefile
1154 $(RM_F) $@
1155 $(PERL) -Ilib -MMail::SpamAssassin -e 'printf("FULL_VERSION=%s\n", Mail::SpamAssassin::Version())' >> $@
1156 $(PERL) -e 'print "DIST_VERSION=$(VERSION_COOL)\n"' >> $@
1157 $(PERL) -e 'print "CPAN_VERSION=$(VERSION)\n"' >> $@
1158
1159
1160 manifest_skip:
1161 sort -f < MANIFEST.SKIP > MANIFEST.SKIP.tmp
1162 mv MANIFEST.SKIP.tmp MANIFEST.SKIP
1163
1164 sysreport:
1165 $(NOECHO) $(PERL) tools/sysreport CC=$(CC) PERL=$(PERL) PERL_BIN=$(PERL_BIN)
1166
1167 EOD
1168
1169 clean_MY_globals($self);
1170 return $code;
1171 }