home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / Build.pm < prev    next >
Encoding:
Perl POD Document  |  2004-08-22  |  49.6 KB  |  2,020 lines

  1. # Copyright 2000-2004 The Apache Software Foundation
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. #     http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. #
  15. package Apache::Build;
  16.  
  17. use 5.006;
  18. use strict;
  19. use warnings;
  20.  
  21. use Config;
  22. use Cwd ();
  23. use File::Spec::Functions qw(catfile catdir canonpath rel2abs devnull);
  24. use File::Basename;
  25. use ExtUtils::Embed ();
  26.  
  27. use constant IS_MOD_PERL_BUILD => grep { -e "$_/lib/mod_perl.pm" } qw(. ..);
  28.  
  29. use constant AIX    => $^O eq 'aix';
  30. use constant DARWIN => $^O eq 'darwin';
  31. use constant HPUX   => $^O eq 'hpux';
  32. use constant OPENBSD => $^O eq 'openbsd';
  33. use constant WIN32  => $^O eq 'MSWin32';
  34.  
  35. use constant MSVC => WIN32() && ($Config{cc} eq 'cl');
  36.  
  37. use constant REQUIRE_ITHREADS => grep { $^O eq $_ } qw(MSWin32);
  38. use constant PERL_HAS_ITHREADS =>
  39.     $Config{useithreads} && ($Config{useithreads} eq 'define');
  40. use constant BUILD_APREXT => WIN32();
  41.  
  42. use ModPerl::Code ();
  43. use ModPerl::BuildOptions ();
  44. use Apache::TestTrace;
  45. use Apache::TestConfig ();
  46.  
  47. our $VERSION = '0.01';
  48. our $AUTOLOAD;
  49.  
  50. sub AUTOLOAD {
  51.     my $self = shift;
  52.     my $name = uc ((split '::', $AUTOLOAD)[-1]);
  53.     unless ($name =~ /^MP_/) {
  54.         die "no such method: $AUTOLOAD";
  55.     }
  56.     unless ($self->{$name}) {
  57.         return wantarray ? () : undef;
  58.     }
  59.     return wantarray ? (split /\s+/, $self->{$name}) : $self->{$name};
  60. }
  61.  
  62. #--- apxs stuff ---
  63.  
  64. our $APXS;
  65.  
  66. my %apxs_query = (
  67.     INCLUDEDIR => 'include',
  68.     LIBEXECDIR => 'modules',
  69.     CFLAGS     => undef,
  70.     PREFIX     => '',
  71. );
  72.  
  73. sub ap_prefix_invalid {
  74.     my $self = shift;
  75.  
  76.     my $prefix = $self->{MP_AP_PREFIX};
  77.  
  78.     unless (-d $prefix) {
  79.         return "$prefix: No such file or directory";
  80.     }
  81.  
  82.     my $include_dir = $self->apxs(-q => 'INCLUDEDIR');
  83.  
  84.     unless (-d $include_dir) {
  85.         return "include/ directory not found in $prefix";
  86.     }
  87.  
  88.     return '';
  89. }
  90.  
  91. sub httpd_is_source_tree {
  92.     my $self = shift;
  93.  
  94.     return $self->{httpd_is_source_tree}
  95.         if exists $self->{httpd_is_source_tree};
  96.  
  97.     my $prefix = $self->dir;
  98.     $self->{httpd_is_source_tree} = 
  99.         defined $prefix && -d $prefix && -e "$prefix/CHANGES";
  100. }
  101.  
  102. # try to find the apxs utility, set $apxs to the path if found,
  103. # otherwise to ''
  104. my $apxs; # undef so we know we haven't tried to set it yet
  105. sub find_apxs_util {
  106.     my $self = shift;
  107.  
  108.     $apxs = ''; # not found
  109.  
  110.     my @trys = ($Apache::Build::APXS,
  111.                 $self->{MP_APXS},
  112.                 $ENV{MP_APXS},
  113.                 catfile $self->{MP_AP_PREFIX}, 'bin', 'apxs');
  114.  
  115.     if (WIN32) {
  116.         my $ext = '.bat';
  117.         for (@trys) {
  118.             $_ .= $ext if ($_ and $_ !~ /$ext$/);
  119.         }
  120.     }
  121.  
  122.     unless (IS_MOD_PERL_BUILD) {
  123.         #if we are building mod_perl via apxs, apxs should already be known
  124.         #these extra tries are for things built outside of mod_perl
  125.         #e.g. libapreq
  126.         # XXX: this may pick a wrong apxs version!
  127.         push @trys,
  128.         Apache::TestConfig::which('apxs'),
  129.         '/usr/local/apache/bin/apxs';
  130.     }
  131.  
  132.     my $apxs_try;
  133.     for (@trys) {
  134.         next unless ($apxs_try = $_);
  135.         chomp $apxs_try;
  136.         if (-x $apxs_try) {
  137.             $apxs = $apxs_try;
  138.             last;
  139.         }
  140.     }
  141. }
  142.  
  143. sub apxs {
  144.     my $self = shift;
  145.  
  146.     $self->find_apxs_util() unless defined $apxs;
  147.  
  148.     my $is_query = (@_ == 2) && ($_[0] eq '-q');
  149.  
  150.     $self = $self->build_config unless ref $self;
  151.  
  152.     my $query_key;
  153.     if ($is_query) {
  154.         $query_key = 'APXS_' . uc $_[1];
  155.         if ($self->{$query_key}) {
  156.             return $self->{$query_key};
  157.         }
  158.     }
  159.  
  160.     unless ($apxs) {
  161.         my $prefix = $self->{MP_AP_PREFIX} || "";
  162.         return '' unless -d $prefix and $is_query;
  163.         my $val = $apxs_query{$_[1]};
  164.         return defined $val ? ($val ? "$prefix/$val" : $prefix) : "";
  165.     }
  166.  
  167.     my $devnull = devnull();
  168.     my $val = qx($apxs @_ 2>$devnull);
  169.     chomp $val if defined $val;
  170.  
  171.     unless ($val) {
  172.         # do we have an error or is it just an empty value?
  173.         my $error = qx($apxs @_ 2>&1);
  174.         chomp $error if defined $error;
  175.         if ($error) {
  176.             error "'$apxs @_' failed:";
  177.             error $error;
  178.         }
  179.         else {
  180.             $val = '';
  181.         }
  182.     }
  183.  
  184.     $self->{$query_key} = $val;
  185. }
  186.  
  187. sub apxs_cflags {
  188.     my $cflags = __PACKAGE__->apxs('-q' => 'CFLAGS');
  189.     $cflags =~ s/\"/\\\"/g;
  190.     $cflags;
  191. }
  192.  
  193. sub apxs_extra_cflags {
  194.     my $flags = __PACKAGE__->apxs('-q' => 'EXTRA_CFLAGS');
  195.     $flags =~ s/\"/\\\"/g;
  196.     $flags;
  197. }
  198.  
  199. sub apxs_extra_cppflags {
  200.     my $flags = __PACKAGE__->apxs('-q' => 'EXTRA_CPPFLAGS');
  201.     $flags =~ s/\"/\\\"/g;
  202.     $flags;
  203. }
  204.  
  205. my %threaded_mpms = map { $_ => 1}
  206.         qw(worker winnt beos mpmt_os2 netware leader perchild threadpool);
  207. sub mpm_is_threaded {
  208.     my $self = shift;
  209.     my $mpm_name = $self->mpm_name();
  210.     return $threaded_mpms{$mpm_name};
  211. }
  212.  
  213. sub mpm_name {
  214.     my $self = shift;
  215.  
  216.     return $self->{mpm_name} if $self->{mpm_name};
  217.  
  218.     # XXX: hopefully apxs will work on win32 one day
  219.     return $self->{mpm_name} = 'winnt' if WIN32;
  220.  
  221.     my $mpm_name = $self->apxs('-q' => 'MPM_NAME');
  222.  
  223.     # building against the httpd source dir
  224.     unless ($mpm_name and $self->httpd_is_source_tree) {
  225.         my $config_vars_file = catfile $self->dir, "build", "config_vars.mk";
  226.         if (open my $fh, $config_vars_file) {
  227.             while (<$fh>) {
  228.                 if (/MPM_NAME = (\w+)/) {
  229.                     $mpm_name = $1;
  230.                     last;
  231.                 }
  232.             }
  233.             close $fh;
  234.         }
  235.     }
  236.  
  237.     unless ($mpm_name) {
  238.         my $msg = 'Failed to obtain the MPM name.';
  239.         $msg .= " Please specify MP_APXS=/full/path/to/apxs to solve " .
  240.             "this problem." unless exists $self->{MP_APXS};
  241.         error $msg;
  242.         exit 1;
  243.     }
  244.  
  245.     return $self->{mpm_name} = $mpm_name;
  246. }
  247.  
  248. sub should_build_apache {
  249.     my ($self) = @_;
  250.     return $self->{MP_AP_BUILD} ? 1 : 0;
  251. }
  252.  
  253. sub configure_apache {
  254.     my ($self) = @_;
  255.  
  256.     unless ($self->{MP_AP_CONFIGURE}) {
  257.         error "You specified MP_AP_BUILD but did not specify the " .
  258.               "arguments to httpd's ./configure with MP_AP_CONFIGURE";
  259.         exit 1;
  260.     }
  261.     
  262.     unless ($self->{MP_AP_PREFIX}) {
  263.         error "You specified MP_AP_BUILD but did not speficy the " .
  264.               "location of httpd's source tree with MP_AP_PREFIX"; 
  265.         exit 1;
  266.     }
  267.  
  268.     unless ($self->{MP_USE_STATIC}) {
  269.         error "When building httpd, you must set MP_USE_STATIC=1";
  270.         exit 1;
  271.     }
  272.  
  273.     debug "Configuring httpd in $self->{MP_AP_PREFIX}";
  274.     
  275.     my $httpd = File::Spec->catfile($self->{MP_AP_PREFIX}, 'httpd');
  276.     push @Apache::TestMM::Argv, ('-httpd' => $httpd);
  277.     
  278.     my $mplib = "$self->{MP_LIBNAME}$Config{lib_ext}";
  279.     my $mplibpath = catfile($self->{cwd}, qw(src modules perl), $mplib);
  280.     
  281.     local $ENV{BUILTIN_LIBS} = $mplibpath;
  282.     local $ENV{AP_LIBS} = $self->ldopts;
  283.     local $ENV{MODLIST} = 'perl';
  284.  
  285.     #XXX: -Wall and/or -Werror at httpd configure time breaks things
  286.     local $ENV{CFLAGS} = join ' ', grep { ! /\-Wall|\-Werror/ } 
  287.         split /\s+/, $ENV{CFLAGS};
  288.     
  289.     my $cd = qq(cd $self->{MP_AP_PREFIX});
  290.     my $cmd = qq(./configure $self->{MP_AP_CONFIGURE});
  291.     debug "Running $cmd";
  292.     system("$cd && $cmd") == 0 or die "httpd: $cmd failed";
  293. }
  294.  
  295. #--- Perl Config stuff ---
  296.  
  297. my %gtop_config = ();
  298. sub find_gtop {
  299.     my $self = shift;
  300.  
  301.     return %gtop_config if %gtop_config;
  302.  
  303.     if (%gtop_config = find_gtop_config()) {
  304.         return %gtop_config;
  305.     }
  306.  
  307.     if ($self->find_dlfile('gtop')) {
  308.         $gtop_config{ldopts} = $self->gtop_ldopts_old();
  309.         $gtop_config{ccopts} = '';
  310.         return %gtop_config;
  311.     }
  312.  
  313.     return ();
  314. }
  315.  
  316. sub find_gtop_config {
  317.     my %c = ();
  318.  
  319.     my $ver_2_5_plus = 0;
  320.     if (system('pkg-config --exists libgtop-2.0') == 0) {
  321.         # 2.x
  322.         chomp($c{ccopts} = qx|pkg-config --cflags libgtop-2.0|);
  323.         chomp($c{ldopts} = qx|pkg-config --libs   libgtop-2.0|);
  324.  
  325.         # 2.0.0 bugfix
  326.         chomp(my $libdir = qx|pkg-config --variable=libdir libgtop-2.0|);
  327.         $c{ldopts} =~ s|\$\(libdir\)|$libdir|;
  328.  
  329.         chomp($c{ver} = qx|pkg-config --modversion libgtop-2.0|);
  330.         ($c{ver_maj}, $c{ver_min}) = split /\./, $c{ver};
  331.         $ver_2_5_plus++ if $c{ver_maj} == 2 && $c{ver_min} >= 5;
  332.  
  333.         if ($ver_2_5_plus) {
  334.             # some headers were removed in libgtop 2.5.0 so we need to
  335.             # be able to exclude them at compile time
  336.             $c{ccopts} .= ' -DGTOP_2_5_PLUS';
  337.         }
  338.  
  339.     }
  340.     elsif (system('gnome-config --libs libgtop') == 0) {
  341.         chomp($c{ccopts} = qx|gnome-config --cflags libgtop|);
  342.         chomp($c{ldopts} = qx|gnome-config --libs   libgtop|);
  343.  
  344.         # buggy ( < 1.0.9?) versions fixup
  345.         $c{ccopts} =~ s|^/|-I/|;
  346.         $c{ldopts} =~ s|^/|-L/|;
  347.     }
  348.  
  349.     # starting from 2.5.0 'pkg-config --cflags libgtop-2.0' already
  350.     # gives us all the cflags that are needed
  351.     if ($c{ccopts} && !$ver_2_5_plus) {
  352.         chomp(my $ginc = `glib-config --cflags`);
  353.         $c{ccopts} .= " $ginc";
  354.     }
  355.  
  356.     if (%c) {
  357.         $c{ccopts} = " $c{ccopts}";
  358.         $c{ldopts} = " $c{ldopts}";
  359.     }
  360.  
  361.     return %c;
  362. }
  363.  
  364. my @Xlib = qw(/usr/X11/lib /usr/X11R6/lib);
  365.  
  366. sub gtop_ldopts_old {
  367.     my $self = shift;
  368.     my $xlibs = "";
  369.  
  370.     my($path) = $self->find_dlfile('Xau', @Xlib);
  371.     if ($path) {
  372.         $xlibs = "-L$path -lXau";
  373.     }
  374.  
  375.     if ($self->find_dlfile('intl')) {
  376.         $xlibs .= ' -lintl';
  377.     }
  378.  
  379.     return " -lgtop -lgtop_sysdeps -lgtop_common $xlibs";
  380. }
  381.  
  382. sub gtop_ldopts {
  383.     exists $gtop_config{ldopts} ? $gtop_config{ldopts} : '';
  384. }
  385.  
  386. sub gtop_ccopts {
  387.     exists $gtop_config{ccopts} ? $gtop_config{ccopts} : '';
  388. }
  389.  
  390. sub ldopts {
  391.     my($self) = @_;
  392.  
  393.     my $config = tied %Config;
  394.     my $ldflags = $config->{ldflags};
  395.  
  396.     if (WIN32) {
  397.         $config->{ldflags} = ''; #same as lddlflags
  398.     }
  399.     elsif (DARWIN) {
  400.         #not sure how this can happen, but it shouldn't
  401.         my @bogus_flags = ('flat_namespace', 'bundle', 'undefined suppress');
  402.         for my $flag (@bogus_flags) {
  403.             $config->{ldflags} =~ s/-$flag\s*//;
  404.         }
  405.     }
  406.  
  407.     my $ldopts = ExtUtils::Embed::ldopts();
  408.     chomp $ldopts;
  409.  
  410.     my $ld = $self->perl_config('ld');
  411.  
  412.     if (HPUX && $ld eq 'ld') {
  413.         while ($ldopts =~ s/-Wl,(\S+)/$1/) {
  414.             my $cp = $1;
  415.             (my $repl = $cp) =~ s/,/ /g;
  416.             $ldopts =~ s/\Q$cp/$repl/;
  417.         }
  418.     }
  419.  
  420.     if ($self->{MP_USE_GTOP}) {
  421.         $ldopts .= $self->gtop_ldopts;
  422.     }
  423.  
  424.     $config->{ldflags} = $ldflags; #reset
  425.  
  426.     $ldopts;
  427. }
  428.  
  429. my $Wall =
  430.   "-Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations";
  431.  
  432. # perl v5.6.1 and earlier produces lots of warnings, so we can't use
  433. # -Werror with those versions.
  434. $Wall .= " -Werror" if $] >= 5.006002;
  435.  
  436. sub ap_ccopts {
  437.     my($self) = @_;
  438.     my $ccopts = "-DMOD_PERL";
  439.  
  440.     if ($self->{MP_USE_GTOP}) {
  441.         $ccopts .= " -DMP_USE_GTOP";
  442.         $ccopts .= $self->gtop_ccopts;
  443.     }
  444.  
  445.     if ($self->{MP_MAINTAINER}) {
  446.         $self->{MP_DEBUG} = 1;
  447.         if ($self->perl_config('gccversion')) {
  448.             #same as --with-maintainter-mode
  449.             $ccopts .= " $Wall -DAP_DEBUG";
  450.             $ccopts .= " -DAP_HAVE_DESIGNATED_INITIALIZER";
  451.         }
  452.     }
  453.  
  454.     if ($self->{MP_COMPAT_1X}) {
  455.         $ccopts .= " -DMP_COMPAT_1X";
  456.     }
  457.  
  458.     if ($self->{MP_DEBUG}) {
  459.         $self->{MP_TRACE} = 1;
  460.         my $win32_flags = MSVC  ? '-Od -MD -Zi' : '';
  461.         my $debug_flags = WIN32 ? $win32_flags : '-g';
  462.         $ccopts .= " $debug_flags" unless $Config{optimize} =~ /$debug_flags/;
  463.         $ccopts .= ' -DMP_DEBUG';
  464.     }
  465.  
  466.     if ($self->{MP_CCOPTS}) {
  467.         $ccopts .= " $self->{MP_CCOPTS}";
  468.     }
  469.  
  470.     if ($self->{MP_TRACE}) {
  471.         $ccopts .= " -DMP_TRACE";
  472.     }
  473.  
  474.     # make sure apr.h can be safely included
  475.     # for example Perl's included -D_GNU_SOURCE implies
  476.     # -D_LARGEFILE64_SOURCE on linux, but this won't happen on
  477.     # Solaris, so we need apr flags living in apxs' EXTRA_CPPFLAGS
  478.     my $extra_cppflags = $self->apxs_extra_cppflags;
  479.     $ccopts .= " " . $extra_cppflags;
  480.  
  481.     $ccopts;
  482. }
  483.  
  484. sub perl_ccopts {
  485.     my $self = shift;
  486.  
  487.     my $cflags = $self->strip_lfs(" $Config{ccflags} ");
  488.  
  489.     my $fixup = \&{"ccopts_$^O"};
  490.     if (defined &$fixup) {
  491.         $fixup->(\$cflags);
  492.     }
  493.  
  494.     if (WIN32 and $self->{MP_DEBUG}) {
  495.         #only win32 has -DDEBUGGING in both optimize and ccflags
  496.         my $optim = $Config{optimize};
  497.  
  498.         unless ($optim =~ /-DDEBUGGING/) {
  499.             $cflags =~ s/$optim//;
  500.        }
  501.     }
  502.  
  503.     $cflags;
  504. }
  505.  
  506. sub ccopts_hpux {
  507.     my $cflags = shift;
  508.     return if $Config{cc} eq 'gcc'; #XXX?
  509.     return if $$cflags =~ /(-Ae|\+e)/;
  510.     $$cflags .= " -Ae ";
  511. }
  512.  
  513. # XXX: there could be more, but this is just for cosmetics
  514. my %cflags_dups = map { $_ => 1 } qw(-D_GNU_SOURCE -D_REENTRANT);
  515. sub ccopts {
  516.     my($self) = @_;
  517.  
  518.     my $cflags = $self->perl_ccopts . ExtUtils::Embed::perl_inc() .
  519.                  $self->ap_ccopts;
  520.  
  521.     # remove duplicates of certain cflags coming from perl and ap/apr
  522.     my @cflags = ();
  523.     my %dups    = ();
  524.     for (split /\s+/, $cflags) {
  525.         if ($cflags_dups{$_}) {
  526.             next if $dups{$_};
  527.             $dups{$_}++;
  528.         }
  529.         push @cflags, $_;
  530.     }
  531.     $cflags = "@cflags";
  532.  
  533.     $cflags;
  534. }
  535.  
  536. sub ldopts_prefix {
  537.     my $self = shift;
  538.     $self->perl_config('ld') eq 'ld' ? '' : "-Wl,";
  539. }
  540.  
  541. sub perl_config_optimize {
  542.     my($self, $val) = @_;
  543.  
  544.     $val ||= $Config{optimize};
  545.  
  546.     if ($self->{MP_DEBUG}) {
  547.         return ' ' unless $Config{ccflags} =~ /-DDEBUGGING/;
  548.     }
  549.  
  550.     $val;
  551. }
  552.  
  553. sub perl_config_ld {
  554.     my($self, $val) = @_;
  555.  
  556.     $val ||= $Config{ld};
  557.  
  558.     basename $val; #bleedperl hpux value is /usr/bin/ld !
  559. }
  560.  
  561. sub perl_config_lddlflags {
  562.     my($self, $val) = @_;
  563.  
  564.     if ($self->{MP_DEBUG}) {
  565.         if (MSVC) {
  566.             unless ($val =~ s/-release/-debug/) {
  567.                 $val .= ' -debug';
  568.             }
  569.         }
  570.     }
  571.  
  572.     if (AIX) {
  573.         my $Wl = $self->ldopts_prefix;
  574.  
  575.         # it's useless to import symbols from libperl.so this way,
  576.         # because perl.exp is incomplete. a better way is to link
  577.         # against -lperl which has all the symbols
  578.         $val =~ s|${Wl}-bI:\$\(PERL_INC\)/perl\.exp||;
  579.         # also in the case of Makefile.modperl PERL_INC is defined
  580.  
  581.         # this works with at least ld(1) on powerpc-ibm-aix5.1.0.0:
  582.         # -berok ignores symbols resolution problems (they will be
  583.         #        resolved at run-time
  584.         # -brtl prepares the object for run-time loading
  585.         # LDFLAGS already inserts -brtl
  586.         $val .= " ${Wl}-berok";
  587.         # XXX: instead of -berok, could make sure that we have:
  588.         #   -Lpath/to/CORE -lperl
  589.         #   -bI:$path/apr.exp -bI:$path/aprutil.exp -bI:$path/httpd.exp
  590.         #   -bI:$path/modperl_*.exp 
  591.         # - don't import modperl_*.exp in Makefile.modperl which
  592.         #   exports -bE:$path/modperl_*.exp
  593.         # - can't rely on -bI:$path/perl.exp, because it's incomplete,
  594.         #   use -lperl instead
  595.         # - the issue with using apr/aprutil/httpd.exp is to pick the
  596.         #   right path if httpd wasn't yet installed
  597.     }
  598.  
  599.     $val;
  600. }
  601.  
  602. sub perl_config {
  603.     my($self, $key) = @_;
  604.  
  605.     my $val = $Config{$key} || '';
  606.  
  607.     my $method = \&{"perl_config_$key"};
  608.     if (defined &$method) {
  609.         return $method->($self, $val);
  610.     }
  611.  
  612.     return $val;
  613. }
  614.  
  615. sub find_in_inc {
  616.     my $name = shift;
  617.     for (@INC) {
  618.         my $file;
  619.         if (-e ($file = "$_/auto/Apache/$name")) {
  620.             return $file;
  621.         }
  622.     }
  623. }
  624.  
  625. sub libpth {
  626.     my $self = shift;
  627.     $self->{libpth} ||= [split /\s+/, $Config{libpth}];
  628.     return wantarray ? @{ $self->{libpth} } : $self->{libpth};
  629. }
  630.  
  631. sub find_dlfile {
  632.     my($self, $name) = (shift, shift);
  633.  
  634.     require DynaLoader;
  635.     require AutoLoader; #eek
  636.  
  637.     my $found = 0;
  638.     my $loc = "";
  639.     my(@path) = ($self->libpth, @_);
  640.  
  641.     for (@path) {
  642.         if ($found = DynaLoader::dl_findfile($_, "-l$name")) {
  643.             $loc = $_;
  644.             last;
  645.         }
  646.     }
  647.  
  648.     return wantarray ? ($loc, $found) : $found;
  649. }
  650.  
  651. sub find_dlfile_maybe {
  652.     my($self, $name) = @_;
  653.  
  654.     my $path = $self->libpth;
  655.  
  656.     my @maybe;
  657.     my $lib = 'lib' . $name;
  658.  
  659.     for (@$path) {
  660.         push @maybe, grep { ! -l $_ } <$_/$lib.*>;
  661.     }
  662.  
  663.     return \@maybe;
  664. }
  665.  
  666. sub lib_check {
  667.     my($self, $name) = @_;
  668.     return unless $self->perl_config('libs') =~ /$name/;
  669.  
  670.     return if $self->find_dlfile($name);
  671.  
  672.     my $maybe = $self->find_dlfile_maybe($name);
  673.     my $suggest = @$maybe ? 
  674.         "You could just symlink it to $maybe->[0]" :
  675.         'You might need to install Perl from source';
  676.     $self->phat_warn(<<EOF);
  677. Your Perl is configured to link against lib$name,
  678.   but lib$name.so was not found.
  679.   $suggest
  680. EOF
  681. }
  682.  
  683. #--- user interaction ---
  684.  
  685. sub prompt {
  686.     my($self, $q, $default) = @_;
  687.     return $default if $self->{MP_PROMPT_DEFAULT};
  688.     require ExtUtils::MakeMaker;
  689.     ExtUtils::MakeMaker::prompt($q, $default);
  690. }
  691.  
  692. sub prompt_y {
  693.     my($self, $q) = @_;
  694.     $self->prompt($q, 'y') =~ /^y/i;
  695. }
  696.  
  697. sub prompt_n {
  698.     my($self, $q) = @_;
  699.     $self->prompt($q, 'n') =~ /^n/i;
  700. }
  701.  
  702. sub phat_warn {
  703.     my($self, $msg, $abort) = @_;
  704.     my $level = $abort ? 'ERROR' : 'WARNING';
  705.     warn <<EOF;
  706. ************* $level *************
  707.  
  708.   $msg
  709.  
  710. ************* $level *************
  711. EOF
  712.     if ($abort) {
  713.         exit 1;
  714.     }
  715.     else {
  716.         sleep 5;
  717.     }
  718. }
  719.  
  720. #--- constructors ---
  721.  
  722. my $bpm = 'Apache/BuildConfig.pm';
  723.  
  724. sub build_config {
  725.     my $self = shift;
  726.     my $bpm_mtime = 0;
  727.  
  728.     $bpm_mtime = (stat $INC{$bpm})[9] if $INC{$bpm};
  729.  
  730.     if (-e "lib/$bpm" and (stat _)[9] > $bpm_mtime) {
  731.         #reload if Makefile.PL has regenerated
  732.         unshift @INC, 'lib';
  733.         delete $INC{$bpm};
  734.         eval { require Apache::BuildConfig; };
  735.         shift @INC;
  736.     }
  737.     else {
  738.         eval { require Apache::BuildConfig; };
  739.     }
  740.  
  741.     return bless {}, (ref($self) || $self) if $@;
  742.     return Apache::BuildConfig::->new;
  743. }
  744.  
  745. sub new {
  746.     my $class = shift;
  747.  
  748.     my $self = bless {
  749.         cwd => Cwd::fastcwd(),
  750.         MP_LIBNAME => 'mod_perl',
  751.         @_,
  752.     }, $class;
  753.  
  754.     $self->{MP_APR_LIB} = 'aprext';
  755.  
  756.     ModPerl::BuildOptions->init($self) if delete $self->{init};
  757.  
  758.     $self;
  759. }
  760.  
  761. sub DESTROY {}
  762.  
  763. my %default_files = (
  764.     'build_config' => 'lib/Apache/BuildConfig.pm',
  765.     'ldopts' => 'src/modules/perl/ldopts',
  766.     'makefile' => 'src/modules/perl/Makefile.modperl',
  767. );
  768.  
  769. sub clean_files {
  770.     my $self = shift;
  771.     [map { $self->default_file($_) } keys %default_files];
  772. }
  773.  
  774. sub default_file {
  775.     my($self, $name, $override) = @_;
  776.     my $key = join '_', 'file', $name;
  777.     $self->{$key} ||= ($override || $default_files{$name});
  778. }
  779.  
  780. sub file_path {
  781.     my $self = shift;
  782.     my @files = map { m:^/: ? $_ : join('/', $self->{cwd}, $_) } @_;
  783.     return wantarray ? @files : $files[0];
  784. }
  785.  
  786. sub freeze {
  787.     require Data::Dumper;
  788.     local $Data::Dumper::Terse = 1;
  789.     my $data = Data::Dumper::Dumper(shift);
  790.     chomp $data;
  791.     $data;
  792. }
  793.  
  794. sub save_ldopts {
  795.     my($self, $file) = @_;
  796.  
  797.     $file ||= $self->default_file('ldopts', $file);
  798.     my $ldopts = $self->ldopts;
  799.  
  800.     open my $fh, '>', $file or die "open $file: $!";
  801.     print $fh "#!/bin/sh\n\necho $ldopts\n";
  802.     close $fh;
  803.     chmod 0755, $file;
  804. }
  805.  
  806. sub noedit_warning_hash {
  807.     ModPerl::Code::noedit_warning_hash(__PACKAGE__);
  808. }
  809.  
  810. sub save {
  811.     my($self, $file) = @_;
  812.  
  813.     delete $INC{$bpm};
  814.  
  815.     $file ||= $self->default_file('build_config');
  816.     $file = $self->file_path($file);
  817.  
  818.     (my $obj = $self->freeze) =~ s/^/    /;
  819.     open my $fh, '>', $file or die "open $file: $!";
  820.  
  821.     #work around autosplit braindeadness
  822.     my $package = 'package Apache::BuildConfig';
  823.  
  824.     print $fh noedit_warning_hash();
  825.  
  826.     print $fh <<EOF;
  827. $package;
  828.  
  829. use Apache::Build ();
  830.  
  831. sub new {
  832. $obj;
  833. }
  834.  
  835. 1;
  836. EOF
  837.  
  838.     close $fh or die "failed to write $file: $!";
  839. }
  840.  
  841. sub rebuild {
  842.     my $self = __PACKAGE__->build_config;
  843.     my @opts = map { qq[$_='$self->{$_}'] } sort grep /^MP_/,  keys %$self;
  844.     my $command = "perl Makefile.PL @opts";
  845.     print "Running: $command\n";
  846.     system $command;
  847. }
  848. # % perl -MApache::Build -e rebuild
  849. *main::rebuild = \&rebuild if $0 eq '-e';
  850.  
  851. #--- attribute access ---
  852.  
  853. sub is_dynamic { shift->{MP_USE_DSO} }
  854.  
  855. sub default_dir {
  856.     my $build = shift->build_config;
  857.  
  858.     return $build->dir || '../apache_x.x/src';
  859. }
  860.  
  861. sub dir {
  862.     my($self, $dir) = @_;
  863.  
  864.     if ($dir) {
  865.         for (qw(ap_includedir)) {
  866.             delete $self->{$_};
  867.         }
  868.         if ($dir =~ m:^../:) {
  869.             $dir = "$self->{cwd}/$dir";
  870.         }
  871.         $self->{dir} = $dir;
  872.     }
  873.  
  874.     return $self->{dir} if $self->{dir};
  875.  
  876.     if (IS_MOD_PERL_BUILD) {
  877.         my $build = $self->build_config;
  878.  
  879.         if ($dir = $build->{'dir'}) {
  880.             for ($dir, "../$dir", "../../$dir") {
  881.                 last if -d ($dir = $_);
  882.             }
  883.         }
  884.     }
  885.  
  886.     $dir ||= $self->{MP_AP_PREFIX};
  887.  
  888. # we no longer install Apache headers, so don't bother looking in @INC
  889. # might end up finding 1.x headers anyhow
  890. #    unless ($dir and -d $dir) {
  891. #        for (@INC) {
  892. #            last if -d ($dir = "$_/auto/Apache/include");
  893. #        }
  894. #    }
  895.     return $self->{dir} = $dir ? canonpath(rel2abs $dir) : undef;
  896. }
  897.  
  898. #--- finding apache *.h files ---
  899.  
  900. sub find {
  901.     my $self = shift;
  902.     my %seen = ();
  903.     my @dirs = ();
  904.  
  905.     for my $src_dir ($self->dir,
  906.                      $self->default_dir,
  907.                      '../httpd-2.0')
  908.       {
  909.           next unless $src_dir;
  910.           next unless (-d $src_dir || -l $src_dir);
  911.           next if $seen{$src_dir}++;
  912.           push @dirs, $src_dir;
  913.           #$modified{$src_dir} = (stat($src_dir))[9];
  914.       }
  915.  
  916.     return @dirs;
  917. }
  918.  
  919. sub ap_includedir  {
  920.     my($self, $d) = @_;
  921.  
  922.     return $self->{ap_includedir}
  923.       if $self->{ap_includedir} and -d $self->{ap_includedir};
  924.  
  925.     return unless $d ||= $self->apxs('-q' => 'INCLUDEDIR') || $self->dir;
  926.  
  927.     if (-e "$d/include/ap_release.h") {
  928.         return $self->{ap_includedir} = "$d/include";
  929.     }
  930.  
  931.     $self->{ap_includedir} = $d;
  932. }
  933.  
  934. # where apr-config and apu-config reside
  935. sub apr_bindir {
  936.     my ($self) = @_;
  937.  
  938.     $self->apr_config_path unless $self->{apr_bindir};
  939.     $self->{apr_bindir};
  940. }
  941.  
  942. sub apr_generation {
  943.     my($self) = @_;
  944.     return $self->httpd_version_as_int =~ m/21\d+/ ? 1 : 0;
  945. }
  946.  
  947. # returns an array of apr/apu linking flags (--link-ld --libs) if found
  948. # an empty array otherwise
  949. my @apru_link_flags = ();
  950. sub apru_link_flags {
  951.     my($self) = @_;
  952.  
  953.     return @apru_link_flags if @apru_link_flags;
  954.  
  955.     for ($self->apr_config_path, $self->apu_config_path) {
  956.         if (my $link = $_ && -x $_ && qx{$_ --link-ld --libs}) {
  957.             chomp $link;
  958.             push @apru_link_flags, $link;
  959.         }
  960.     }
  961.  
  962.     return @apru_link_flags;
  963. }
  964.  
  965. sub apr_config_path {
  966.     shift->apru_config_path("apr");
  967. }
  968.  
  969. sub apu_config_path {
  970.     shift->apru_config_path("apu");
  971. }
  972.  
  973. sub apru_config_path {
  974.     my ($self, $what) = @_;
  975.  
  976.     my $key = "${what}_config_path"; # apr_config_path
  977.     my $mp_key = "MP_" . uc($what) . "_CONFIG"; # MP_APR_CONFIG
  978.  
  979.     return $self->{$key} if $self->{$key} and -x $self->{$key};
  980.  
  981.     if (exists $self->{$mp_key} and -x $self->{$mp_key}) {
  982.         $self->{$key} = $self->{$mp_key};
  983.     }
  984.  
  985.     my $config = $self->apr_generation ? "$what-1-config" : "$what-config";
  986.  
  987.     if (!$self->{$key}) {
  988.         my @tries = ();
  989.         if ($self->httpd_is_source_tree) {
  990.             push @tries, grep { -d $_ }
  991.                 map catdir($_, "srclib", "apr"),
  992.                 grep defined $_, $self->dir;
  993.         }
  994.         else {
  995.             push @tries, grep length,
  996.                 map $self->apxs(-q => $_), qw(APR_BINDIR BINDIR);
  997.             push @tries, catdir $self->{MP_AP_PREFIX}, "bin"
  998.                 if exists $self->{MP_AP_PREFIX} and -d $self->{MP_AP_PREFIX};
  999.         }
  1000.  
  1001.         @tries = map { catfile $_, $config } @tries;
  1002.         if (WIN32) {
  1003.             my $ext = '.bat';
  1004.             for (@tries) {
  1005.                 $_ .= $ext if ($_ and $_ !~ /$ext$/);
  1006.             }
  1007.         }
  1008.  
  1009.         for my $try (@tries) {
  1010.             next unless -x $try;
  1011.             $self->{$key} = $try;
  1012.         }
  1013.     }
  1014.  
  1015.     $self->{$key} ||= Apache::TestConfig::which($config);
  1016.  
  1017.     # apr_bindir makes sense only if httpd/apr is installed, if we are
  1018.     # building against the source tree we can't link against
  1019.     # apr/aprutil libs
  1020.     unless ($self->httpd_is_source_tree) {
  1021.         $self->{apr_bindir} = $self->{$key}
  1022.             ? dirname $self->{$key}
  1023.             : '';
  1024.         }
  1025.  
  1026.     $self->{$key};
  1027. }
  1028.  
  1029. sub apr_includedir {
  1030.     my ($self) = @_;
  1031.  
  1032.     return $self->{apr_includedir}
  1033.         if $self->{apr_includedir} and -d $self->{apr_includedir};
  1034.  
  1035.     my $incdir;
  1036.     my $apr_config_path = $self->apr_config_path;
  1037.  
  1038.     if ($apr_config_path) {
  1039.         my $httpd_version = $self->httpd_version;
  1040.         chomp($incdir = `$apr_config_path --includedir`);
  1041.     }
  1042.  
  1043.     unless ($incdir and -d $incdir) {
  1044.         # falling back to the default when apr header files are in the
  1045.         # same location as the httpd header files
  1046.         $incdir = $self->ap_includedir;
  1047.     }
  1048.  
  1049.     my @tries = ($incdir);
  1050.     if ($self->httpd_is_source_tree) {
  1051.         my $path = catdir $self->dir, "srclib", "apr", "include";
  1052.         push @tries, $path if -d $path;
  1053.     }
  1054.  
  1055.     for (@tries) {
  1056.         next unless $_ && -e catfile $_, "apr.h";
  1057.         $self->{apr_includedir} = $_;
  1058.         last;
  1059.     }
  1060.  
  1061.     unless ($self->{apr_includedir}) {
  1062.         error "Can't find apr include/ directory,",
  1063.             "use MP_APR_CONFIG=/path/to/apr-config";
  1064.         exit 1;
  1065.     }
  1066.  
  1067.     $self->{apr_includedir};
  1068. }
  1069.  
  1070. #--- parsing apache *.h files ---
  1071.  
  1072. sub mmn_eq {
  1073.     my($class, $dir) = @_;
  1074.  
  1075.     return 1 if WIN32; #just assume, till Apache::Build works under win32
  1076.  
  1077.     my $instsrc;
  1078.     {
  1079.         local @INC = grep { !/blib/ } @INC;
  1080.         my $instdir;
  1081.         for (@INC) { 
  1082.             last if -d ($instdir = "$_/auto/Apache/include");
  1083.         }
  1084.         $instsrc = $class->new(dir => $instdir);
  1085.     }
  1086.     my $targsrc = $class->new($dir ? (dir => $dir) : ());
  1087.  
  1088.     my $inst_mmn = $instsrc->module_magic_number;
  1089.     my $targ_mmn = $targsrc->module_magic_number;
  1090.  
  1091.     unless ($inst_mmn && $targ_mmn) {
  1092.         return 0;
  1093.     }
  1094.     if ($inst_mmn == $targ_mmn) {
  1095.         return 1;
  1096.     }
  1097.     print "Installed MMN $inst_mmn does not match target $targ_mmn\n";
  1098.  
  1099.     return 0;
  1100. }
  1101.  
  1102. sub module_magic_number {
  1103.     my $self = shift;
  1104.  
  1105.     return $self->{mmn} if $self->{mmn};
  1106.  
  1107.     my $d = $self->ap_includedir;
  1108.  
  1109.     return 0 unless $d;
  1110.  
  1111.     #return $mcache{$d} if $mcache{$d};
  1112.     my $fh;
  1113.     for (qw(ap_mmn.h http_config.h)) {
  1114.         last if open $fh, "$d/$_";
  1115.     }
  1116.     return 0 unless $fh;
  1117.  
  1118.     my $n;
  1119.     my $mmn_pat = join '|', qw(MODULE_MAGIC_NUMBER_MAJOR MODULE_MAGIC_NUMBER);
  1120.     while(<$fh>) {
  1121.         if(s/^\#define\s+($mmn_pat)\s+(\d+).*/$2/) {
  1122.            chomp($n = $_);
  1123.            last;
  1124.        }
  1125.     }
  1126.     close $fh;
  1127.  
  1128.     $self->{mmn} = $n
  1129. }
  1130.  
  1131. sub fold_dots {
  1132.     my $v = shift;
  1133.     $v =~ s/\.//g;
  1134.     $v .= '0' if length $v < 3;
  1135.     $v;
  1136. }
  1137.  
  1138. sub httpd_version_as_int {
  1139.     my($self, $dir) = @_;
  1140.     my $v = $self->httpd_version($dir);
  1141.     fold_dots($v);
  1142. }
  1143.  
  1144. sub httpd_version_cache {
  1145.     my($self, $dir, $v) = @_;
  1146.     return '' unless $dir;
  1147.     $self->{httpd_version}->{$dir} = $v if $v;
  1148.     $self->{httpd_version}->{$dir};
  1149. }
  1150.  
  1151. sub httpd_version {
  1152.     my($self, $dir) = @_;
  1153.  
  1154.     return unless $dir = $self->ap_includedir($dir);
  1155.  
  1156.     if (my $v = $self->httpd_version_cache($dir)) {
  1157.         return $v;
  1158.     }
  1159.  
  1160.     my $header = "$dir/ap_release.h";
  1161.     open my $fh, $header or do {
  1162.         error "Unable to open $header: $!";
  1163.         return undef;
  1164.     };
  1165.  
  1166.     my $version;
  1167.  
  1168.     while (<$fh>) {
  1169.         #now taking bets on how many friggin times this will change
  1170.         #over the course of apache 2.0.  1.3 changed it at least a half
  1171.         #dozen times.  hopefully it'll stay in the same file at least.
  1172.         if (/^\#define\s+AP_SERVER_MAJORVERSION\s+\"(\d+)\"/) {
  1173.             #XXX could be more careful here.  whatever.  see above.
  1174.             my $major = $1;
  1175.             my $minor = (split /\s+/, scalar(<$fh>))[-1];
  1176.             my $patch = (split /\s+/, scalar(<$fh>))[-1];
  1177.             $version = join '.', $major, $minor, $patch;
  1178.             $version =~ s/\"//g;
  1179.             last;
  1180.         }
  1181.         elsif (/^\#define\s+AP_SERVER_BASEREVISION\s+\"(.*)\"/) {
  1182.             $version = $1;
  1183.             last;
  1184.         }
  1185.         elsif(/^\#define\s+AP_SERVER_MAJORVERSION_NUMBER\s+(\d+)/) {
  1186.             # new 2.1 config
  1187.             my $major = $1;
  1188.             my $minor = (split /\s+/, scalar(<$fh>))[-1];
  1189.             my $patch = (split /\s+/, scalar(<$fh>))[-1];
  1190.             my $string = (split /\s+/, scalar(<$fh>))[-1];
  1191.             $version = join '.', $major, $minor, "$patch$string";
  1192.             $version =~ s/\"//g;
  1193.             last;
  1194.         }
  1195.     }
  1196.  
  1197.     close $fh;
  1198.  
  1199.     debug "parsed version $version from ap_release.h";
  1200.  
  1201.     $self->httpd_version_cache($dir, $version);
  1202. }
  1203.  
  1204. my %wanted_apr_config = map { $_, 1} qw(
  1205.     HAS_THREADS HAS_DSO HAS_MMAP HAS_RANDOM HAS_SENDFILE
  1206.     HAS_LARGE_FILES HAS_INLINE HAS_FORK
  1207. );
  1208.  
  1209. sub get_apr_config {
  1210.     my $self = shift;
  1211.  
  1212.     return $self->{apr_config} if $self->{apr_config};
  1213.  
  1214.     my $header = catfile $self->apr_includedir, "apr.h";
  1215.     open my $fh, $header or do {
  1216.         error "Unable to open $header: $!";
  1217.         return undef;
  1218.     };
  1219.  
  1220.     my %cfg;
  1221.     while (<$fh>) {
  1222.         next unless s/^\#define\s+APR_((HAVE|HAS|USE)_\w+)/$1/;
  1223.         chomp;
  1224.         my($name, $val) = split /\s+/, $_, 2;
  1225.         next unless $wanted_apr_config{$name};
  1226.         $val =~ s/\s+$//;
  1227.         next unless $val =~ /^\d+$/;
  1228.         $cfg{$name} = $val;
  1229.     }
  1230.  
  1231.     $self->{apr_config} = \%cfg;
  1232. }
  1233.  
  1234. #--- generate Makefile ---
  1235.  
  1236. sub canon_make_attr {
  1237.     my($self, $name) = (shift, shift);
  1238.  
  1239.     my $attr = join '_', 'MODPERL', uc $name;
  1240.     $self->{$attr} = "@_";
  1241.     "$attr = $self->{$attr}\n\n";
  1242. }
  1243.  
  1244. sub xsubpp {
  1245.     my $self = shift;
  1246.     my $xsubpp = join ' ', '$(MODPERL_PERLPATH)',
  1247.       '$(MODPERL_PRIVLIBEXP)/ExtUtils/xsubpp',
  1248.         '-typemap', '$(MODPERL_PRIVLIBEXP)/ExtUtils/typemap';
  1249.  
  1250.     my $typemap = $self->file_path('lib/typemap');
  1251.     if (-e $typemap) {
  1252.         $xsubpp .= join ' ',
  1253.           ' -typemap', $typemap;
  1254.     }
  1255.  
  1256.     $xsubpp;
  1257. }
  1258.  
  1259. sub make_xs {
  1260.     my($self, $fh) = @_;
  1261.  
  1262.     print $fh $self->canon_make_attr(xsubpp => $self->xsubpp);
  1263.  
  1264.     return [] unless $self->{XS};
  1265.  
  1266.     my @files;
  1267.     my @xs_targ;
  1268.  
  1269.     while (my($name, $xs) = each %{ $self->{XS} }) {
  1270.         #Foo/Bar.xs => Foo_Bar.c
  1271.         (my $c = $xs) =~ s:.*?WrapXS/::;
  1272.         $c =~ s:/:_:g;
  1273.         $c =~ s:\.xs$:.c:;
  1274.  
  1275.         push @files, $c;
  1276.  
  1277.         push @xs_targ, <<EOF;
  1278. $c: $xs
  1279. \t\$(MODPERL_XSUBPP) $xs > \$*.xsc && \$(MODPERL_MV) \$*.xsc \$@
  1280.  
  1281. EOF
  1282.     }
  1283.  
  1284.     my %o = (xs_o_files => 'o', xs_o_pic_files => 'lo');
  1285.  
  1286.     for my $ext (qw(xs_o_files xs_o_pic_files)) {
  1287.         print $fh $self->canon_make_attr($ext, map {
  1288.             (my $file = $_) =~ s/c$/$o{$ext}/; $file;
  1289.         } @files);
  1290.     }
  1291.  
  1292.     print $fh $self->canon_make_attr(xs_clean_files => @files);
  1293.  
  1294.     \@xs_targ;
  1295. }
  1296.  
  1297. #when we use a bit of MakeMaker, make it use our values for these vars
  1298. my %perl_config_pm_alias = (
  1299.     PERL         => 'perlpath',
  1300.     PERLRUN      => 'perlpath',
  1301.     PERL_LIB     => 'privlibexp',
  1302.     PERL_ARCHLIB => 'archlibexp',
  1303. );
  1304.  
  1305. my $mm_replace = join '|', keys %perl_config_pm_alias;
  1306.  
  1307. my @perl_config_pm =
  1308.   (qw(cc cpprun rm ranlib lib_ext obj_ext cccdlflags lddlflags optimize),
  1309.    values %perl_config_pm_alias);
  1310.  
  1311. sub mm_replace {
  1312.     my $val = shift;
  1313.     $$val =~ s/\(($mm_replace)\)/(MODPERL_\U$perl_config_pm_alias{$1})/g;
  1314. }
  1315.  
  1316. #help prevent warnings
  1317. my @mm_init_vars = (BASEEXT => '');
  1318.  
  1319. sub make_tools {
  1320.     my($self, $fh) = @_;
  1321.  
  1322.     for (@perl_config_pm) {
  1323.         print $fh $self->canon_make_attr($_, $self->perl_config($_));
  1324.     }
  1325.  
  1326.     require ExtUtils::MakeMaker;
  1327.     my $mm = bless { @mm_init_vars }, 'MM';
  1328.     $mm->init_main;
  1329.     $mm->init_others;
  1330.  
  1331.     for (qw(rm_f mv ld ar cp test_f)) {
  1332.         my $val = $mm->{"\U$_"};
  1333.         if ($val) {
  1334.             mm_replace(\$val);
  1335.         }
  1336.         else {
  1337.             $val = $Config{$_};
  1338.         }
  1339.         print $fh $self->canon_make_attr($_ => $val);
  1340.     }
  1341. }
  1342.  
  1343. sub export_files_MSWin32 {
  1344.     my $self = shift;
  1345.     my $xs_dir = $self->file_path("xs");
  1346.     "-def:$xs_dir/modperl.def";
  1347. }
  1348.  
  1349. sub export_files_aix {
  1350.     my $self = shift;
  1351.  
  1352.     my $Wl = $self->ldopts_prefix;
  1353.     # there are several modperl_*.exp, not just $(BASEEXT).exp
  1354.     # $(BASEEXT).exp resolves to modperl_global.exp
  1355.     my $xs_dir = $self->file_path("xs");
  1356.     join " ", map "${Wl}-bE:$xs_dir/modperl_$_.exp", qw(inline ithreads);
  1357. }
  1358.  
  1359. sub dynamic_link_header_default {
  1360.     return <<'EOF';
  1361. $(MODPERL_LIBNAME).$(MODPERL_DLEXT): $(MODPERL_PIC_OBJS)
  1362.     $(MODPERL_RM_F) $@
  1363.     $(MODPERL_LD) $(MODPERL_LDDLFLAGS) \
  1364.     $(MODPERL_AP_LIBS) \
  1365.     $(MODPERL_PIC_OBJS) $(MODPERL_LDOPTS) \
  1366. EOF
  1367. }
  1368.  
  1369. sub dynamic_link_default {
  1370.     my $self = shift;
  1371.  
  1372.     my $link = $self->dynamic_link_header_default . "\t" . '-o $@';
  1373.  
  1374.     my $ranlib = "\t" . '$(MODPERL_RANLIB) $@';
  1375.  
  1376.     $link .= "\n" . $ranlib unless (DARWIN or OPENBSD);
  1377.  
  1378.     $link;
  1379. }
  1380.  
  1381. sub dynamic_link_MSWin32 {
  1382.     my $self = shift;
  1383.     my $defs = $self->export_files_MSWin32;
  1384.     my $symbols = $self->modperl_symbols_MSWin32;
  1385.     return $self->dynamic_link_header_default .
  1386.         "\t$defs" .
  1387.         ($symbols ? ' \\' . "\n\t-pdb:$symbols" : '') .
  1388.         ' -out:$@';
  1389. }
  1390.  
  1391. sub dynamic_link_aix {
  1392.     my $self = shift;
  1393.     my $link = $self->dynamic_link_header_default .
  1394.         "\t" . $self->export_files_aix . " \\\n" .
  1395.         "\t" . '-o $@' . " \n" .
  1396.         "\t" . '$(MODPERL_RANLIB) $@';
  1397. }
  1398.  
  1399. sub dynamic_link {
  1400.     my $self = shift;
  1401.     my $link = \&{"dynamic_link_$^O"};
  1402.     $link = \&dynamic_link_default unless defined &$link;
  1403.     $link->($self);
  1404. }
  1405.  
  1406. sub apache_libs_MSWin32 {
  1407.     my $self = shift;
  1408.     my $prefix = $self->apxs(-q => 'PREFIX');
  1409.     my @libs = map { "$prefix/lib/lib$_.lib" } qw(apr aprutil httpd);
  1410.     "@libs";
  1411. }
  1412.  
  1413. sub apache_libs {
  1414.     my $self = shift;
  1415.     my $libs = \&{"apache_libs_$^O"};
  1416.     return "" unless defined &$libs;
  1417.     $libs->($self);
  1418. }
  1419.  
  1420. sub modperl_libs_MSWin32 {
  1421.     my $self = shift;
  1422.     # mod_perl.lib will be installed into MP_AP_PREFIX/lib
  1423.     # for use by 3rd party xs modules
  1424.     "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.lib";
  1425. }
  1426.  
  1427. sub modperl_libs {
  1428.     my $self = shift;
  1429.     my $libs = \&{"modperl_libs_$^O"};
  1430.     return "" unless defined &$libs;
  1431.     $libs->($self);
  1432. }
  1433.  
  1434. # returns the directory and name of the aprext lib built under blib/ 
  1435. sub mp_apr_blib {
  1436.     my $self = shift;
  1437.     return unless (my $mp_apr_lib = $self->{MP_APR_LIB});
  1438.     my $lib_mp_apr_lib = 'lib' . $mp_apr_lib;
  1439.     my @dirs = $self->{MP_INST_APACHE2} ?
  1440.         qw(blib arch Apache2 auto) : qw(blib arch auto);
  1441.     my $apr_blib = catdir $self->{cwd}, @dirs, $lib_mp_apr_lib;
  1442.     my $full_libname = $lib_mp_apr_lib . $Config{lib_ext};
  1443.     return ($apr_blib, $full_libname);
  1444. }
  1445.  
  1446. sub mp_apr_lib_MSWin32 {
  1447.     my $self = shift;
  1448.     # The MP_APR_LIB will be installed into MP_AP_PREFIX/lib
  1449.     # for use by 3rd party xs modules
  1450.     my ($dir, $lib) = $self->mp_apr_blib();
  1451.     $lib =~ s[^lib(\w+)$Config{lib_ext}$][$1];
  1452.     $dir = Win32::GetShortPathName($dir);
  1453.     return qq{ -L$dir -l$lib };
  1454. }
  1455.  
  1456. # linking used for the aprext lib used to build APR/APR::*
  1457. sub mp_apr_lib {
  1458.     my $self = shift;
  1459.     my $libs = \&{"mp_apr_lib_$^O"};
  1460.     return "" unless defined &$libs;
  1461.     $libs->($self);
  1462. }
  1463.  
  1464. sub modperl_symbols_MSWin32 {
  1465.     my $self = shift;
  1466.     return "" unless $self->{MP_DEBUG};
  1467.     "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.pdb";
  1468. }
  1469.  
  1470. sub modperl_symbols {
  1471.     my $self = shift;
  1472.     my $symbols = \&{"modperl_symbols_$^O"};
  1473.     return "" unless defined &$symbols;
  1474.     $symbols->($self);
  1475. }
  1476.  
  1477. sub write_src_makefile {
  1478.     my $self = shift;
  1479.     my $code = ModPerl::Code->new;
  1480.     my $path = $code->path;
  1481.  
  1482.     my $install = <<'EOI';
  1483. install:
  1484. # install mod_perl.so
  1485.     @$(MKPATH) $(MODPERL_AP_LIBEXECDIR)
  1486.     $(MODPERL_TEST_F) $(MODPERL_LIB_DSO) && \
  1487.     $(MODPERL_CP) $(MODPERL_LIB_DSO) $(MODPERL_AP_LIBEXECDIR)
  1488. # install mod_perl .h files
  1489.     @$(MKPATH) $(MODPERL_AP_INCLUDEDIR)
  1490.     $(MODPERL_CP) $(MODPERL_H_FILES) $(MODPERL_AP_INCLUDEDIR)
  1491. EOI
  1492.  
  1493.     my $mf = $self->default_file('makefile');
  1494.  
  1495.     open my $fh, '>', $mf or die "open $mf: $!";
  1496.  
  1497.     print $fh noedit_warning_hash();
  1498.  
  1499.     print $fh $self->canon_make_attr('makefile', basename $mf);
  1500.  
  1501.     $self->make_tools($fh);
  1502.  
  1503.     print $fh $self->canon_make_attr('ap_libs', $self->apache_libs);
  1504.  
  1505.     print $fh $self->canon_make_attr('libname', $self->{MP_LIBNAME});
  1506.     print $fh $self->canon_make_attr('dlext', 'so'); #always use .so
  1507.  
  1508.     if (AIX) {
  1509.         my $xs_dir = $self->file_path("xs");
  1510.         print $fh "BASEEXT = $xs_dir/modperl_global\n\n";
  1511.     }
  1512.  
  1513.     my %libs = (
  1514.         dso    => "$self->{MP_LIBNAME}.$self->{MODPERL_DLEXT}",
  1515.         static => "$self->{MP_LIBNAME}$self->{MODPERL_LIB_EXT}",
  1516.     );
  1517.  
  1518.     #XXX short-term compat for Apache::TestConfigPerl
  1519.     $libs{shared} = $libs{dso};
  1520.  
  1521.     while (my($type, $lib) = each %libs) {
  1522.         print $fh $self->canon_make_attr("lib_$type", $libs{$type});
  1523.     }
  1524.  
  1525.     if (my $symbols = $self->modperl_symbols) {
  1526.         print $fh $self->canon_make_attr('lib_symbols', $symbols);
  1527.         $install .= <<'EOI';
  1528. # install mod_perl symbol file
  1529.     @$(MKPATH) $(MODPERL_AP_LIBEXECDIR)
  1530.     $(MODPERL_TEST_F) $(MODPERL_LIB_SYMBOLS) && \
  1531.     $(MODPERL_CP) $(MODPERL_LIB_SYMBOLS) $(MODPERL_AP_LIBEXECDIR)
  1532. EOI
  1533.     }
  1534.  
  1535.     if (my $libs = $self->modperl_libs) {
  1536.         print $fh $self->canon_make_attr('lib_location', $libs);
  1537.         print $fh $self->canon_make_attr('ap_libdir', 
  1538.                                          "$self->{MP_AP_PREFIX}/lib");
  1539.         $install .= <<'EOI';
  1540. # install mod_perl.lib
  1541.     @$(MKPATH) $(MODPERL_AP_LIBDIR)
  1542.     $(MODPERL_TEST_F) $(MODPERL_LIB_LOCATION) && \
  1543.     $(MODPERL_CP) $(MODPERL_LIB_LOCATION) $(MODPERL_AP_LIBDIR)
  1544. EOI
  1545.     }
  1546.  
  1547.     my $libperl = join '/',
  1548.       $self->perl_config('archlibexp'), 'CORE', $self->perl_config('libperl');
  1549.  
  1550.     #this is only used for deps, if libperl has changed, relink mod_perl.so
  1551.     #not all perl dists put libperl where it should be, so just leave this
  1552.     #out if it isn't in the proper place
  1553.     if (-e $libperl) {
  1554.         print $fh $self->canon_make_attr('libperl', $libperl);
  1555.     }
  1556.  
  1557.     for my $method (qw(ccopts ldopts inc)) {
  1558.         print $fh $self->canon_make_attr($method, $self->$method());
  1559.     }
  1560.  
  1561.     for my $method (qw(c_files o_files o_pic_files h_files)) {
  1562.         print $fh $self->canon_make_attr($method, @{ $code->$method() });
  1563.     }
  1564.  
  1565.     my @libs;
  1566.     for my $type (map { uc } keys %libs) {
  1567.         next unless $self->{"MP_USE_$type"};
  1568.         # on win32 mod_perl.lib must come after mod_perl.so
  1569.         $type eq 'STATIC'
  1570.             ? push    @libs, $self->{"MODPERL_LIB_$type"}
  1571.             : unshift @libs, $self->{"MODPERL_LIB_$type"};
  1572.     }
  1573.  
  1574.     print $fh $self->canon_make_attr('lib', "@libs");
  1575.  
  1576.     for my $q (qw(LIBEXECDIR INCLUDEDIR)) {
  1577.         print $fh $self->canon_make_attr("AP_$q",
  1578.                                          $self->apxs(-q => $q));
  1579.     }
  1580.  
  1581.     my $xs_targ = $self->make_xs($fh);
  1582.  
  1583.     print $fh <<'EOF';
  1584. MODPERL_CCFLAGS = $(MODPERL_INC) $(MODPERL_CCOPTS) $(MODPERL_OPTIMIZE)
  1585.  
  1586. MODPERL_CCFLAGS_SHLIB = $(MODPERL_CCFLAGS) $(MODPERL_CCCDLFLAGS)
  1587.  
  1588. MODPERL_OBJS = $(MODPERL_O_FILES) $(MODPERL_XS_O_FILES)
  1589.  
  1590. MODPERL_PIC_OBJS = $(MODPERL_O_PIC_FILES) $(MODPERL_XS_O_PIC_FILES)
  1591.  
  1592. MKPATH = $(MODPERL_PERLPATH) "-MExtUtils::Command" -e mkpath
  1593.  
  1594. all: lib
  1595.  
  1596. lib: $(MODPERL_LIB)
  1597.  
  1598. EOF
  1599.  
  1600.     print $fh $install;
  1601.  
  1602.     print $fh <<'EOF';
  1603.  
  1604. .SUFFIXES: .xs .c $(MODPERL_OBJ_EXT) .lo .i .s
  1605.  
  1606. .c.lo:
  1607.     $(MODPERL_CC) $(MODPERL_CCFLAGS_SHLIB) \
  1608.     -c $< && $(MODPERL_MV) $*$(MODPERL_OBJ_EXT) $*.lo
  1609.  
  1610. .c$(MODPERL_OBJ_EXT):
  1611.     $(MODPERL_CC) $(MODPERL_CCFLAGS) -c $<
  1612.  
  1613. .c.i:
  1614.     $(MODPERL_CPPRUN) $(MODPERL_CCFLAGS) -c $< > $*.i
  1615.  
  1616. .c.s:
  1617.     $(MODPERL_CC) -O -S $(MODPERL_CCFLAGS) -c $<
  1618.  
  1619. .xs.c:
  1620.     $(MODPERL_XSUBPP) $*.xs >$@
  1621.  
  1622. .xs$(MODPERL_OBJ_EXT):
  1623.     $(MODPERL_XSUBPP) $*.xs >$*.c
  1624.     $(MODPERL_CC) $(MODPERL_CCFLAGS) -c $*.c
  1625.  
  1626. .xs.lo:
  1627.     $(MODPERL_XSUBPP) $*.xs >$*.c
  1628.     $(MODPERL_CC) $(MODPERL_CCFLAGS_SHLIB) \
  1629.     -c $*.c && $(MODPERL_MV) $*$(MODPERL_OBJ_EXT) $*.lo
  1630.  
  1631. clean:
  1632.     $(MODPERL_RM_F) *.a *.so *.xsc \
  1633.     $(MODPERL_LIBNAME).exp $(MODPERL_LIBNAME).lib \
  1634.     *$(MODPERL_OBJ_EXT) *.lo *.i *.s *.pdb \
  1635.     $(MODPERL_CLEAN_FILES) \
  1636.     $(MODPERL_XS_CLEAN_FILES)
  1637.  
  1638. $(MODPERL_OBJS): $(MODPERL_H_FILES) $(MODPERL_MAKEFILE)
  1639. $(MODPERL_PIC_OBJS): $(MODPERL_H_FILES) $(MODPERL_MAKEFILE)
  1640. $(MODPERL_LIB): $(MODPERL_LIBPERL)
  1641.  
  1642. $(MODPERL_LIBNAME)$(MODPERL_LIB_EXT): $(MODPERL_OBJS)
  1643.     $(MODPERL_RM_F) $@
  1644.     $(MODPERL_AR) crv $@ $(MODPERL_OBJS)
  1645.     $(MODPERL_RANLIB) $@
  1646.  
  1647. EOF
  1648.  
  1649.     print $fh $self->dynamic_link;
  1650.  
  1651.     print $fh @$xs_targ;
  1652.  
  1653.     print $fh "\n"; # Makefile must end with \n to avoid warnings
  1654.  
  1655.     close $fh;
  1656. }
  1657.  
  1658. #--- generate MakeMaker parameter values ---
  1659.  
  1660. sub otherldflags_default {
  1661.     my $self = shift;
  1662.     # e.g. aix's V:ldflags feeds -brtl and other flags
  1663.     $self->perl_config('ldflags');
  1664. }
  1665.  
  1666. sub otherldflags {
  1667.     my $self = shift;
  1668.     my $flags = \&{"otherldflags_$^O"};
  1669.     return $self->otherldflags_default unless defined &$flags;
  1670.     $flags->($self);
  1671. }
  1672.  
  1673. sub otherldflags_MSWin32 {
  1674.     my $self = shift;
  1675.     my $flags = $self->otherldflags_default;
  1676.     $flags .= ' -pdb:$(INST_ARCHAUTODIR)\$(BASEEXT).pdb' if $self->{MP_DEBUG};
  1677.     $flags;
  1678. }
  1679.  
  1680. sub typemaps {
  1681.     my $self = shift;
  1682.     my @typemaps = ();
  1683.  
  1684.     # XXX: could move here the code from ModPerl::BuildMM
  1685.     return [] if IS_MOD_PERL_BUILD;
  1686.  
  1687.     # for post install use
  1688.     for (@INC) {
  1689.         # make sure not to pick mod_perl 1.0 typemap
  1690.         next if $self->{MP_INST_APACHE2} && $_ !~ /Apache2$/;
  1691.         my $file = "$_/auto/Apache/typemap";
  1692.         push @typemaps, $file if -e $file;
  1693.     }
  1694.  
  1695.     return \@typemaps;
  1696. }
  1697.  
  1698. sub includes {
  1699.     my $self = shift;
  1700.  
  1701.     my @inc = ();
  1702.  
  1703.     unless (IS_MOD_PERL_BUILD) {
  1704.         # XXX: what if apxs is not available? win32?
  1705.         my $ap_inc = $self->apxs('-q' => 'INCLUDEDIR');
  1706.         if ($ap_inc && -d $ap_inc) {
  1707.             push @inc, $ap_inc;
  1708.             return \@inc;
  1709.         }
  1710.  
  1711.         # this is fatal
  1712.         my $reason = $ap_inc
  1713.             ? "path $ap_inc doesn't exist"
  1714.             : "apxs -q INCLUDEDIR didn't return a value";
  1715.         die "Can't find the mod_perl include dir (reason: $reason)";
  1716.     }
  1717.  
  1718.     my $src = $self->dir;
  1719.     my $os = WIN32 ? 'win32' : 'unix';
  1720.     push @inc, $self->file_path("src/modules/perl", "xs");
  1721.  
  1722.     push @inc, $self->mp_include_dir;
  1723.  
  1724.     unless ($self->httpd_is_source_tree) {
  1725.         push @inc, $self->apr_includedir;
  1726.  
  1727.         my $ainc = $self->apxs('-q' => 'INCLUDEDIR');
  1728.         if (-d $ainc) {
  1729.             push @inc, $ainc;
  1730.             return \@inc;
  1731.         }
  1732.     }
  1733.  
  1734.     for ("$src/modules/perl", "$src/include",
  1735.          "$src/srclib/apr/include",
  1736.          "$src/srclib/apr-util/include",
  1737.          "$src/os/$os")
  1738.       {
  1739.           push @inc, $_ if -d $_;
  1740.       }
  1741.  
  1742.     return \@inc;
  1743. }
  1744.  
  1745. sub inc {
  1746.     my @includes = map { "-I$_" } @{ shift->includes };
  1747.     "@includes";
  1748. }
  1749.  
  1750. ### Picking the right LFS support flags for mod_perl, by Joe Orton ###
  1751. #
  1752. # on Unix systems where by default off_t is a "long", a 32-bit integer,
  1753. # there are two different ways to get "large file" support, i.e. the
  1754. # ability to manipulate files bigger than 2Gb:
  1755. #
  1756. # 1) you compile using -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64.  This
  1757. # makes sys/types.h expose off_t as a "long long", a 64-bit integer, and
  1758. # changes the size of a few other types too.  The C library headers
  1759. # automatically arrange to expose a correct implementation of functions
  1760. # like lseek() which take off_t parameters.
  1761. #
  1762. # 2) you compile using -D_LARGEFILE64_SOURCE, and use what is called the
  1763. # "transitional" interface.  This means that the system headers expose a
  1764. # new type, "off64_t", which is a long long, but the size of off_t is not
  1765. # changed.   A bunch of new functions like lseek64() are exposed by the C 
  1766. # library headers, which take off64_t parameters in place of off_t.
  1767. #
  1768. # Perl built with -Duselargefiles uses approach (1).
  1769. #
  1770. # APR HEAD uses (2) by default. APR 0.9 does not by default use either
  1771. # approach, but random users can take a httpd-2.0.49 tarball, and do:
  1772. #
  1773. #   export CPPFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
  1774. #   ./configure
  1775. #
  1776. # to build a copy of apr/httpd which uses approach (1), though this
  1777. # isn't really a supported configuration.
  1778. #
  1779. # The problem that mod_perl has to work around is when you take a
  1780. # package built with approach (1), i.e. Perl, and any package which was
  1781. # *not* built with (1), i.e. APR, and want to interface between
  1782. # them. [1]
  1783. #
  1784. # So what you want to know is whether APR was built using approach (1)
  1785. # or not.  APR_HAS_LARGE_FILES in HEAD just tells you whether APR was
  1786. # built using approach (2) or not, which isn't useful in solving this
  1787. # problem.
  1788. #
  1789. # [1]: In some cases, it may be OK to interface between packages which
  1790. # use (1) and packages which use (2).  APR HEAD is currently not such a
  1791. # case, since the size of apr_ino_t is still changing when
  1792. # _FILE_OFFSET_BITS is defined.
  1793. #
  1794. # If you want to see how this matters, get some httpd function to do at
  1795. # the very beginning of main():
  1796. #
  1797. #   printf("sizeof(request_rec) = %lu, sizeof(apr_finfo_t) = %ul",
  1798. #          sizeof(request_rec), sizeof(apr_finfo_t));
  1799. #
  1800. # and then put the same printf in mod_perl somewhere, and see the
  1801. # differences. This is why it is a really terribly silly idea to ever
  1802. # use approach (1) in anything other than an entirely self-contained
  1803. # application.
  1804. #
  1805. # there is no conflict if both libraries either have or don't have
  1806. # large files support enabled
  1807. sub has_large_files_conflict {
  1808.     my $self = shift;
  1809.  
  1810.     my $apxs_flags = join $self->apxs_extra_cflags, $self->apxs_extra_cppflags;
  1811.     my $apr_lfs64  = $apxs_flags      =~ /-D_FILE_OFFSET_BITS=64/;
  1812.     my $perl_lfs64 = $Config{ccflags} =~ /-D_FILE_OFFSET_BITS=64/;
  1813.  
  1814.     # XXX: we don't really deal with the case where APR was built with
  1815.     # -D_FILE_OFFSET_BITS=64 but perl wasn't, since currently we strip
  1816.     # only perl's ccflags, not apr's flags. the reason we don't deal
  1817.     # with it is that we didn't have such a case yet, but may need to
  1818.     # deal with it later
  1819.  
  1820.     return $perl_lfs64 ^ $apr_lfs64;
  1821. }
  1822.  
  1823. # if perl is built with uselargefiles, but apr not, the build won't
  1824. # work together as it uses two binary incompatible libraries, so
  1825. # reduce the functionality to the greatest common denominator (C code
  1826. # will have to make sure to prevent any operations that may rely on
  1827. # effects created by uselargefiles, e.g. Off_t=8 instead of Off_t=4)
  1828. sub strip_lfs {
  1829.     my($self, $cflags) = @_;
  1830.     return $cflags unless $self->has_large_files_conflict();
  1831.  
  1832.     my $lf = $Config{ccflags_uselargefiles}
  1833.         || '-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64';
  1834.     $cflags =~ s/$lf//;
  1835.     $cflags;
  1836. }
  1837.  
  1838. sub define {
  1839.     my $self = shift;
  1840.  
  1841.     return "";
  1842. }
  1843.  
  1844. # in case MP_INST_APACHE2=0 we shouldn't try to adjust @INC
  1845. # because it may pick older Apache2 from the previous install
  1846. sub generate_apache2_pm {
  1847.     my $self = shift;
  1848.  
  1849.     my $fixup = !$self->{MP_INST_APACHE2} 
  1850.         ? '# MP_INST_APACHE2=0, do nothing'
  1851.         : <<'EOF';
  1852. BEGIN {
  1853.     my @dirs = ();
  1854.  
  1855.     for my $path (@INC) {
  1856.         my $dir = "$path/Apache2";
  1857.         next unless -d $dir;
  1858.         push @dirs, $dir;
  1859.     }
  1860.  
  1861.     if (@dirs) {
  1862.         unshift @INC, @dirs;
  1863.     }
  1864.  
  1865.     # now re-org the libs to have first devel libs, then blib libs,
  1866.     # and only then perl core libs
  1867.     use File::Basename qw(dirname);
  1868.     my $project_root = $blib ? dirname(dirname($blib)) : '';
  1869.     if ($project_root) {
  1870.         my (@a, @b, @c);
  1871.         for (@INC) {
  1872.             if (m|^\Q$project_root\E|) {
  1873.                 m|blib| ? push @b, $_ : push @a, $_;
  1874.             }
  1875.             else {
  1876.                 push @c, $_;
  1877.             }
  1878.         }
  1879.         @INC = (@a, @b, @c);
  1880.     }
  1881.  
  1882. }
  1883. EOF
  1884.  
  1885.     my $content = join "\n\n", noedit_warning_hash(),
  1886.         'package Apache2;', $fixup, "1;";
  1887.     my $file = catfile qw(lib Apache2.pm);
  1888.     open my $fh, '>', $file or die "Can't open $file: $!";
  1889.     print $fh $content;
  1890.     close $fh;
  1891.  
  1892. }
  1893.  
  1894. 1;
  1895.  
  1896. __END__
  1897.  
  1898. =head1 NAME
  1899.  
  1900. Apache::Build - Methods for locating and parsing bits of Apache source code
  1901.  
  1902. =head1 SYNOPSIS
  1903.  
  1904.  use Apache::Build ();
  1905.  my $build = Apache::Build->new;
  1906.  
  1907.  # rebuild mod_perl with build opts from the previous build
  1908.  % cd modperl-2.0
  1909.  % perl -MApache::Build -e rebuild
  1910.  
  1911. =head1 DESCRIPTION
  1912.  
  1913. This module provides methods for locating and parsing bits of Apache
  1914. source code.
  1915.  
  1916. Since mod_perl remembers what build options were used to build it, you
  1917. can use this knowledge to rebuild it using the same options. Simply
  1918. chdir to the mod_perl source directory and run:
  1919.  
  1920.   % cd modperl-2.0
  1921.   % perl -MApache::Build -e rebuild
  1922.  
  1923. If you want to rebuild not yet installed, but already built mod_perl,
  1924. run from its root directory:
  1925.  
  1926.   % perl -Ilib -MApache::Build -e rebuild
  1927.  
  1928. =head1 METHODS
  1929.  
  1930. =over 4
  1931.  
  1932. =item new
  1933.  
  1934. Create an object blessed into the B<Apache::Build> class.
  1935.  
  1936.  my $build = Apache::Build->new;
  1937.  
  1938. =item dir
  1939.  
  1940. Top level directory where source files are located.
  1941.  
  1942.  my $dir = $build->dir;
  1943.  -d $dir or die "can't stat $dir $!\n";
  1944.  
  1945. =item find
  1946.  
  1947. Searches for apache source directories, return a list of those found.
  1948.  
  1949. Example:
  1950.  
  1951.  for my $dir ($build->find) {
  1952.     my $yn = prompt "Configure with $dir ?", "y";
  1953.     ...
  1954.  }
  1955.  
  1956. =item inc
  1957.  
  1958. Print include paths for MakeMaker's B<INC> argument to
  1959. C<WriteMakefile>.
  1960.  
  1961. Example:
  1962.  
  1963.  use ExtUtils::MakeMaker;
  1964.  
  1965.  use Apache::Build ();
  1966.  
  1967.  WriteMakefile(
  1968.      'NAME'    => 'Apache::Module',
  1969.      'VERSION' => '0.01',
  1970.      'INC'     => Apache::Build->new->inc,
  1971.  );
  1972.  
  1973.  
  1974. =item module_magic_number
  1975.  
  1976. Return the B<MODULE_MAGIC_NUMBER> defined in the apache source.
  1977.  
  1978. Example:
  1979.  
  1980.  my $mmn = $build->module_magic_number;
  1981.  
  1982. =item httpd_version
  1983.  
  1984. Return the server version.
  1985.  
  1986. Example:
  1987.  
  1988.  my $v = $build->httpd_version;
  1989.  
  1990. =item otherldflags
  1991.  
  1992. Return other ld flags for MakeMaker's B<dynamic_lib> argument to
  1993. C<WriteMakefile>. This might be needed on systems like AIX that need
  1994. special flags to the linker to be able to reference mod_perl or httpd
  1995. symbols.
  1996.  
  1997. Example:
  1998.  
  1999.  use ExtUtils::MakeMaker;
  2000.  
  2001.  use Apache::Build ();
  2002.  
  2003.  WriteMakefile(
  2004.      'NAME'        => 'Apache::Module',
  2005.      'VERSION'     => '0.01', 
  2006.      'INC'         => Apache::Build->new->inc,
  2007.      'dynamic_lib' => {
  2008.          'OTHERLDFLAGS' => Apache::Build->new->otherldflags,
  2009.      },
  2010.  );
  2011.  
  2012. =back
  2013.  
  2014.  
  2015. =head1 AUTHOR
  2016.  
  2017. Doug MacEachern
  2018.  
  2019. =cut
  2020.