blob: 6e1e21040ca470f76401eb8d88d1217f7916ab93 [file] [log] [blame]
use 5.006;
use strict;
use warnings FATAL => 'all';
my $min_httpd_version = '2.0.35';
my($old_modperl_version, $old_modperl_pm);
BEGIN {
eval {
require mod_perl;
if ($mod_perl::VERSION < 1.99) {
$old_modperl_version = $mod_perl::VERSION;
}
$old_modperl_pm = delete $INC{'mod_perl.pm'};
%mod_perl:: = ();
};
}
use lib qw(lib Apache-Test/lib);
use Config;
use File::Spec::Functions;
use DirHandle ();
use File::Copy 'cp';
use File::Basename 'basename';
use Apache::Build ();
use Apache::TestReportPerl ();
use Apache::TestSmokePerl ();
use Apache::TestTrace;
use Apache::TestMM qw(test);
use ModPerl::TestRun ();
use ModPerl::Code ();
use ModPerl::MM ();
use constant WIN32 => Apache::Build::WIN32;
our $VERSION;
if (Apache::Build::REQUIRE_ITHREADS()) {
unless (Apache::Build::HAS_ITHREADS()) {
die "your system requires an ithreads enabled Perl";
}
}
perl_version_check();
my $build = Apache::Build->new(init => 1);
my $code = ModPerl::Code->new;
#XXX: dunno why but win32 fails because of this:
#cd docs/api/mod_perl-2.0 && nmake all ...
#NMAKE : fatal error U1073: don't know how to make 'all'
#Stop.
#NMAKE : fatal error U1077: 'cd' : return code '0x2'
#Stop.
my @remote_makefile_dirs = WIN32() ? () :
qw(docs/api/mod_perl-2.0);
configure();
local %ModPerl::MM::PM = (
'lib/typemap' => 'blib/lib/Apache2/typemap',
'lib/Apache2.pm' => 'blib/lib/Apache2.pm',
);
ModPerl::MM::WriteMakefile(
NAME => 'mod_perl',
VERSION => $VERSION,
DIR => get_dirs_with_makefile(@remote_makefile_dirs),
macro => {
MODPERL_SRC => $code->path,
MODPERL_MAKEFILE => basename($build->default_file('makefile')),
MAKE_F => '$(MAKE) ' . (WIN32 ? '/f' : '-f'),
MODPERL_LIBMAKE => '$(MAKE) -f $(MODPERL_MAKEFILE)',
PERL => $build->perl_config('perlpath'),
MOD_INSTALL => ModPerl::MM::mod_install(),
APACHE_PREFIX => $build->apxs('-q' => 'prefix'),
APACHE_LIBDIR => $build->apxs('-q' => 'libexecdir'),
},
clean => {
FILES => "@{ clean_files() }",
},
dist => {
DIST_DEFAULT => 'mydist',
COMPRESS=> 'gzip -9f', SUFFIX=>'gz',
},
);
post_configure();
sub configure {
set_modperl_version();
if ($old_modperl_version) {
$old_modperl_version =~ s/(\d\d)(\d\d)/$1_$2/;
my $vstring = "mod_perl/$old_modperl_version";
print "$vstring installation detected...";
if ($build->{MP_INST_APACHE2}) {
print "ok (installing relative to Apache2/)\n";
}
else {
print "not ok\n";
error "cannot install mod_perl/$VERSION on top of $vstring",
"use MP_INST_APACHE2=1 option " .
"or to force installation delete:\n $old_modperl_pm";
die "\n";
}
}
if (WIN32()) {
#Makefile.PL's in WrapXS/ just need to pass the -e mod_perl.lib test
#the real mod_perl.lib will be in place when WrapXS/ dll's are
#actually linked
my $lib = "src/modules/perl/$build->{MP_LIBNAME}.lib";
unless (-e $lib) {
open my $fh, '>', $lib or die "open $lib: $!";
print $fh "#this is a dummy file to trick MakeMaker";
close $fh;
}
}
system_sanity_check();
if ($build->{MP_APXS}) {
debug "Using APXS => $build->{MP_APXS}";
}
elsif ($build->{MP_AP_PREFIX}) {
if (my $reason = $build->ap_prefix_invalid) {
error "invalid MP_AP_PREFIX: $reason";
exit 1;
}
debug "Using Apache prefix => $build->{MP_AP_PREFIX}";
}
else {
for my $path ($build->find) {
$build->dir($path);
my $mmn = $build->module_magic_number;
my $v = $build->httpd_version;
next unless $v;
next if $v lt $min_httpd_version;
last if $build->prompt_y("Configure mod_perl with $path?");
}
}
my $httpd_version = $build->httpd_version;
unless ($httpd_version) {
error 'Unable to determine server version, aborting.';
if ($build->{MP_APXS} || $build->{MP_AP_PREFIX}) {
my $what = $build->{MP_APXS} ? 'MP_APXS' : 'MP_AP_PREFIX';
error "Invalid $what specified?";
}
else {
error 'Please specify MP_APXS or MP_AP_PREFIX.';
}
exit(1);
}
if ($httpd_version lt $min_httpd_version) {
error "Apache/$httpd_version not supported, " .
"$min_httpd_version or higher is required";
exit(1);
}
printf "Configuring Apache/%s mod_perl/%s Perl/v%vd\n",
$httpd_version, $VERSION, $^V;
my $apr_config = $build->get_apr_config; #cache it
for (@{ clean_files() }) {
debug "unlink...$_" if -e $_ && unlink;
}
#ModPerl::MM will use Apache::BuildConfig in subdir/Makefile.PL's
$build->save;
for my $util (qw(Report Smoke)) {
my $class = "Apache::Test${util}Perl";
$class->generate_script;
}
for my $util (qw(Run)) {
my $class = "ModPerl::Test${util}";
$class->generate_script;
}
my $tables_dir = tables_dir($httpd_version);
unshift @INC, $tables_dir;
if ($build->{MP_GENERATE_XS}) {
debug "generating XS code using $tables_dir...";
xs_generate($httpd_version);
}
install_typemap();
}
sub post_configure {
#now have any data subdir/Makefile.PL's save, e.g. XS
$build = Apache::Build->build_config;
$build->write_src_makefile;
$build->save_ldopts;
$code->generate($build);
for my $type (qw(DSO STATIC)) {
next unless $build->{"MP_USE_$type"};
warning "mod_perl \L$type\E library will be built as ".
$build->{"MODPERL_LIB_$type"};
}
if ($build->is_dynamic) {
warning "You'll need to add the following to httpd.conf:",
" LoadModule perl_module modules/$build->{MODPERL_LIB_DSO}\n";
}
if ($build->{MP_INST_APACHE2}) {
warning "Apache Perl modules will be installed relative to Apache2/";
warning "Don't forget to:",
"- configure 'PerlModule Apache2' in httpd.conf",
"- or 'use Apache2 ();' in a startup script";
}
$build->save;
}
sub tables_dir {
my $httpd_version = shift;
my $tables_version = 'current';
#XXX: support versioning
#$httpd_version =~ /-dev$/ ? 'current' : $httpd_version;
my $tables_dir = "xs/tables/$tables_version";
}
sub xs_generate {
require ModPerl::WrapXS;
my $xs = ModPerl::WrapXS->new;
$xs->generate;
#shift @INC; #ModPerl::Code needs this path too
}
sub install_typemap {
my $to_file = 'lib/typemap';
open my $to_fh, ">$to_file" or die "open $to_file: $!";
for my $from_file (qw(WrapXS/typemap xs/typemap)) {
open my $from_fh, $from_file or die "open $from_file: $!";
cp $from_fh, $to_fh;
close $from_fh;
}
close $to_fh or die "close $to_file: $!";
}
sub echo_cmd {
my $cmd = shift;
print "$cmd\n";
system($cmd) == 0 or exit(1);
}
sub clean_files {
my $path = $code->path;
return [@{ $build->clean_files },
qw(lib/typemap),
<xs/*.exp>, <xs/*.def>,
map { "$path/$_"} @{ $code->clean_files }];
}
sub set_modperl_version {
require './lib/mod_perl.pm';
$VERSION = $mod_perl::VERSION;
$VERSION =~ s/(\d\d)(\d\d)$/$1_$2/;
open my $fh, 'Changes';
while(<$fh>) {
if(/^=item.*-dev/) {
$VERSION .= '-dev';
last;
}
last if /^=item/;
}
close $fh;
}
sub perl_version_check {
if ($] < 5.006_001) {
error "You are running Perl version 5.6.0\n" .
"We strongly suggest you upgrade to at least 5.6.1";
}
if ($] >= 5.007 and $] < 5.008) {
error "5.7.x development versions of Perl are no longer supported\n" .
"Upgrade to 5.8.0 or higher";
exit 1;
}
}
sub system_sanity_check {
return if WIN32;
my $ccflags = $build->perl_config('ccflags');
for (split /\s+/, $ccflags) {
next unless s/^-I//;
my $header = "$_/ap_mmn.h";
if (-e $header) {
$build->phat_warn(<<EOF);
Apache headers found in unexpected location: ``$_'', suggestions:
*) Remove via ``rpm -e apache''
*) Remove by hand
*) Complain to your os vendor about their poor layout choice
*) Complain to your sysadmin about their poor layout choice
EOF
}
}
$build->lib_check('gdbm');
malloc_check();
os_check();
}
sub malloc_check {
return unless $build->is_dynamic;
return unless $build->perl_config('usemymalloc') eq 'y';
my $abort = $^O eq 'solaris';
my $bincompat = $build->perl_config('bincompat5005');
if ($bincompat) {
$build->phat_warn(<<EOF, $abort);
Your current configuration will most likely trigger core dumps, suggestions:
*) Do not configure mod_perl as a DSO
*) Rebuild Perl without malloc pollution (Configure -Ubincompat5005)
EOF
}
}
sub os_check {
my $check = \&{"os_check_$^O"};
return unless defined &$check;
$check->()
}
sub os_check_hpux {
my $ccflags = $build->perl_config('ccflags');
my $ld = $build->perl_config('ld');
if ($build->is_dynamic and $ld eq 'ld') {
unless ($ccflags =~ /\+z/i) {
$build->phat_warn(<<EOF);
mod_perl is unlikely to link with your libperl, suggestions:
*) Rebuild Perl with Configure -Accflags=+Z ...
EOF
}
}
}
# by default only Makefile.PL's in the first level sub-dirs are
# discovered. If you want to reach a Makefile.PL's in some remote
# directories, pass them to this function.
sub get_dirs_with_makefile {
my @remove_makefile_dirs = @_;
my %mf_dirs = ();
# since we cannot override MM::init_dirscan, but at the same time
# want to change $self->{DIR}, we have to reproduce
# MM::init_dirscan's section on setting DIR
for my $dir (@remote_makefile_dirs,
grep {-d} DirHandle->new(curdir())->read) {
next if curdir() eq $dir || updir() eq $dir;
next if -l $dir; # no symlinks per MakeMaker
$mf_dirs{$dir}++ if -f catfile($dir, "Makefile.PL");
}
return [sort keys %mf_dirs];
}
package MY;
use Config;
sub MY::top_targets {
my $self = shift;
my $string = $self->MM::top_targets;
ModPerl::MM::add_dep(\$string, pure_all => 'modperl_lib');
$string .= <<'EOF';
source_scan:
$(PERL) build/source_scan.pl
xs_generate:
$(PERL) build/xs_generate.pl
etags:
$(SHELL) build/make_etags
modperl_lib:
cd "$(MODPERL_SRC)" && $(MODPERL_LIBMAKE)
modperl_lib_install:
cd "$(MODPERL_SRC)" && $(MODPERL_LIBMAKE) install
modperl_src_clean:
cd "$(MODPERL_SRC)" && $(MODPERL_LIBMAKE) clean
EOF
$string;
}
sub MY::install {
my $self = shift;
my $string = $self->MM::install(@_);
ModPerl::MM::add_dep(\$string, pure_install => 'modperl_lib_install');
$string;
}
sub MY::clean {
my $self = shift;
my $string = $self->MM::clean(@_);
ModPerl::MM::add_dep(\$string, clean => 'modperl_src_clean');
ModPerl::MM::add_dep(\$string, clean => 'test_clean');
$string;
}
sub MY::postamble {
return <<'EOF';
mydist : manifest tardist
cvs_tag :
cvs tag MODPERL_$(VERSION_SYM) .
@echo update mod_perl.pm VERSION now
EOF
}
sub MY::tool_autosplit {
'';
}
sub MY::manifypods {
my $self = shift;
my $ver = $self->{VERSION} || "";
local $_ = $self->MM::manifypods(@_);
s/pod2man\s*$/pod2man --release mod_perl-$ver/m;
$_;
}
sub MY::pasthru {
my $self = shift;
chomp(my $str = $self->MM::pasthru);
join $/, "$str\\",
"\t".'PERL="$(PERL)"\\',
"\t".'DEFINE="$(DEFINE)"',
"";
}
sub MY::dist_basics {
my $self = shift;
my $str = $self->MM::dist_basics;
$str =~ s/(\"?)-MExtUtils(::Manifest=mkmanifest)/-Ilib $1-MModPerl$2/;
$str;
}