home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / MM.pm < prev    next >
Encoding:
Perl POD Document  |  2003-12-17  |  6.1 KB  |  213 lines

  1. package ModPerl::MM;
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use ExtUtils::MakeMaker ();
  7. use ExtUtils::Install ();
  8.  
  9. use Cwd ();
  10. use Carp;
  11.  
  12. our %PM; #add files to installation
  13.  
  14. # MM methods that this package overrides
  15. no strict 'refs';
  16. my $stash = \%{__PACKAGE__ . '::MY::'};
  17. my @methods = grep *{$stash->{$_}}{CODE}, keys %$stash;
  18. my $eu_mm_mv_all_methods_overriden = 0;
  19.  
  20. use strict 'refs';
  21.  
  22. sub override_eu_mm_mv_all_methods {
  23.     my @methods = @_;
  24.  
  25.     my $orig_sub = \&ExtUtils::MakeMaker::mv_all_methods;
  26.     no warnings 'redefine';
  27.     *ExtUtils::MakeMaker::mv_all_methods = sub {
  28.         # do the normal move
  29.         $orig_sub->(@_);
  30.         # for all the overloaded methods mv_all_method installs a stab
  31.         # eval "package MY; sub $method { shift->SUPER::$method(\@_); }";
  32.         # therefore we undefine our methods so on the recursive invocation of
  33.         # Makefile.PL they will be undef, unless defined in Makefile.PL
  34.         # and my_import will override these methods properly
  35.         for my $sym (@methods) {
  36.             my $name = "MY::$sym";
  37.             undef &$name if defined &$name;
  38.         }
  39.     };
  40. }
  41.  
  42. #to override MakeMaker MOD_INSTALL macro
  43. sub mod_install {
  44.     # adding -MApache2 here so 3rd party modules could use this macro,
  45.     q{$(PERL) -I$(INST_LIB) -I$(PERL_LIB)  -MApache2 -MModPerl::MM \\}."\n" .
  46.     q{-e "ModPerl::MM::install({@ARGV},'$(VERBINST)',0,'$(UNINST)');"}."\n";
  47. }
  48.  
  49. sub add_dep {
  50.     my($string, $targ, $add) = @_;
  51.     $$string =~ s/($targ\s+::)/$1 $add/;
  52. }
  53.  
  54. sub add_dep_before {
  55.     my($string, $targ, $before_targ, $add) = @_;
  56.     $$string =~ s/($targ\s+::.*?) ($before_targ)/$1 $add $2/;
  57. }
  58.  
  59. sub add_dep_after {
  60.     my($string, $targ, $after_targ, $add) = @_;
  61.     $$string =~ s/($targ\s+::.*?$after_targ)/$1 $add/;
  62. }
  63.  
  64. sub build_config {
  65.     my $key = shift;
  66.     require Apache::Build;
  67.     my $build = Apache::Build->build_config;
  68.     return $build unless $key;
  69.     $build->{$key};
  70. }
  71.  
  72. #strip the Apache2/ subdir so things are install where they should be
  73. sub install {
  74.     my $hash = shift;
  75.  
  76.     if (build_config('MP_INST_APACHE2')) {
  77.         while (my($k,$v) = each %$hash) {
  78.             delete $hash->{$k};
  79.             $k =~ s:/Apache2$::;
  80.             $hash->{$k} = $v;
  81.         }
  82.     }
  83.  
  84.     ExtUtils::Install::install($hash, @_);
  85. }
  86.  
  87. #the parent WriteMakefile moves MY:: methods into a different class
  88. #so alias them each time WriteMakefile is called in a subdir
  89.  
  90. sub my_import {
  91.     my $package = shift;
  92.     no strict 'refs';
  93.     my $stash = \%{$package . '::MY::'};
  94.     for my $sym (keys %$stash) {
  95.         next unless *{$stash->{$sym}}{CODE};
  96.         my $name = "MY::$sym";
  97.         # the method is defined in Makefile.PL
  98.         next if defined &$name;
  99.         # do the override behind the scenes
  100.         *$name = *{$stash->{$sym}}{CODE};
  101.     }
  102. }
  103.  
  104. my @default_opts = qw(CCFLAGS LIBS INC OPTIMIZE LDDLFLAGS TYPEMAPS);
  105. my @default_dlib_opts = qw(OTHERLDFLAGS);
  106. my @default_macro_opts = qw(MOD_INSTALL);
  107. my $b = build_config();
  108. my %opts = (
  109.     CCFLAGS      => sub { $b->{MODPERL_CCOPTS}                        },
  110.     LIBS         => sub { join ' ', $b->apache_libs, $b->modperl_libs },
  111.     INC          => sub { $b->inc;                                    },
  112.     OPTIMIZE     => sub { $b->perl_config('optimize');                },
  113.     LDDLFLAGS    => sub { $b->perl_config('lddlflags');               },
  114.     TYPEMAPS     => sub { $b->typemaps;                               },
  115.     OTHERLDFLAGS => sub { $b->otherldflags;                           },
  116.     MOD_INSTALL  => \&ModPerl::MM::mod_install,
  117. );
  118.  
  119. sub get_def_opt {
  120.     my $opt = shift;
  121.     return $opts{$opt}->() if exists $opts{$opt};
  122.     # handle cases when Makefile.PL wants an option we don't have a
  123.     # default for. XXX: some options expect [] rather than scalar.
  124.     Carp::carp("!!! no default argument defined for argument: $opt");
  125.     return '';
  126. }
  127.  
  128. sub WriteMakefile {
  129.     my %args = @_;
  130.  
  131.     # override ExtUtils::MakeMaker::mv_all_methods
  132.     # can't do that on loading since ModPerl::MM is also use()'d
  133.     # by ModPerl::BuildMM which itself overrides it
  134.     unless ($eu_mm_mv_all_methods_overriden) {
  135.         override_eu_mm_mv_all_methods(@methods);
  136.         $eu_mm_mv_all_methods_overriden++;
  137.     }
  138.  
  139.     my $build = build_config();
  140.     my_import(__PACKAGE__);
  141.  
  142.     # set top-level WriteMakefile's values if weren't set already
  143.     for (@default_opts) {
  144.         $args{$_} = get_def_opt($_) unless exists $args{$_}; # already defined
  145.     }
  146.  
  147.     # set dynamic_lib-level WriteMakefile's values if weren't set already
  148.     $args{dynamic_lib} ||= {};
  149.     my $dlib = $args{dynamic_lib};
  150.     for (@default_dlib_opts) {
  151.         $dlib->{$_} = get_def_opt($_) unless exists $dlib->{$_};
  152.     }
  153.  
  154.     # set macro-level WriteMakefile's values if weren't set already
  155.     $args{macro} ||= {};
  156.     my $macro = $args{macro};
  157.     for (@default_macro_opts) {
  158.         $macro->{$_} = get_def_opt($_) unless exists $macro->{$_};
  159.     }
  160.  
  161.     ExtUtils::MakeMaker::WriteMakefile(%args);
  162. }
  163.  
  164. #### MM overrides ####
  165.  
  166. sub ModPerl::MM::MY::constants {
  167.     my $self = shift;
  168.  
  169.     my $build = build_config();
  170.  
  171.     #install everything relative to the Apache2/ subdir
  172.     if ($build->{MP_INST_APACHE2}) {
  173.         $self->{INST_ARCHLIB} .= '/Apache2';
  174.         $self->{INST_LIB} .= '/Apache2';
  175.     }
  176.  
  177.     $self->MM::constants;
  178. }
  179.  
  180.  
  181. sub ModPerl::MM::MY::post_initialize {
  182.     my $self = shift;
  183.  
  184.     my $build = build_config();
  185.     my $pm = $self->{PM};
  186.  
  187.     while (my($k, $v) = each %PM) {
  188.         if (-e $k) {
  189.             $pm->{$k} = $v;
  190.         }
  191.     }
  192.  
  193.     #not everything in MakeMaker uses INST_LIB
  194.     #so we have do fixup a few PMs to make sure *everything*
  195.     #gets installed into Apache2/
  196.     if ($build->{MP_INST_APACHE2}) {
  197.         while (my($k, $v) = each %$pm) {
  198.             #move everything to the Apache2/ subdir
  199.             #unless already specified with \$(INST_LIB)
  200.             #or already in Apache2/
  201.             unless ($v =~ /Apache2/) {
  202.                 $v =~ s|(blib/lib)|$1/Apache2|;
  203.             }
  204.  
  205.             $pm->{$k} = $v;
  206.         }
  207.     }
  208.  
  209.     '';
  210. }
  211.  
  212. 1;
  213.