#!perl BEGIN { $Is_Win32 = ($^O eq "MSWin32"); $Is_Cygwin = ($^O =~ m/cygwin/g); if($Is_Win32) { require 5.004_02; require Win32; } elsif($Is_Cygwin) { require 5.005_03; } else { require 5.003_97; } } sub MMN_130 () { 19980527 } use ExtUtils::MakeMaker; use Config (); use FileHandle (); use DirHandle (); use File::Compare (); use File::Basename qw(dirname basename); use File::Path qw(mkpath rmtree); use Cwd; use File::Copy qw(cp); #use Apache::ExtUtils qw(%Config); unless (%Config) { *Config = \%Config::Config; } my %vcache = (); #SERVER_VERSION my %mcache = (); #MODULE_MAGIC_NUMBER #version 1.5 that ships with 5.003 is broken! *cp = sub { system "cp @_"; for (@_) { -e $_ or die $! } } if $File::Copy::VERSION < 2.0; my $Is_dougm = (defined($ENV{USER}) && ($ENV{USER} eq "dougm")); my $USE_THREADS; my $thrlib = join '|', qw(-lpthread); if ($] < 5.005_60) { $USE_THREADS = (defined($Config{usethreads}) && ($Config{usethreads} eq "define")); } else { $USE_THREADS = (defined($Config{use5005threads}) && ($Config{use5005threads} eq "define")); } #hmm, seems the #include flip/flop isn't needed anymore #so ignore the stuff above for now $USE_THREADS = $ENV{PERL_USE_THREADS} || 0; require "./lib/mod_perl.pm"; $VERSION = $mod_perl::VERSION = $mod_perl::VERSION; { $VERSION =~ s/(\d\d)(\d\d)$/$1_$2/; } { local *FH; open FH, "Changes"; while() { if(/^=item.*-dev/) { $VERSION .= "-dev"; last; } last if /^=item/; } close FH; } use subs qw(iedit asrc); if($] < 5.004_04) { print < "Ben-SSL", "apache_ssl.c" => "Ben-SSL", "mod_ssl.h" => "Stronghold", "modules/modssl" => "Stronghold", ); unless (-e "t/docs/test.shtml") { cp "t/docs/test.html", "t/docs/test.shtml"; } for (qw(.htaccess hooks.txt)) { my $file = "t/docs/$_"; local *FH; open FH, ">$file" or die "can't write test file: $file: $!"; chmod 0666, $file; close FH; } chmod 0644, "t/conf/mod_perl_srm.conf"; mkdir "t/logs", 0777; chmod 0777, "t/logs"; unless ($Is_Win32) { system "chmod a+x t/net/perl/* t/net/perl/io/*"; } #generated by us at one time or another my(@do_clean) = qw{ t/docs/.htaccess t/docs/hooks.txt src/Configuration lib/Apache/MyConfig.pm Apache/Apache.xs Constants/Constants.xs t/modules/ssi.t t/logs/error_log t/conf/srm.conf t/conf/dev-null t/logs/httpd.pid src/modules/perl/mod_perl_version.h t/net/perl/cgi.pl t/report t/TEST t/httpd apaci/find_source apaci/apxs_cflags apaci/mod_perl.config }; #t/conf/httpd.conf #t/net/config.pl for(@do_clean) { unlink $_ } unless ($Is_Win32) { rename "t/conf/httpd.conf", "t/conf/httpd.conf.old"; } rmtree "t/docs/stacked", 0, 0; gen_script("t/net/perl/cgi.pl"); gen_script("t/report"); gen_script("t/TEST"); gen_script("apaci/find_source"); gen_script("apaci/apxs_cflags"); gen_script("apaci/perl_config", "$PWD/lib"); gen_script("apaci/load_modules.pl"); write_version_h("src/modules/perl"); my(@test_pre_init) = qq( test_pre_init: ); # Automatic setup support my(@adirs, %seen, %mft_map, %vers_map, $src_dir, $vers, $conf, $ans); %vers_map = ( '1.1.1' => "Makefile.tmpl", '1.1.3' => "Makefile.tmpl", '1.2' => "Makefile.tmpl-1.2", '1.1.1Xcert-Sentry' => "Makefile.tmpl-XCert", '1.1.1Ben-SSL' => "Makefile.tmpl-Ben-SSL", '1.1.3Ben-SSL' => "Makefile.tmpl-Ben-SSL", '1.2Ben-SSL' => "", NONE => "", ); $LIBPERL = "DEFAULT"; $USE_APACI = $USE_DSO = $USE_APXS = 0; $WITH_APXS = ""; $APACI_ARGS = ""; @APACI_ARGS = (); $EVERYTHING = $EXPERIMENTAL = 0; $PERL_DEBUG = ""; $PERL_DESTRUCT_LEVEL = ""; $PERL_STATIC_EXTS = ""; $PERL_USELARGEFILES = 1; $PERL_EXTRA_CFLAGS = ""; $PERL_EXTRA_LIBS = ""; $SSLCacheServerPort = 8539; $SSL_BASE = ""; $Port = $ENV{HTTP_PORT} || 8529; #so Doug can 'make test' different-builds@sametime/samebox if(!$Is_Win32 and $ENV{RANDOM_PORT} and $$ > 8000 and $$ < 30000) { $PORT ||= $$; print "I'll use Port $PORT\n"; } $PORT ||= $Port; $TARGET = ""; $DO_HTTPD = $ENV{DO_HTTPD} || 0; $NO_HTTPD = $ENV{NO_HTTPD} || 0; $PREP_HTTPD = 0; $PERL_TRACE = 0; $ALL_HOOKS = 0; $APACHE_SRC = ""; $APACHE_PREFIX = ""; $APACHE_HEADER_INSTALL = 1; $PERL_SECTIONS = 0; $PERL_SSI = 0; $ADD_VERSION = 1; $STATIC = 1; $DYNAMIC = 0; $CONFIG = ""; $ADD_MODULE = ""; $PERL_DIRECTIVE_HANDLERS = 0; $PERL_TABLE_API = 0; $PERL_LOG_API = 0; $PERL_URI_API = 0; $PERL_UTIL_API = 0; $PERL_FILE_API = 0; $PERL_CONNECTION_API = 1; #these two were split out late in the game $PERL_SERVER_API = 1; #so they are on by default $PERL_RUN_XS = 0; $MOD_PERL_PREFIX; my %experimental = map { $_,1 } qw{ PERL_AUTOPRELOAD PERL_RUN_XS PERL_MARK_WHERE DO_INTERNAL_REDIRECT PERL_TIE_SCRIPTNAME PERL_STASH_POST_DATA XS_IMPORT PERL_SAFE_STARTUP PERL_DEFAULT_OPMASK PERL_ORALL_OPMASK }; my %PassEnv = map { $_,1 } qw(SSL_BASE); my @mp_args = (keys %PassEnv, qw(EXPERIMENTAL EVERYTHING DO_HTTPD NO_HTTPD CONFIG ADD_MODULE APACHE_PREFIX USE_APACI USE_DSO USE_APXS WITH_APXS APACI_ARGS PREP_HTTPD ALL_HOOKS ADD_VERSION STATIC DYNAMIC PORT XS_IMPORT)); sub is_mp_arg { my $arg = shift; return 1 if $experimental{$arg}; for (@mp_args) { return 1 if $arg eq $_; } return 0; } #callback hooks @callback_hooks = qw{ PERL_DISPATCH PERL_CHILD_INIT PERL_CHILD_EXIT PERL_POST_READ_REQUEST PERL_TRANS PERL_HEADER_PARSER PERL_ACCESS PERL_AUTHEN PERL_AUTHZ PERL_TYPE PERL_FIXUP PERL_HANDLER PERL_LOG PERL_INIT PERL_CLEANUP PERL_RESTART PERL_STACKED_HANDLERS PERL_METHOD_HANDLERS PERL_DIRECTIVE_HANDLERS PERL_TABLE_API PERL_LOG_API PERL_URI_API PERL_UTIL_API PERL_FILE_API PERL_CONNECTION_API PERL_SERVER_API }; $callback_alias{PERL_INIT} = "PERL_HEADER_PARSER"; $callback_alias{PERL_CLEANUP} = "PERL_LOG"; %callback_hooks = map { $_,0 } @callback_hooks; $callback_hooks{PERL_HANDLER} = 1; #PerlHandler always on %cant_hook = (); my @mm_args; { my($fh,$file); for (qw(./ ../ ./. ../.), "$ENV{HOME}/.") { last if $fh = FileHandle->new($file = $_."makepl_args.mod_perl"); } if($fh) { print "Reading Makefile.PL args from $file\n"; while(<$fh>) { chomp; s/^\s+//; s/\s+$//; next if /^#/ || /^$/; last if /^__END__/; if(/^APACI_ARGS/) { s/^APACI_ARGS=//; push @APACI_ARGS, $_; } else { unshift @ARGV, split /\s+/, $_; } } close $fh; } if(@APACI_ARGS) { unshift @ARGV, "APACI_ARGS=" . join(",", @APACI_ARGS); } } my $vcpp = ($Config{cc} =~ /^cl(\.exe)?$/); my %win32_args; my %win32_accept = map {$_ => 1} qw(APACHE_SRC INSTALL_DLL INSTALL_LIB DEBUG EAPI); while($_ = shift) { ($k,$v) = split /=/, $_, 2; if ($vcpp) { if ($win32_accept{$k}) { $win32_args{$k} = ($k eq 'DEBUG' or $k eq 'EAPI') ? 1 : $v; } else { push @mm_args, $_; } next; } unless (/^(PERL|APACHE)/ or is_mp_arg($k)) { push @mm_args, $_; } if ($k eq 'PREFIX') { require File::Spec; $MOD_PERL_PREFIX = File::Spec->catfile($v, $Config{'installstyle'}, 'site_perl', $Config{'version'}, $Config{'archname'}); } $v = 1 unless defined $v; if($experimental{$k}) { $experimental{$k}++; $PERL_EXTRA_CFLAGS .= " -D${k}=1"; } ${$k} = $v, next if defined ${$k}; $callback_hooks{$k} = $v if exists $callback_hooks{$k}; } my $win32_auto; if ($vcpp and $win32_args{APACHE_SRC}) { $EVERYTHING = 1; my $fixed_apsrc = win32_fix_path($win32_args{APACHE_SRC}); $APACHE_SRC = -d "$fixed_apsrc/include" ? $fixed_apsrc : (-d "$fixed_apsrc/src/include" ? $fixed_apsrc . '/src' : die "Cannot find the Apache include directory under $fixed_apsrc"); $win32_auto = 1; unless ($win32_args{INSTALL_DLL}) { my $w32_ap_mod = $fixed_apsrc . '/modules'; $win32_args{INSTALL_DLL} = $w32_ap_mod if -d $w32_ap_mod; } unless ($win32_args{INSTALL_LIB}) { my $w32_ap_lib = $fixed_apsrc . '/libexec'; $win32_args{INSTALL_LIB} = $w32_ap_lib if -d $w32_ap_lib; } } my %very_experimental = map {$_,1} qw(PERL_DEFAULT_OPMASK PERL_SAFE_STARTUP PERL_ORALL_OPMASK PERL_STARTUP_DONE_CHECK PERL_DSO_UNLOAD); if($EXPERIMENTAL) { for (keys %experimental) { next if $very_experimental{$_}; #have to *really* ask for this one next if $experimental{$_}++ > 1; $PERL_EXTRA_CFLAGS .= " -D$_=1"; } } if($experimental{PERL_DEFAULT_OPMASK} > 1) { $experimental{PERL_SAFE_STARTUP} = 2; $PERL_EXTRA_CFLAGS .= " -DPERL_SAFE_STARTUP=1"; } for (keys %PassEnv) { $ENV{$_} = $$_ if $$_; } $USE_APACI = 1 if $USE_DSO; if(0) { #if($USE_DSO or $USE_APXS and !$DO_HTTPD) { print "*" x 65, $/; print <= 5.006) { $PERL_EXTRA_CFLAGS .= " $Config{ccflags}"; } # apache-1.3.xx won't compile with -D_GNU_SOURCE $PERL_EXTRA_CFLAGS =~ s/-D_GNU_SOURCE//; if ($USE_APACI) { print "Will configure via APACI"; if($USE_DSO) { print " (DSO enabled)"; } $NO_HTTPD = 1 if $PREP_HTTPD; print "\n"; } @ARGV = @mm_args; $STATIC = 0 if $DYNAMIC; $Configuration = $CONFIG || "Configuration"; for (keys %callback_alias) { $callback_hooks{$callback_alias{$_}}++ if $callback_hooks{$_}; } if($EVERYTHING) { @callback_hooks{qw(PERL_STACKED_HANDLERS PERL_METHOD_HANDLERS)} = (1) x 2; for(qw(ALL_HOOKS PERL_SSI PERL_SECTIONS PERL_DIRECTIVE_HANDLERS PERL_LOG_API PERL_URI_API PERL_UTIL_API PERL_TABLE_API PERL_FILE_API)) { $$_ = 1; } } if($ALL_HOOKS) { for (@callback_hooks) { next if /(Api|Table|Handler)s?$/i; $callback_hooks{$_}++; } } if($DYNAMIC) { $PERL_DIRECTIVE_HANDLERS = $PERL_TABLE_API = $PERL_FILE_API = $PERL_LOG_API = $PERL_URI_API = $PERL_UTIL_API = 1; } my @xs_modules = qw{ Apache Apache::Constants }; if($Is_Win32) { $NO_HTTPD = 1; $PERL_DIRECTIVE_HANDLERS = 1; } unless ($NO_HTTPD && !$PREP_HTTPD) { for $src_dir ($APACHE_SRC, <../apache*/src>, <../stronghold*/src>, , "../src", "./src") { next unless -d $src_dir; next if $seen{$src_dir}++; next unless $vers = httpd_version($src_dir); unless(exists $vers_map{$vers}) { print STDERR "Apache version '$vers' unsupported\n"; next; } $mft_map{$src_dir} = $vers_map{$vers}; #print STDERR "$src_dir -> $vers_map{$vers}\n"; push @adirs, $src_dir; $modified{$src_dir} = (stat($src_dir))[9]; last if $DO_HTTPD; } unless (@adirs) { print "Enter `q' to stop search\n"; while(1) { print "Please tell me where I can find your apache src\n" ; $src_dir = prompt("", $APACHE_SRC_DEFAULT); last if $src_dir eq "q"; if(-d $src_dir) { push(@adirs, $src_dir); $mft_map{$src_dir} = $vers_map{httpd_version($src_dir)}; last; } else { print "Can't stat `$src_dir'\n"; } } } } if($PERL_EXTRA_CFLAGS) { $PERL_EXTRA_CFLAGS = join(" ", split(",", $PERL_EXTRA_CFLAGS)); $PERL_EXTRA_CFLAGS =~ s/\s+/ /g; } if($PERL_DEBUG) { my $lib = "$Config{archlibexp}/CORE/libperld$Config{lib_ext}"; if (-e $lib) { $LIBPERL = "-lperld"; $libperl = " -- $LIBPERL"; } $PERL_EXTRA_CFLAGS .= " -g"; $PERL_TRACE=1; $PERL_DESTRUCT_LEVEL=2; print "DEBUG mode...\n"; print "...adding `-g' to EXTRA_CFLAGS\n"; print "...turning on PERL_TRACE\n"; print "...setting PERL_DESTRUCT_LEVEL=2\n"; print "...linking against libperld\n" if $libperl; sleep(1); } $PERL_EXTRA_CFLAGS .= " -DPERL_DESTRUCT_LEVEL=$PERL_DESTRUCT_LEVEL" if $PERL_DESTRUCT_LEVEL; for $adir (sort {$modified{$b} <=> $modified{$a}} @adirs) { $conf = "$adir/$Configuration"; $httpd_h = asrc($adir)."/httpd.h"; if (-e $httpd_h) { unless($NO_HTTPD and not $DYNAMIC and not $PREP_HTTPD) { unless($DO_HTTPD) { $ans = prompt("Configure mod_perl with $adir ?", "y"); next unless $ans =~ /^y$/i; } $APACHE_SRC = $adir; $IsBenSSL = -e "$adir/apache_ssl.c"; last unless(-e $conf || -e "$conf.tmpl"); #building from 'make offsite-tar' } #++$NO_HTTPD if $USE_APACI; my $mmn = magic_number($APACHE_SRC); if(($mmn < MMN_130) and $USE_APACI) { #1.3.0 print "Sorry, need 1.3.0+ for USE_APACI\n"; $USE_APACI = $USE_DSO = 0; } for my $api (qw(LOG URI UTIL FILE TABLE)) { local $_ = join "_", "PERL", $api, "API"; if(($mmn < MMN_130) and $$_) { #1.3.0 $$_ = 0; $cant_hook{$_} = "(need 1.3.0 or higher)"; } } if($USE_DSO and $PERL_SSI) { $PERL_SSI=0; $cant_hook{PERL_SSI} = "(doesn't work w/ USE_DSO=1)"; } unless ($DO_HTTPD or $NO_HTTPD) { $ans = prompt("Shall I build httpd in $adir for you?", "y"); ++$NO_HTTPD, ++$PREP_HTTPD unless $ans =~ /^y$/i; } if($NO_HTTPD) { #must generate Makefile.config for 1.3bx unless (-e "$adir/Makefile.config") { my $cfgfile = $CONFIG ? $CONFIG : "Configuration"; print "(cd $adir && ./Configure -file $cfgfile)"; } } #copy the source files if(!$NO_HTTPD or $USE_APACI or $PREP_HTTPD) { mkpath "$adir/modules/perl"; #ignore make's output here `(cd $adir/modules/perl && make clean 2> /dev/null)`; local(*MANI); open MANI, "MANIFEST" or die "open MANIFEST $!"; my $atopdir = dirname($adir); unlink "$atopdir/perlxsi.c"; #only rm and cp files mod_perl ships with while() { next unless m,^src/modules/perl/,; chomp; #print "rm -f $adir/$_\n"; unlink "$atopdir/$_"; next if not m,.+\.(xs|c|h)$, and $USE_APACI; next if $DYNAMIC and /\.xs$/; #print "cp $_ $atopdir/$_\n" if $USE_APACI; my $dest = "$atopdir/$_"; cp $_, $dest; #$mani_src{$_}++; } close MANI; cp "src/modules/perl/mod_perl_version.h", "$atopdir/src/modules/perl/mod_perl_version.h"; if($USE_APACI) { open MANI, "MANIFEST" or die "open MANIFEST $!"; while() { next unless m,^apaci/,; chomp; s/\.PL$//; (my $to = $_) =~ s,^apaci/,src/modules/perl/,; unlink "$atopdir/$to"; print "cp $_ $atopdir/$to\n"; my $dest = "$atopdir/$to"; cp $_, $dest; chmod 0755, $dest if -x $_; } close MANI; } } ($APACHE_ROOT = $APACHE_SRC) =~ s,/src/?$,,; last if $NO_HTTPD; # or $USE_APACI; unless(-e "src/Configuration" and (-M "src/Configuration" < -M $conf) and not $USE_APACI) { unless(-e $conf) { cp "$conf.tmpl", $conf; } cp $conf, "src/Configuration"; $conf = "src/Configuration"; conf_fixup("$adir/Makefile.tmpl", $conf); } } if ($NO_HTTPD) { } elsif($USE_APACI) { #take care of things later } else { $conf = "src/Configuration"; my($dash_make, $cfgfile); $dash_make = " -make $PWD/src/$mft_map{$adir} " if $can_dash_make{asrc $adir} and $mft_map{$adir}; #print STDERR "(cd $adir; ./Configure${dash_make} -file $PWD/$conf)\n"; $cfgfile = $CONFIG ? $CONFIG : "$PWD/$conf"; $dash_make ||= ""; system "(cd $adir && ./Configure${dash_make} -file $cfgfile)"; open FH, "$APACHE_SRC/Makefile" or die "can't open $APACHE_SRC/Makefile $!"; while() { $SSL_BASE ||= $1 if /^\s*SSL_BASE\s*=\s*(.*)/; $EXTRA_CFLAGS = $1 if /CFLAGS1\s*=\s*(.*)/; $SSLINCS = $1 if /SSLINCS\s*=\s*(.*)/; } close FH; if($SSL_BASE) { $SSL_INCLUDE = " -I$SSL_BASE/include "; $SSL_CFLAGS = "-DAPACHE_SSL $SSL_INCLUDE"; } #stronghold if($SSLINCS) { $SSL_INCLUDE = " $SSLINCS "; $SSL_CFLAGS = "-DAPACHE_SSL $SSL_INCLUDE"; } } print "EXTRA_CFLAGS: $EXTRA_CFLAGS\n" if $EXTRA_CFLAGS; print "SSL_CFLAGS: $SSL_CFLAGS\n" if $SSL_CFLAGS; last if $APACHE_SRC; } if($PERL_DIRECTIVE_HANDLERS) { push @xs_modules, "Apache::ModuleConfig"; $callback_hooks{PERL_DIRECTIVE_HANDLERS} = 1; } #if($PERL_RUN_XS or $experimental{PERL_RUN_XS} > 1) { if (0) { my $mmn = $USE_APXS ? MMN_130 : magic_number($APACHE_SRC); if($mmn >= MMN_130) { push @xs_modules, "Apache::PerlRunXS"; } else { $PERL_RUN_XS = 0; $experimental{PERL_RUN_XS} = 0; print "Sorry, need 1.3.0+ for Apache::PerlRunXS\n"; } } for (qw(Log URI Util Connection Server File Table)) { my $s = "PERL_".uc($_)."_API"; if($$s or $Is_Win32) { push @xs_modules, "Apache::$_"; $callback_hooks{$s} = 1; } } my @xs_mod_snames = map { (my $s = $_) =~ s/.*:://; $s } @xs_modules; win32_setup() if $Is_Win32; if($DYNAMIC) { print "Will build Apache::* extensions dynamic\n"; for (@xs_mod_snames) { cp "src/modules/perl/${_}.xs", "${_}/${_}.xs"; } } if($APACHE_SRC or $USE_APXS) { ++$STATIC if grep { $_ eq lc($Config{osname}) } qw(aix svr4 unixware); my $mmn = $USE_APXS ? MMN_130 : magic_number($APACHE_SRC); my $httpdv = $USE_APXS ? 130 : httpd_version($APACHE_SRC,1); unless($httpdv >= 130) { phat_warn("Apache Version 1.3.0 required, aborting..."); exit(1); } if($httpdv >= 130) { if($callback_hooks{PERL_CHILD_INIT}) { $My::child_init++; } } else { $callback_hooks{PERL_CHILD_INIT} = 0; $cant_hook{PERL_CHILD_INIT} = "(need 1.3.0 or higher)"; } if($mmn >= 19970728) { $callback_hooks{PERL_CHILD_EXIT} = $My::child_exit = $callback_hooks{PERL_CHILD_INIT} = $My::child_init = 1; } else { $callback_hooks{PERL_CHILD_EXIT} = 0; $cant_hook{PERL_CHILD_EXIT} = "(need 1.3.0 or higher)"; } unless($mmn >= 19970825) { $callback_hooks{PERL_POST_READ_REQUEST} = 0; $cant_hook{PERL_POST_READ_REQUEST} = "(need 1.3.0 or higher)"; } setup_for_static() unless $USE_APXS; iedit "$APACHE_SRC/modules/perl/Makefile", "s!^PERL\\s*=.*!PERL=$Config{'perlpath'}!" unless $USE_APACI or $USE_APXS; for (@callback_hooks) { ($k,$v) = ($_,$callback_hooks{$_}); unless ($USE_APACI or $USE_APXS) { iedit "$APACHE_SRC/modules/perl/Makefile", "s/^$k /#$k /" if $v; } $why = ($cant_hook{$k} || "(enable with $k=1)") unless $v; $k =~ s/([A-Z]+)/ucfirst(lc($1))/ge; $k =~ s/_//g; $k .= "Handler" unless $k =~ /(Api|Table|Handler)s?$/; push @mod_perl_hooks, $k; print $k . '.' x (28 - length($k)); print $v ? "enabled\n" : "disabled $why\n"; } unless($httpdv >= 120) { $PERL_SECTIONS = $PERL_SSI = 0; $cant_hook{PERL_SECTIONS} = $cant_hook{PERL_SSI} = "(need 1.2.0 or higher)"; } $PERL_SSI = 0 if $Is_Win32; unless ($Is_Win32) { for (qw(PERL_SECTIONS PERL_SSI), keys %experimental) { $k = $_; if($experimental{$_}) { next unless $experimental{$_} > 1; print $k . '.' x (28 - length($k)); print "enabled (experimental)"; } else { $why = ($cant_hook{$_} || "(enable with $k=1)") unless $$_; $k =~ s/([A-Z]+)/ucfirst(lc($1))/ge; $k =~ s/_//g; $k =~ s/Ssi$/SSI/; #*shrug* push @mod_perl_hooks, $k; print $k . '.' x (28 - length($k)); print $$_ ? "enabled" : "disabled $why\n"; } print "\n"; unless ($USE_APACI or $USE_APXS) { iedit "$APACHE_SRC/modules/perl/Makefile", "s/^($_) /#\$1 /" if $$_; } } } unless ($USE_APACI or $USE_APXS) { iedit "$APACHE_SRC/modules/perl/Makefile", "s/^#TRACE/TRACE/" if $PERL_TRACE; } my $ssl_name = is_ssl(); if($ssl_name) { print "I see you are building with $ssl_name,\nI'll set the SSL flags in mod_perl's Makefile\n"; if($ssl_name =~ /stronghold/i) { my $skey; my $lfile; my $conf = "$APACHE_SRC/../conf/httpd.conf"; if(-e $conf) { open FH, $conf; while() { chomp; if(/^StrongholdKey/) { $skey = $_; last; } elsif(s/^StrongholdLicenseFile\s+//) { $lfile = $_; unless ($lfile =~ m:^/:) { $lfile = "$PWD/$APACHE_SRC/../$lfile"; } } } close FH; } if($skey) { $StrongholdKey = $skey; print "Using $skey for 'make test'\n"; } elsif(-e $lfile) { $StrongholdKey = join " ", "StrongholdLicenseFile", $lfile; print "Using $StrongholdKey for 'make test'\n"; } else { print "Before running `make test', ", "you must add your `StrongholdLicenseFile' to t/conf/httpd.conf\n"; } } unless ($USE_APACI or $USE_APXS) { iedit "$APACHE_SRC/modules/perl/Makefile", "s:^#APACHE_SSL.*:APACHE_SSL = $SSL_CFLAGS:"; } } #my $incdir = ($mmn >= 19970825) ? "../../main" : "../.."; my $minc = asrc($APACHE_SRC); $minc =~ /(main|include)/; my $incdir = $1 ? "../../$1" : "../.."; my $edit_note = quotemeta(<= 19970912 and not $USE_APACI and not $USE_APXS and not $Is_Win32) { #1.3b1 system "cat $APACHE_SRC/Makefile.config $APACHE_SRC/modules/perl/Makefile > /tmp/mpmf.$$"; system "mv /tmp/mpmf.$$ $APACHE_SRC/modules/perl/Makefile"; } if($callback_hooks{PERL_TRANS}) { push @test_pre_init, "\t", '$(CP) t/conf/mod_perl_srm.conf t/conf/srm.conf', "\n"; } unless ($USE_APXS) { unless (-l "t/httpd" or $Is_Win32) { system "$Config{lns} $APACHE_SRC/httpd t/httpd"; } write_extra_tests(); } } unless (-e "t/net/config.pl") { cp "t/net/config.pl.dist", "t/net/config.pl"; } init_config_pl() if $Is_Win32; my (%win32_path); if ($win32_auto) { require File::Spec; win32_inc_and_lib(); win32_fix_dsp(); } write_my_config($APACHE_SRC); unless($Is_Win32 or -e "t/conf/httpd.conf" or ($NO_HTTPD && !$PREP_HTTPD)) { init_tests_and_config(); } init_tests_and_config() if $USE_APXS; sub init_config_pl { my $mmn = magic_number($APACHE_SRC) || 0; my $hf = FileHandle->new(">>t/net/config.pl") or die "can't open t/net/config.pl $!"; my $apaci_cfg = APACI->init; my($k,$v); my(%all) = %callback_hooks; while (($k,$v) = each %experimental) { $all{$k} = ($experimental{$k} > 1) ? 1 : 0; } print $hf "%callback_hooks = (\n"; while (($k,$v) = each %all) { print $hf " $k => $v,\n"; my $yes_no = $v ? "yes" : "no"; print $apaci_cfg "$k = $yes_no\n" if $apaci_cfg; } print $hf " MMN => $mmn,\n"; print $hf " USE_DSO => 1,\n" if $USE_DSO; print $hf ");\n1;\n"; $hf->close; $apaci_cfg->close if $apaci_cfg; } sub init_tests_and_config { local *FH; open FH, ">t/conf/dev-null"; print FH "#mod_ssl has a problem with /dev/null\n"; close FH; cp "t/conf/httpd.conf-dist", "t/conf/httpd.conf"; chmod 0644, "t/conf/httpd.conf"; $uid = $>; $gid = $); #use only first value if $) contains more than one $gid =~ s/^(\d+).*$/$1/; $User = $Is_Win32 ? "nobody" : $ENV{APACHE_USER} || (getpwuid($uid) || "#$uid"); $Group = $Is_Win32 ? "nogroup" : $ENV{APACHE_GROUP} || (getgrgid($gid) || "#$gid"); if($User eq "root") { my $other = (getpwnam('nobody'))[0]; $User = $other if $other; } if($User eq "root") { print "Cannot run tests as User `$User'\n"; $User = prompt("Which User?", "nobody"); $Group = prompt("Which Group?", $Group); } print STDERR "Will run tests as User: '$User' Group: '$Group'\n"; if($Port != $PORT) { iedit "t/conf/httpd.conf", "s/^(Port) .*/\$1 $PORT/"; iedit "t/net/config.pl", "s/$Port/$PORT/;"; } if($experimental{PERL_SAFE_STARTUP} > 1) { if($experimental{PERL_DEFAULT_OPMASK} < 2) { iedit "t/conf/httpd.conf", "s/^#(PerlOpmask)/\$1/"; } } init_config_pl(); if($USE_APACI and not $PREP_HTTPD and not $USE_APXS) { my $shrpenv = $Config{shrpenv} || ""; $shrpenv .= ' ' if $shrpenv; my $cmd = "CC=\"${shrpenv}$Config{cc}\" "; if($PERL_EXTRA_CFLAGS) { $cmd .= qq(CFLAGS="$PERL_EXTRA_CFLAGS" ); } if ($USE_DSO) { # override apache's notion of this flag $cmd .= qq(LDFLAGS_SHLIB_EXPORT="$Config{ccdlflags}" ); #if Perl is linked with -lpthread, httpd needs tobe too if ($Config{libs} =~ /($thrlib)/) { $PERL_EXTRA_LIBS .= " $1"; } } if ($PERL_EXTRA_LIBS) { $cmd .= qq(LIBS="$PERL_EXTRA_LIBS" ); } $cmd .= "./configure " . "--activate-module=src/modules/perl/libperl.a"; # Do not disable the rule EXPAT for Stronghold, since this # rule is not implementated yet and breaks the configure process. if(is_ssl() !~ /stronghold/i) { $cmd .= " --disable-rule=EXPAT"; } if($USE_DSO) { $cmd .= " --enable-shared=perl"; } if($APACI_ARGS) { $cmd .= " " . join " ", split(',', $APACI_ARGS); } if($APACHE_PREFIX and $APACI_ARGS !~ /--prefix=/) { $cmd .= " --prefix=$APACHE_PREFIX"; } if ($APACI_ARGS =~ /--target=(\S+)/) { $TARGET = $1; } if($ADD_MODULE) { for (split ",", $ADD_MODULE) { if(/^([a-zA-Z0-9][a-zA-Z0-9_]+)$/) { $cmd .= " --enable-module=$1"; } elsif(m:(src/modules/[^/]+/[^/]+)$:) { $cmd .= " --activate-module=$1"; } } } print "(cd $APACHE_ROOT && $cmd)\n"; system "(cd $APACHE_ROOT && $cmd)"; } if($USE_APXS) { my $cmd = "./configure --with-perl=$^X"; $cmd .= " --with-apxs=$WITH_APXS" if $WITH_APXS; system "(cd apaci && $cmd)"; } #expand ./t to full path iedit "t/conf/httpd.conf", "s: \./t(\\S*): $PWD/t\$1:"; for (qw(User Group)) { $$_ = qq{"$$_"} if $$_ =~ /\s/; # User takes one parameter iedit "t/conf/httpd.conf", "s/^$_ .*/$_ $$_/"; } conf_append(<= 121 or $mmn >= MMN_130; conf_append("PerlChildInitHandler My::child_init") if $My::child_init; conf_append("PerlChildExitHandler My::child_exit") if $My::child_exit; conf_append("PerlTransHandler My::ProxyTest") if $callback_hooks{PERL_TRANS} and $callback_hooks{PERL_STACKED_HANDLERS} and $mmn > 19980270 and $Is_dougm; conf_append(< SetHandler perl-script PerlHandler Stacked::one Stacked::two Stacked::three Stacked::four EOF } { (my $pmv = $VERSION) =~ s/_//g; $pmv =~ s/-dev$//; my $hooks = "@mod_perl_hooks"; my $dummy = "hooks=`$hooks'\n" unless $hooks; cp "lib/mod_perl_hooks.pm.PL", "lib/mod_perl_hooks.pm"; if ($Is_Win32) { my @args = ($^X, '-spi.bak', '-e', "\"s/sub mod_perl::hooks.*/sub mod_perl::hooks { qw($hooks) }/\"", 'lib/mod_perl_hooks.pm'); system(@args) == 0 or die "@args failed\n"; } iedit "lib/mod_perl_hooks.pm", qq(s/sub mod_perl::hooks.*/sub mod_perl::hooks { qw($hooks) }/); require "lib/mod_perl_hooks.pm"; my @list = mod_perl::hooks(); unless ($Is_Cygwin) { # test doesn't seem to be needed, works for me (Per Einar) @list == @mod_perl_hooks or die "Edit of lib/mod_perl_hooks.pm failed $!\n"; } unlink $Is_Win32 ? "lib/mod_perl_hooks.pm.bak" : "lib/mod_perl_hooks.pm~"; } #checking for LWP code, borrowed from LWP's own Makefile.PL :-) unless ($Is_Win32) { print "Checking CGI.pm VERSION.........."; eval { require CGI; }; if($CGI::VERSION >= 2.39) { print "ok\n"; } else { print "I suggest upgrading from $CGI::VERSION to 2.39+\n"; sleep 2; } print "Checking for LWP::UserAgent......"; eval { require LWP::UserAgent; }; if ($@) { $no_lwp++; $missing_modules++; print "failed\n"; print <t/docs/blib.pl"; print FH "use lib qw(\n", (map { "$PWD/$_\n" } qw(blib/lib blib/arch)), ");\n1;\n"; close FH; for my $f (qw(.htaccess hooks.txt)) { open FH, ">t/docs/$f"; print FH " "; close FH; chmod 0666, "t/docs/$f";#make sure httpd can write to it } if($PERL_SSI) { cp "t/modules/ssi.test", "t/modules/ssi.t"; } else { unlink "t/modules/ssi.t"; # might be there from prior run } mkdir "t/docs/subr", 0755; if ($Is_Win32) { open FH, ">t/docs/subr/index.html" or die "Cannot open t/docs/subr/index.html: $!"; print FH scalar(localtime); close FH; } else { system "date > t/docs/subr/index.html"; } return unless $callback_hooks{PERL_STACKED_HANDLERS} and $callback_hooks{PERL_FIXUP}; local *FH; my $meth_test; if($callback_hooks{PERL_METHOD_HANDLERS}) { $meth_test = <<'EOF'; #see startup.pl PerlFixupHandler MyClass->method PerlFixupHandler $MyClass::Object->method PerlFixupHandler MyClass PerlFixupHandler LoadClass PerlFixupHandler LoadClass->method EOF } my $dir = "t/docs/stacked"; mkdir $dir, 0755; cp "t/docs/test.html", $dir; open FH, ">$dir/.htaccess"; print FH < \@DIR, NAME => "mod_perl", VERSION => $VERSION, ($] < 5.005 ? () : ( ABSTRACT => 'Embed a Perl interpreter in the Apache HTTP server', AUTHOR => 'Doug MacEachern ', )), #should override `CCFLAGS', can't with older perls #CCDLFLAGS => "$Config{ccdlflags} $EXTRA_CFLAGS", DEFINE => $EXTRA_CFLAGS, macro => { PERL => $Config{'perlpath'}, OPCODE_FILE => "src/opcodes.txt", APACHE_ROOT => $APACHE_ROOT, APACHE_SRC => $APACHE_SRC, ARCHNAME => $Config{archname}, HTTPD => $TARGET, PORT => $PORT, PWD => $PWD, PERL5LIB_ENV => "PERL5LIB=$ENV{PERL5LIB}", SHRPENV => $Config{shrpenv}, CVSROOT => 'cvs.apache.org:/home/cvs', }, 'dist' => { COMPRESS=> 'gzip -9f', SUFFIX=>'gz', CI => qq(ci -u -m\\"See Changes file\\"), }, clean => { FILES => "@do_clean", } ); print "*** BSDI users: be sure to read the INSTALL `Notes' section ***\n" if $Config{osname} =~ /bsdos/i; cleanup_for_static(); sub MY::dist_basics { my $self = shift; my $string = $self->MM::dist_basics; if($USE_APXS) { $string =~ s/(distclean\s+::\s+)/$1 apxs_distclean /; } return $string; } sub MY::clean { my $self = shift; my $string = $self->MM::clean(@_); if ($win32_auto) { $string .= sprintf qq{\tmsdev src\\modules\\win32\\mod_perl.dsp \\\n} . qq{\t/MAKE "mod_perl - Win32 %s" /CLEAN\n}, ($win32_args{DEBUG} == 1) ? 'Debug' : 'Release'; return $string; } unless($NO_HTTPD) { my $asrc = asrc($APACHE_SRC, "http_main.c"); return $string unless $APACHE_SRC and -e "$asrc/http_main.c"; $string .= "\t-cd \$(APACHE_SRC) && \$(MAKE) clean\n"; } if($USE_APXS) { $string .= "\t-cd ./apaci && \$(MAKE) clean\n"; } $string; } sub MY::install { my $self = shift; my $string = $self->MM::install; my $add = ""; if($USE_APXS) { $add = "apxs_install"; } elsif ($win32_auto and ($win32_args{INSTALL_DLL} or $win32_args{INSTALL_LIB})) { $add = 'amp_install'; } elsif($USE_APACI) { if($APACI_ARGS =~ /--prefix=/ or $APACHE_PREFIX) { $add = "apaci_install"; } } if($add and (!$NO_HTTPD and !$PREP_HTTPD) or $USE_APXS or $win32_auto) { $string =~ s/(pure_install\s+)(.*)/$1 $add $2/; } return $string; } sub MY::top_targets { my $self = shift; my $string = $self->MM::top_targets; return $string unless $USE_APXS or $USE_APACI or $APACHE_SRC or $win32_auto; if ($win32_auto) { $string =~ s/(pure_all\s+::.*\s+subdirs\s+)(.*)/$1 amp_dll $2/; $string .= sprintf qq{\namp_dll:\n} . qq{\tmsdev src\\modules\\win32\\mod_perl.dsp \\\n} . qq{\t/MAKE "mod_perl - Win32 %s" /USEENV\n}, ($win32_args{DEBUG} == 1) ? 'Debug' : 'Release'; if ($win32_args{INSTALL_DLL}) { $string .= sprintf qq{\namp_install:\n\t\$(CP) "%s" "%s"}, "$win32_path{MODPERL_LIB}/mod_perl.so", $win32_args{INSTALL_DLL} . ($win32_args{APACHE_VERS} < 1315 ? '/ApacheModulePerl.dll' : '/mod_perl.so'); } if ($win32_args{INSTALL_LIB}) { $string .= sprintf qq{\n\t\$(CP) "%s" "%s"}, "$win32_path{MODPERL_LIB}/mod_perl.lib", $win32_args{INSTALL_LIB} . '/mod_perl.lib'; } return $string; } if($USE_APXS) { $string =~ s/(pure_all\s+::\s+)(.*)/$1 apxs_libperl $2/; } elsif($USE_APACI and !$PREP_HTTPD) { $string =~ s/(pure_all\s+::\s+)(.*)/$1 apaci_httpd $2/; } elsif($APACHE_SRC) { return $string unless -f "$APACHE_SRC/$Configuration"; my $asrc = asrc($APACHE_SRC, "http_main.c"); if(-e "$asrc/http_main.c" and !$NO_HTTPD) { $string =~ s/(pure_all\s+::\s+)(.*)/$1 apache_httpd $2/; } } $string .= <<'EOF'; gen_exports: $(PERL) -I./lib -MExtUtils::testlib -MApache::Constants::Exports \ -e 'Apache::Constants::Exports->gen_ctags' > Exports.c gen_op_mask: $(PERL) -MExtUtils::testlib -MApache::Opcode \ -e 'Apache::Opcode->gen_op_mask' -- $(OPCODE_FILE) > op_mask.c update_op_mask: gen_op_mask @$(RM_F) $(APACHE_SRC)/modules/perl/mod_perl_opmask.o $(CP) op_mask.c $(APACHE_SRC)/modules/perl/op_mask.c apxs_distclean: (cd ./apaci && $(MAKE) distclean) apxs_libperl: (cd ./apaci && $(PERL5LIB_ENV) $(MAKE)) apxs_install: apxs_libperl (cd ./apaci && $(MAKE) install;) apache_httpd: $(APACHE_SRC)/Makefile.tmpl (cd $(APACHE_SRC) && $(PERL5LIB_ENV) $(SHRPENV) $(MAKE) CC="$(CC)";) apaci_httpd: (cd $(APACHE_ROOT) && $(PERL5LIB_ENV) $(MAKE)) apaci_install: (cd $(APACHE_ROOT) && $(MAKE) install) tar_Apache: (cd $(INSTALLSITELIB)/$(ARCHNAME); \ $(TAR) -cf $(PWD)/Apache.tar mod_perl.pm Apache.pm Apache auto/Apache; ) offsite-tar: $(CP) MANIFEST MANIFEST.orig echo src/Makefile.config >> MANIFEST $(CP) $(APACHE_SRC)/Makefile.config src/Makefile.config mkdir "src/include" $(PERL) -e 'for (<$(APACHE_SRC)/include/*.h>) {' \ -e 'system "$(CP) $$_ src/include/";' \ -e 's,^$(APACHE_SRC),,;' \ -e 'system "echo src$$_ >> MANIFEST";' \ -e '}' $(MAKE) dist $(RM_RF) src/include/ $(RM) src/Makefile.config $(MV) MANIFEST.orig MANIFEST EOF $string; } sub MY::pasthru { return unless $APACHE_SRC; my $self = shift; chomp(my $str = $self->MM::pasthru); join $/, "$str\\", "\t".'APACHE_SRC="$(APACHE_SRC)"\\', "\t".'DEFINE="$(DEFINE)"', ""; } sub MY::test { my $self = shift; my $test = $self->MM::test; my $mmn = magic_number($APACHE_SRC); return <<'EOF' if $USE_APXS and not $Is_dougm; test: @echo "Can't make test with APXS (yet)" EOF return <<'EOF' if $USE_DSO and ($mmn <= 19980527) and not $Is_dougm; test: @echo "Can't make test with DSO (yet)" EOF my $script = "t/TEST"; $script .= ".win32" if $Is_Win32; my $my_test = $Is_Win32 ? q( test: run_tests ) : q( test: pure_all start_httpd run_tests kill_httpd ); my $have_so = $USE_DSO || ($APACI_ARGS =~ /--enable-shared=/); push @test_pre_init, "\t", './apaci/load_modules.pl $(APACHE_SRC)', "\n" if $have_so; join '', @test_pre_init, qq( MP_TEST_SCRIPT=$script ), q( TEST_VERBOSE=0 kill_httpd: kill `cat t/logs/httpd.pid` @$(RM_F) t/conf/srm.conf @$(RM_F) t/logs/mod_perl.lock* $(RM_F) t/logs/httpd.pid $(RM_F) t/logs/error_log start_httpd: test_pre_init @(cd t/conf; test -f httpd.conf || cp httpd.conf-dist httpd.conf) @(cd t/net; test -f config.pl || cp config.pl.dist config.pl) @$(TOUCH) t/conf/srm.conf $(APACHE_SRC)/$(HTTPD) -f `pwd`/t/conf/httpd.conf -X -d `pwd`/t & @echo httpd listening on port $(PORT) @echo will write error_log to: t/logs/error_log @echo "letting apache warm up...\c" @sleep 2 @echo done start_httpd_fork: $(APACHE_SRC)/$(HTTPD) -f `pwd`/t/conf/httpd.conf -d `pwd`/t rehttpd: kill_httpd start_httpd run_tests: $(FULLPERL) $(MP_TEST_SCRIPT) $(TEST_VERBOSE) ), $my_test, q( test_report: $(MAKE) test | t/report ); } use File::Find; sub MY::subdirs { my $self = shift; if($ENV{TEST_PERL_DIRECTIVES}) { push @{$self->{DIR}}, "t/TestDirectives"; } $self->MM::subdirs(@_); } sub wanted { return unless /\.h$/ or /os-inline\.c$/; (my $d = $File::Find::dir) =~ s:^\Q$APACHE_SRC::; $d =~ s:^/::; my $from = "$File::Find::dir/$_"; my $to = '$(INST_ARCHLIB)/' . "auto/Apache/include/"; $to .= "$d/" if $d; $to .= $_; $My::self->{PM}->{$from} = $to; } sub win32_mph { return unless /\.h$/ or /os-inline\.c$/; (my $d = $File::Find::dir) =~ s:^\Q$MODPERL_SRC::; $d =~ s:^/::; my $from = "$File::Find::dir/$_"; my $to = '$(INST_ARCHLIB)/' . "auto/Apache/include/modules/perl/"; $to .= "$d/" if $d; $to .= $_; $My::self->{PM}->{$from} = $to; } sub MY::post_initialize { my($self) = shift; return unless $APACHE_HEADER_INSTALL; my($ap_src, $ap_inc); if ($APACHE_SRC) { $ap_src = $APACHE_SRC; $ap_inc = "$ap_src/include"; } elsif ($USE_APXS) { #$base = `$WITH_APXS -q INCLUDEDIR`; $ap_inc = $ap_src = 'src'; #just install mod_perl headers } return unless $ap_src and -d $ap_src; $My::self = $self; { local $APACHE_SRC = $ap_src; finddepth(\&wanted, $ap_src); } if ($Is_Win32) { local $MODPERL_SRC = win32_fix_path($PWD) . '/src/modules/perl'; finddepth(\&win32_mph, $MODPERL_SRC); } $self->{PM}{"Apache/typemap"} = '$(INST_ARCHLIB)/' . "auto/Apache/typemap"; $self->{PM}{"apaci/mod_perl.exp"} = '$(INST_ARCHLIB)/' . "auto/Apache/mod_perl.exp"; for (qw(ap_config_auto.h)) { my $from = "$ap_inc/$_"; my $to = '$(INST_ARCHLIB)/' . "auto/Apache/include/$_"; unless ($self->{PM}->{$from}) { $self->{PM}->{$from} = $to; my @args = ($Config{perlpath}, '-MExtUtils::Command', '-e', 'touch', $from); system(@args) == 0 or die "system @args failed: $?"; } } ''; } sub MY::postamble { return <<'EOF'; cvs_export : cvs -d $(CVSROOT) export -rv$(VERSION_SYM) -d$(DISTVNAME) . cvs_tag : cvs -d $(CVSROOT) tag v$(VERSION_SYM) modperl @echo update mod_perl.pm VERSION now EOF } #' sub MY::manifypods { my $self = shift; my $ver = $self->{VERSION} || ""; local($_) = $self->MM::manifypods(@_); s/pod2man\s*$/pod2man --release mod_perl-$ver/m; $_; } sub fold_dots { my $v = shift; $v =~ s/\.//g; $v .= "0" if length $v < 3; $v; } sub vcache { my($v,$dir) = @_; $vcache{$dir} = fold_dots($v); } sub httpd_version { my($dir, $vnumber) = @_; local $^W=0; $dir = asrc($dir) || ""; if($vnumber) { return $vcache{$dir} if $vcache{$dir}; } my $fh = FileHandle->new("$dir/httpd.h") or return; my($server, $version, $rest); my($fserver, $fversion, $frest); my($string, $extra, @vers); while(<$fh>) { next unless /^#define/; s/SERVER_PRODUCT \"/\"Apache/; #1.3.13 next unless s/^#define\s+SERVER_(BASE|)(VERSION|REVISION)\s+"(.*)\s*".*/$3/; unless (m:/:) { $_ = "Apache/$_"; #1.3.14, argh } chomp($string = $_); #print STDERR "Examining SERVER_VERSION '$string'..."; #could be something like: #Stronghold-1.4b1-dev Ben-SSL/1.3 Apache/1.1.1 @vers = split /\s+/, $string; foreach (@vers) { next unless ($fserver,$fversion,$frest) = m,^([^/]+)/(\d\.\d+\.?\d*)([^ ]*),i; #print STDERR "match ($fserver,$fversion,$frest)\n"; if($fserver =~ /Xcert-Sentry/i or $fserver eq "Ben-SSL") { $extra ||= $fserver; #print STDERR "I see $fserver/$fversion, ok\n"; next; } if($fserver eq "Apache") { ($server, $version) = ($fserver, $fversion); if($version eq '1.2' and $frest =~ s/^b(\d+).*/$1/) { if($frest >= 8 and is_ssl($dir)) { $do_link_swap++; $can_dash_make{$dir}++; return $vnumber ? vcache($version,$dir) : "NONE"; } warn "Apache/1.2b$frest is not supported, upgrade to 1.2.0.\n"; return undef; } elsif($version >= 1.2) { $do_link_swap++ if is_ssl($dir); $can_dash_make{$dir}++; return $vnumber ? vcache($version,$dir) : "NONE"; } } else { #print STDERR "'$fserver/$fversion' unrecognized.\n"; next; } print STDERR "Found $fserver '$fversion' in $dir/httpd.h\n"; } } $fh->close; #print STDERR "return $version$extra\n"; return($version.$extra); } use lib "./lib"; use Apache::src (); sub magic_number { my $d = asrc shift; my $src = Apache::src->new; $src->dir($d); return($mcache{$d} = $src->module_magic_number); } sub cleanup_for_static { return unless $STATIC; for (@xs_mod_snames) { rename "${_}/${_}.xs.disabled", "${_}/${_}.xs"; } } sub setup_for_static { my $d = "$APACHE_SRC/modules/perl"; my $mf = "$APACHE_SRC/modules/perl/Makefile"; my @static_src = (); unless ($USE_APACI) { iedit $mf, "s/(PERL_STATIC_EXTS) =.*/\$1 = $PERL_STATIC_EXTS/" if $PERL_STATIC_EXTS; } return unless $STATIC; cp "Apache/typemap", $d; for (@xs_mod_snames) { rename "${_}/${_}.xs", "${_}/${_}.xs.disabled" if -e "${_}/${_}.xs"; push @static_src, "$_.c"; } =pod my @xs_names = (); my @xs_files = (); my $dir = "src/modules/perl"; my $dh = DirHandle->new($dir) or die; for my $file ($dh->read) { next unless $file =~ /\.xs$/; push @xs_names, module_name_from_xs("$dir/$file"); push @xs_files, $file; unless ($mani_src{"$dir/$file"}) { cp "$dir/$file", $d; print "Adding module `$xs_names[-1]' to httpd\n"; } } #print "XS_NAMES=@xs_names\n"; #print "XS_FILES=@xs_files\n"; #XXX think about this some more iedit $mf, "s/^#STATIC_SRC.*/STATIC_SRC = @xs_files/"; iedit $mf, "s/^#STATIC_EXTS.*/STATIC_EXTS = @xs_names/"; =cut unless ($USE_APACI) { #XXX: ho,hum, need to generate the whole damn thing #instead of all these frigging iedits. if ($DYNAMIC) { } else { iedit $mf, "s/^#STATIC_SRC.*/STATIC_SRC = @static_src/"; iedit $mf, "s/^#STATIC_EXTS.*/STATIC_EXTS = @xs_modules/"; iedit $mf, "s/^#STATIC_/STATIC_/"; } #bloody hell, make sucks and so does this. #this has only cause a few people pain, enough. iedit $mf, "s/ \Q\$(STATIC_SRC)\E/ @static_src/"; } } sub module_name_from_xs { my $file = shift; my $fh = FileHandle->new($file) or die "can't open file $file $!"; my($module, $package, $prefix, %seen); while(<$fh>) { if( ($module, $package, $prefix) = /^MODULE\s*=\s*([\w:]+)(?:\s+PACKAGE\s*=\s*([\w:]+))?(?:\s+PREFIX\s*=\s*(\S+))?\s*$/) { $seen{$module}++; } } if(keys %seen > 1) { warn "$module name guess might be incorrect"; } return (keys %seen)[0]; } sub asrc { my $d = shift; my $file = shift || "httpd.h"; return $d if -e "$d/$file"; return "$d/include" if -e "$d/include/$file"; return "$d/main" if -e "$d/main/$file"; return undef; } sub conf_append { local *CFG; open CFG, ">>t/conf/httpd.conf" or die "open httpd.conf $!"; print CFG join "\n", @_, ""; close CFG; } sub edit_extra_cflags { my($cfg) = @_; my $fh = IO::File->new($cfg) or die "open $cfg $!"; my $repl = ""; my @file = (); my $ccopts = ccopts(); my $dssv = "-DSERVER_SUBVERSION"; my $ssv = qq($dssv=\\"mod_perl/$VERSION\\" ); my $inc = " $ccopts -I. -I../.. -DUSE_PERL_SSI" if $PERL_SSI; $inc .= " -DAPACHE_SSL" if is_ssl() and $PERL_SSI; $inc .= $SSL_INCLUDE if $SSL_INCLUDE; $inc .= " -DSTRONGHOLD" if is_ssl() =~ /stronghold/i; $inc .= " $PERL_EXTRA_CFLAGS" if $PERL_EXTRA_CFLAGS; $inc .= " -DMOD_PERL"; while (<$fh>) { push @file, $_; next unless /EXTRA_CFLAGS\s*=/; next if /mod_perl/; next if /^#/; chomp; $repl = $_; my $backwhack = ""; if($repl =~ s/(\\)\s*$//) { $backwhack = $1; } my $mmn = magic_number($APACHE_SRC); if($mmn >= 19980507) { $ADD_VERSION = 0; } if($ADD_VERSION) { if(/$dssv=/) { $repl =~ s{ $dssv\s*=\s*(.?)['"](.*?)(.?)["'] }[ qq($dssv="$1"$2 mod_perl/$VERSION$3"") ]ex; } else { $repl .= " $ssv"; } } $file[-1] = "$repl $inc $backwhack\n"; } close $fh; if($repl) { $fh = IO::File->new(">$cfg") or die "open $cfg $!"; print $fh @file; close $fh; } } sub conf_fixup { my($mf, $cfg) = @_; return if $USE_APACI; my $mmn = magic_number($APACHE_SRC); #source re-org my $sro = 1 if $mmn >= 19970825; edit_extra_cflags($cfg); $PERL_STATIC_EXTS ||= ""; $libperl ||= ""; my $ldopts = "`$^X $PWD/src/modules/perl/ldopts $PERL_STATIC_EXTS $libperl`"; iedit $cfg, q{next unless /EXTRA_LIBS\s*=/;}. q{next if /perl/; chomp;}. qq{\$_ .= q| $ldopts\n|;}; for (split ",", $ADD_MODULE) { add_module($cfg,$_); } if(is_ssl() =~ /stronghold/i) { if($do_link_swap) { warn "swapping link order in $mf for Stronghold\n"; my $repl = quotemeta('$(REGLIB) $(LIBS)'); iedit $mf, "s:\Q\$(LIBS) \$(REGLIB)\E:$repl:;"; #XXX hack $repl = quotemeta('CFLAGS=$(CFLAGS)'); iedit $mf, qq(s:\Q\"CFLAGS=\$(CFLAGS)"\E:'$repl':;); #" } my $repl = q{AUX_CFLAGS='\$(CFLAGS)'}; iedit $mf, qq{s/AUX_CFLAGS="..CFLAGS."/$repl/}; } { my $repl = q{CC='\$(CC)'}; iedit $mf, qq{s/CC=..CC. /$repl /}; } open(CONF, $cfg) || die "Can't open $cfg: $!"; while () { $seen_modperl++ if /^Module\s+perl_module/i || /^AddModule\s+.*libperl/; } close(CONF); unless ($seen_modperl) { print "Appending mod_perl to $conf\n"; open(CONF, ">>$cfg") || die "Can't open $cfg: $!"; my $line; $line = $sro ? "AddModule modules/perl/libperl.a" : "Module perl_module modules/perl/libperl.a"; print CONF <) { if(/^\\w{0,3}Module\\s+.*$name\.[oa]/i) { close IN; # print STDERR "has module $name\n"; return 1; } } return 0; } sub add_module { my($cfg, $name) = @_; iedit $cfg, "s/^#\\s+(\\w{0,3}Module\\s+.*$name\.[oa])/\$1/"; } sub gen_script { my $file = shift; my(@lib) = @_; local(*IN,*OUT); open IN, "$file.PL" or die "Couldn't open $file.PL: $!"; open OUT, ">$file" or die "Couldn't open $file: $!"; print OUT "#!$Config{perlpath}\n"; if (@lib) { print OUT "use lib qw(@lib);\n"; } print OUT join '', ; close OUT; close IN; chmod 0755, "$file"; } sub iedit { my $file = shift; return if $Is_Win32; #print STDERR "-e @_\n"; system $^X, "-pi~", "-e", "@_", $file; } sub win32_setup { my $d = "src/modules/perl"; dirent_kludge($d); cp "Apache/typemap", $d; chdir $d; system "$^X -MExtUtils::Embed -e xsinit -- -std @xs_modules $PERL_STATIC_EXTS"; my $lib = $Config{privlibexp}; for (@xs_mod_snames) { system "$^X $lib/ExtUtils/xsubpp -typemap $lib/ExtUtils/typemap $_.xs > $_.c"; } chdir "../../../"; open(F, '>t/docs/init.pl') or die "Cannot open t/docs/init.pl: $!"; print F <<"END"; #!perl \$Apache::Server::CWD = '$PWD'; END close F; } sub dirent_kludge { my $d = shift; local *FH; open FH, ">$d/dirent.h" or die "can't write $d/dirent.h $!"; print FH <$d/mod_perl_version.h" or die "can't write $d/mod_perl_version.h $!"; print FH < } . ($my_config{$_} =~ /^\d+$/ ? $my_config{$_} : qq{'$my_config{$_}'}) } sort keys %my_config; local *FH; open FH, '>lib/Apache/MyConfig.pm' || die "Can't open lib/Apache/MyConfig.pm: $!"; print FH < module provides access to the various hooks and features set when mod_perl is built. This circumvents the need to set up a live server just to find out if a certain callback hook is available. Itterate through \%Apache::MyConfig::Setup to get obtain build information then see Appendix B of the Eagle book for more detail on each key. EOT close FH; } # obtain the Apache and mod_perl lib and include directories for Win32 sub win32_inc_and_lib { my $modperl_src = win32_fix_path(cwd) . '/src'; $win32_path{MODPERL_INC} = $modperl_src . '/modules/perl'; $win32_path{MODPERL_LIB} = ($win32_args{DEBUG} == 1) ? $modperl_src . '/modules/win32/Debug' : $modperl_src . '/modules/win32/Release'; unless ( -d $win32_args{APACHE_SRC}) { opendir(DIR, '../') or die "Cannot read parent directory: $!\n"; my @dirs = map {"../$_"} grep {/apache/ and -d "../$_"} readdir DIR; closedir DIR or die "Cannot close parent directory: $!\n"; die "Cannot find the apache sources\n" unless ($win32_args{APACHE_SRC} = find_dir(\@dirs, 'apache source')); } $win32_args{APACHE_SRC} = win32_fix_path($win32_args{APACHE_SRC}); if (-d "$win32_args{APACHE_SRC}/libexec") { $win32_path{APACHE_LIB} = $win32_args{APACHE_SRC} . '/libexec'; $win32_path{APACHE_INC} = $win32_args{APACHE_SRC} . '/include'; $win32_args{APACHE_VERS} = httpd_version($win32_path{APACHE_INC}, 1); } else { $win32_args{APACHE_SRC} .= '/src' unless $win32_args{APACHE_SRC} =~ /src$/; $win32_path{APACHE_INC} = $win32_args{APACHE_SRC} . '/include'; $win32_args{APACHE_VERS} = httpd_version($win32_path{APACHE_INC}, 1); $win32_path{APACHE_LIB} = ($win32_args{DEBUG} == 1) ? $win32_args{APACHE_SRC} . ($win32_args{APACHE_VERS} < 1315 ? '/CoreD' : '/Debug') : $win32_args{APACHE_SRC} . ($win32_args{APACHE_VERS} < 1315 ? '/CoreR' : '/Release'); } die "Cannot find ApacheCore.lib under $win32_path{APACHE_LIB}\n" unless -f "$win32_path{APACHE_LIB}/ApacheCore.lib"; die "Cannot find httpd.h under $win32_path{APACHE_INC}\n" unless -f "$win32_path{APACHE_INC}/httpd.h"; if ($win32_args{INSTALL_DLL} ) { $win32_args{INSTALL_DLL} = win32_fix_path($win32_args{INSTALL_DLL}); unless ( -d $win32_args{INSTALL_DLL}) { my @dirs = grep {-d} ('\Program Files\Apache Group\Apache\modules', '\Apache\modules', '\Program Files\Apache\modules'); $win32_args{INSTALL_DLL} = find_dir(\@dirs, 'Apache/modules'); if ($win32_args{INSTALL_DLL} and -d $win32_args{INSTALL_DLL}) { $win32_args{INSTALL_DLL} = win32_fix_path($win32_args{INSTALL_DLL}); } else { print <<'END'; **** The Apache/modules directory was not found. ******* **** Please install mod_perl.so manually. ******* END } } } if ($win32_args{INSTALL_LIB} ) { $win32_args{INSTALL_LIB} = win32_fix_path($win32_args{INSTALL_LIB}); unless ( -d $win32_args{INSTALL_LIB}) { my @dirs = grep {-d} ('\Program Files\Apache Group\Apache\libexec', '\Apache\libexec', '\Program Files\Apache\libexec'); $win32_args{INSTALL_LIB} = find_dir(\@dirs, 'Apache/libexec'); if ($win32_args{INSTALL_LIB} and -d $win32_args{INSTALL_LIB}) { $win32_args{INSTALL_LIB} = win32_fix_path($win32_args{INSTALL_LIB}); } else { print <<'END'; **** The Apache/libexec directory was not found. ******* **** Please install mod_perl.lib manually. ******* END } } } } # fix mod_perl.dsp with the perl and apache inc and lib directories sub win32_fix_dsp { my $amp = 'src/modules/win32'; my $dsp = 'mod_perl.dsp'; unless ( -f "$amp/$dsp.orig") { rename("$amp/$dsp", "$amp/$dsp.orig") or die "Couldn't rename $amp/$dsp: $!\n"; } my $perl_inc = win32_fix_path_dsp("$Config{archlibexp}/CORE"); open(OLDDSP, "$amp/$dsp.orig") or die "Couldn't read $amp/$dsp.orig: $!\n"; open(NEWDSP, ">$amp/$dsp") or die "Couldn't create $amp/$dsp: $!\n"; while () { if (/^SOURCE=.*ApacheCore\.lib/) { printf NEWDSP "SOURCE=%s\n", win32_fix_path_dsp("$win32_path{APACHE_LIB}/ApacheCore.lib"); } elsif (/^SOURCE=.*perl(56)?\.lib/) { print NEWDSP qq{SOURCE=$perl_inc\\$Config{libperl}\n}; } elsif (/ADD CPP/) { my $apache_inc = win32_fix_path_dsp($win32_path{APACHE_INC}); s!/I "\\Perl\\lib\\CORE"!/I "$apache_inc" /I "$apache_inc/../os/win32" /I "$perl_inc"!; s!(/D "WIN32")!$1 /D "EAPI" ! if $win32_args{EAPI}; print NEWDSP $_; } else { print NEWDSP $_; } } close OLDDSP; close NEWDSP; return; } # find a directory of type $type, given some possible $dirs sub find_dir { my ($dirs, $type) = @_; my $j = 0; my $src; while (1) { $src = @$dirs > 0 ? $dirs->[$j] : ''; $src = prompt("\nWhere is your $type directory? (q to quit)", $src); return undef if $src eq 'q'; return $src if -d $src; print qq{'$src': no such directory\n}; $j = ($j == @$dirs-1) ? 0 : $j + 1; } } # fix a path for Win32 Makefile sub win32_fix_path { my $path = shift; $path = File::Spec->rel2abs($path) if not File::Spec->file_name_is_absolute($path); $path = Win32::GetShortPathName($path) if $path =~ / /; $path =~ tr!\\!/!; $path =~ s!/$!!; return $path; } # fix a path for mod_perl.dsp sub win32_fix_path_dsp { local $_ = shift; tr!/!\\!; return $_; } #in version 1.2505 of Embed.pm we could just import these instead of using ``, #but it might require lots of people to upgrade sub ccopts { unless ($Embed::ccopts) { $Embed::ccopts = "$Config{ccflags} -I$Config{archlibexp}/CORE"; if($USE_THREADS) { $Embed::ccopts .= " -DPERL_THREADS"; } } $Embed::ccopts; } sub ldopts { $Embed::ldopts ||= `$^X -MExtUtils::Embed -e ldopts`; if($^O eq "aix") { $Embed::ldopts =~ s,(-bE:)(perl\.exp),$1$Config{archlibexp}/$2,; } $Embed::ldopts; } sub perl_version { my $v = "$]"; $v =~ s/\.//g; $v .= "0" while length($v) < 6; $v; } #for linking third-party xs modules static built w/ MakeMaker's: 'make static' #must have when the xs module is compiled with profiling `-pg -a' flags sub add_static_ar { $PERL_STATIC_AR ||= ""; my $cur = $APACHE_SRC =~ /^../ ? "$PWD/" : ""; for (qw(blib/arch/auto arch/auto)) { last if -d ($ar_dir = "$APACHE_SRC/modules/perl/$_"); $ar_dir = ""; } return unless -d $ar_dir; finddepth(sub { return unless /^[A-Z]\w+\.a$/; (my $rel = $File::Find::dir) =~ s:$APACHE_SRC/?::; (my $mod = $rel) =~ s:.*auto/::; $mod =~ s,/,::,; print "linking static $mod => $rel/$_\n"; $PERL_STATIC_AR .= $cur . "$File::Find::dir/$_ "; $PERL_STATIC_EXTS .= "$mod "; }, $ar_dir); } sub APACI::init { return undef if $Is_Win32; my $lib_cfg; if($USE_APXS) { $lib_cfg = "apaci/mod_perl.config"; chmod 0644, $lib_cfg; } elsif($USE_APACI) { $lib_cfg = "$APACHE_SRC/modules/perl/mod_perl.config"; } else { return undef; } unless (File::Compare::compare($lib_cfg,"apaci/mod_perl.config") == 0) { #warn "mod_perl.config already edited\n"; #return undef; } my $apaci_cfg = FileHandle->new(">$lib_cfg") or die "can't open $lib_cfg $!"; my @static_src = (); for (@xs_mod_snames) { push @static_src, "$_.c"; } add_static_ar(); my $static_targets = ""; $static_targets = <= 5.006 ? 'A' : 'D'; phat_warn(<; } my $suggest = @maybe ? "You could just symlink it to $maybe[0]" : "You might need to install Perl from source"; phat_warn(<= 5.006 and $Config{uselargefiles} and $PERL_USELARGEFILES and $USE_APXS; local $Apache::src::APXS = $WITH_APXS; my $cflags = Apache::src->new->apxs('-q' => 'CFLAGS') || ''; return if $cflags =~ /LARGEFILE/; $PERL_USELARGEFILES=0; #just do it since return; #nobody seems to listen to the warning below phat_warn(<refCnt = 1; mp->next = modList; modList = mp; - if (loadbind(0, mainModule, mp->entry) == -1) { + /* + * Assume anonymous exports come from the module this dlopen + * is linked into, that holds true as long as dlopen and all + * of the perl core are in the same shared object. Also bind + * against the main part, in the case a perl is not the main + * part, e.g mod_perl as DSO in Apache so perl modules can + * also reference Apache symbols. + */ + if (loadbind(0, (void *)dlopen, mp->entry) == -1 || + loadbind(0, mainModule, mp->entry) == -1) { dlclose(mp); errvalid++; strcpy(errbuf, "loadbind: "); @@ -336,12 +343,6 @@ safefree(mp->name); safefree(mp); return result; -} - -static void terminate(void) -{ - while (modList) - dlclose(modList); } /* Added by Wayne Scott EOF } sub shrplib_check { return unless $Config{'useshrplib'} and $Config{'useshrplib'} eq 'define'; my $libperl = $Config{'libperl'} || 'libperl.so'; for my $dir (qw(/lib /usr/lib /usr/local/lib)) { next unless -e "$dir/$libperl"; my $coredir = "$Config{'archlibexp'}/CORE"; my $corelib = "$coredir/$libperl"; phat_warn(<