You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-cvs@httpd.apache.org by ra...@apache.org on 2003/08/06 07:26:24 UTC

cvs commit: httpd-apreq-2/win32 apxs_win32 apxs_win32_PL README

randyk      2003/08/05 22:26:24

  Modified:    win32    README
  Added:       win32    apxs_win32 apxs_win32_PL
  Log:
  temporarily add Win32 apxs tool, to be used to build env/c-modules/
  on Win32.
  
  Revision  Changes    Path
  1.3       +9 -4      httpd-apreq-2/win32/README
  
  Index: README
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/win32/README,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- README	16 Jun 2003 03:02:13 -0000	1.2
  +++ README	6 Aug 2003 05:26:24 -0000	1.3
  @@ -3,10 +3,10 @@
      perl Configure.pl
   to generate the top-level Makefile. Available options are:
   
  -  --with-apache=C:\Path\to\Apache2 : specify the top-level Apache2 directory
  -  --debug                          : build a debug version
  -  --without-perl                   : skip initialization of perl glue
  -  --help                           : print a help message
  +  --with-apache2=C:\Path\to\Apache2 : specify the top-level Apache2 directory
  +  --debug                           : build a debug version
  +  --without-perl                    : skip initialization of perl glue
  +  --help                            : print a help message
   
   With no options specified, an attempt will be made to find a suitable 
   Apache2 directory, and if found, a non-debug version will be built.
  @@ -22,3 +22,8 @@
     nmake docs          - build documentation
   
   The 'docs' target is only available if a doxygen binary is detected.
  +
  +An experimental apxs tool for Win32 is included here, which will be
  +needed to build the env/c-modules tests. To install it, run
  +   perl apxs_win32_PL
  +which will lead you through an installation dialogue.
  
  
  
  1.1                  httpd-apreq-2/win32/apxs_win32
  
  Index: apxs_win32
  ===================================================================
  #!%perlbin% -w
  # ====================================================================
  # The Apache Software License, Version 1.1
  #
  # Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
  # reserved.
  #
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions
  # are met:
  #
  # 1. Redistributions of source code must retain the above copyright
  #    notice, this list of conditions and the following disclaimer.
  #
  # 2. Redistributions in binary form must reproduce the above copyright
  #    notice, this list of conditions and the following disclaimer in
  #    the documentation and/or other materials provided with the
  #    distribution.
  #
  # 3. The end-user documentation included with the redistribution,
  #    if any, must include the following acknowledgment:
  #       "This product includes software developed by the
  #        Apache Software Foundation (http://www.apache.org/)."
  #    Alternately, this acknowledgment may appear in the software itself,
  #    if and wherever such third-party acknowledgments normally appear.
  #
  # 4. The names "Apache" and "Apache Software Foundation" must
  #    not be used to endorse or promote products derived from this
  #    software without prior written permission. For written
  #    permission, please contact apache@apache.org.
  #
  # 5. Products derived from this software may not be called "Apache",
  #    nor may "Apache" appear in their name, without prior written
  #    permission of the Apache Software Foundation.
  #
  # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  # DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  # ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  # SUCH DAMAGE.
  # ====================================================================
  #
  # This software consists of voluntary contributions made by many
  # individuals on behalf of the Apache Software Foundation.  For more
  # information on the Apache Software Foundation, please see
  # <http://www.apache.org/>.
  #
  
  require 5.003;
  use strict;
  package apxs;
  use File::Copy;
  
  ##
  ##  Configuration
  ##
  
  my %config_vars = ();
  
  my $installbuilddir = "%exp_installbuilddir%";
  get_config_vars("$installbuilddir/config_vars.mk",\%config_vars);
  
  # read the configuration variables once
  
  my $prefix         = get_vars("prefix");
  my $CFG_PREFIX     = $prefix;
  my $exec_prefix    = get_vars("exec_prefix");
  my $datadir        = get_vars("datadir");
  my $localstatedir  = get_vars("localstatedir");
  my $CFG_TARGET     = get_vars("progname");
  my $CFG_SYSCONFDIR = get_vars("sysconfdir");
  my $CFG_SYSCONF    = get_vars("sysconf");
  my $CFG_CFLAGS     = join ' ', map { get_vars($_) }
      qw(SHLTCFLAGS CFLAGS NOTEST_CPPFLAGS EXTRA_CPPFLAGS EXTRA_CFLAGS);
  my $includedir     = get_vars("includedir");
  my $CFG_INCLUDEDIR = eval qq("$includedir");
  my $libdir         = get_vars("libdir");
  my $CFG_LIBDIR     = eval qq("$libdir");
  my $CFG_CC         = get_vars("CC");
  my $CFG_LD         = get_vars("LD");
  my $CFG_LDFLAGS    = get_vars("LDFLAGS");
  my $libexecdir     = get_vars("libexecdir");
  my $CFG_LIBEXECDIR = eval qq("$libexecdir");
  my $sbindir        = get_vars("sbindir");
  my $CFG_SBINDIR    = eval qq("$sbindir");
  my $ltflags        = $ENV{'LTFLAGS'};
  $ltflags or $ltflags = "--silent";
  
  my %internal_vars = map {$_ => 1}
      qw(TARGET CC CFLAGS CFLAGS_SHLIB LD_SHLIB LDFLAGS_SHLIB LIBS_SHLIB
         PREFIX SBINDIR INCLUDEDIR LIBEXECDIR SYSCONFDIR SYSCONF);
  
  my $CP    = "%CP%";
  my $CHMOD = "%CHMOD%";
  my $RM_F  = "%RM_F%";
  my $TOUCH = "%TOUCH%";
  
  ##
  ##  parse argument line
  ##
  
  #   defaults for parameters
  my $opt_n = '';
  my $opt_g = '';
  my $opt_c = 0;
  my $opt_o = '';
  my @opt_D = ();
  my @opt_I = ();
  my @opt_L = ();
  my @opt_l = ();
  my @opt_W = ();
  my @opt_S = ();
  my $opt_e = 0;
  my $opt_i = 0;
  my $opt_a = 0;
  my $opt_A = 0;
  my $opt_q = 0;
  my $opt_h = 0;
  my $opt_p = 0;
  my $opt_d = 0;
  
  #   this subroutine is derived from Perl's getopts.pl with the enhancement of
  #   the "+" metacharacter at the format string to allow a list to be built by
  #   subsequent occurrences of the same option.
  sub Getopts {
      my ($argumentative, @ARGV) = @_;
      my $errs = 0;
      local $_;
      local $[ = 0;
  
      my @args = split / */, $argumentative;
      while (@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
          my ($first, $rest) = ($1,$2);
          if ($_ =~ m|^--$|) {
              shift @ARGV;
              last;
          }
          my $pos = index($argumentative,$first);
          if ($pos >= $[) {
              if ($pos < $#args && $args[$pos+1] eq ':') {
                  shift @ARGV;
                  if ($rest eq '') {
                      unless (@ARGV) {
                          error("Incomplete option: $first (needs an argument)");
                          $errs++;
                      }
                      $rest = shift(@ARGV);
                  }
                  eval "\$opt_$first = \$rest;";
              }
              elsif ($pos < $#args && $args[$pos+1] eq '+') {
                  shift @ARGV;
                  if ($rest eq '') {
                      unless (@ARGV) {
                          error("Incomplete option: $first (needs an argument)");
                          $errs++;
                      }
                      $rest = shift(@ARGV);
                  }
                  eval "push(\@opt_$first, \$rest);";
              }
              else {
                  eval "\$opt_$first = 1";
                  if ($rest eq '') {
                      shift(@ARGV);
                  }
                  else {
                      $ARGV[0] = "-$rest";
                  }
              }
          }
          else {
              error("Unknown option: $first");
              $errs++;
              if ($rest ne '') {
                  $ARGV[0] = "-$rest";
              }
              else {
                  shift(@ARGV);
              }
          }
      }
      return ($errs == 0, @ARGV);
  }
  
  sub usage {
      print STDERR "Usage: apxs -g [-S <var>=<val>] -n <modname>\n";
      print STDERR "       apxs -q [-S <var>=<val>] <query> ...\n";
      print STDERR "       apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]]\n";
      print STDERR "               [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>]\n";
      print STDERR "               [-Wl,<flags>] [-p] <files> ...\n";
      print STDERR "       apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n";
      print STDERR "       apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n";
      exit(1);
  }
  
  #   option handling
  my $rc;
  ($rc, @ARGV) = &Getopts("qn:gco:I+D+L+l+W+S+eiaApd", @ARGV);
  &usage if ($rc == 0);
  &usage if ($#ARGV == -1 and not $opt_g);
  &usage if (not $opt_q and not ($opt_g and $opt_n) 
             and not $opt_i and not $opt_c and not $opt_e);
  
  #   argument handling
  my @args = @ARGV;
  my $name = 'unknown';
  $name = $opt_n if ($opt_n ne '');
  
  if (@opt_S) {
      my ($opt_S);
      foreach $opt_S (@opt_S) {
          if ($opt_S =~ m/^([^=]+)=(.*)$/) {
              my ($var) = $1;
              my ($val) = $2;
              my $oldval = eval "\$CFG_$var";
  
              unless ($var and $oldval) {
                  print STDERR "apxs:Error: no config variable $var\n";
                  &usage;
              }
  
              eval "\$CFG_${var}=\"${val}\"";
          } else {
              print STDERR "apxs:Error: malformatted -S option\n";
              &usage;
          }	
      }
  }
  
  ##
  ##  Initial shared object support check
  ##
  my $httpd = get_vars("sbindir") . "/" . get_vars("progname");
  $httpd = eval qq("$httpd");
  $httpd = eval qq("$httpd");
  my $envvars = get_vars("sbindir") . "/envvars";
  $envvars = eval qq("$envvars");
  $envvars = eval qq("$envvars");
  
  #allow apxs to be run from the source tree, before installation
  if ($0 =~ m:support/apxs$:) {
      ($httpd = $0) =~ s:support/apxs$::;
  }
  
  unless (-f "$httpd") {
      error("$httpd not found or not executable");
      exit 1;
  }
  
  sub get_config_vars{
      my ($file, $rh_config) = @_;
  
      open IN, $file or die "cannot open $file: $!";
      while (<IN>){
          if (/^\s*(.*?)\s*=\s*(.*)$/){
              $rh_config->{$1} = $2;
          }
      }
      close IN;
  }
  
  sub get_vars {
      my $result = '';
      my $ok = 0;
      my $arg;
      foreach $arg (@_) {
          if (exists $config_vars{$arg} or exists $config_vars{lc $arg}) {
              my $val = exists $config_vars{$arg}
                  ? $config_vars{$arg}
                      : $config_vars{lc $arg};
              $val =~ s/[()]//g;
              $result .= eval "qq($val)" if defined $val;
              $result .= ";;";
              $ok = 1;
          }
          if (not $ok) {
              if (exists $internal_vars{$arg} 
                  or exists $internal_vars{lc $arg}) {
                  my $val = exists $internal_vars{$arg} ? $arg : lc $arg;
                  $val = eval "\$CFG_$val";
                  $result .= eval "qq($val)" if defined $val;
                  $result .= ";;";
                  $ok = 1;
              }
              if (not $ok) {
                  error("Invalid query string `$arg'");
                  exit(1);
              }
          }
      }
      $result =~ s|;;$||;
      #    $result =~ s|:| |;
      return $result;
  }
  
  ##
  ##  Operation
  ##
  
  #   helper function for executing a list of
  #   system command with return code checks
  sub execute_cmds {
      my (@cmds) = @_;
      my ($cmd, $rc);
  
      foreach $cmd (@cmds) {
          notice($cmd);
          $rc = system $cmd;
          if ($rc) {
              error(sprintf "Command failed with rc=%d\n", $rc << 8);
              exit 1 ;
          }
      }
  }
  
  if ($opt_g) {
      ##
      ##  SAMPLE MODULE SOURCE GENERATION
      ##
  
      if (-d $name) {
          error("Directory `$name' already exists. Remove first");
          exit(1);
      }
  
      my $data = join('', <DATA>);
      $data =~ s!__END__.*!!s;
      $data =~ s|%NAME%|$name|sg;
      $data =~ s|%SYSCONF%|$CFG_SYSCONF|sg;
      $data =~ s|%PREFIX%|$prefix|sg;
      $data =~ s|%INSTALLBUILDDIR%|$installbuilddir|sg;
  
      my ($mkf, $src) = ($data =~ m|^(.+)-=\#=-\n(.+)|s);
  
      notice("Creating [DIR]  $name");
      mkdir $name or die "Cannot mkdir $name: $!";
      notice("Creating [FILE] $name/Makefile");
      open(FP, ">${name}/Makefile") or die "Cannot open ${name}/Makefile: $!";
      print FP $mkf;
      close(FP);
      notice("Creating [FILE] $name/mod_$name.c");
      open(FP, ">${name}/mod_${name}.c") || die;
      print FP $src;
      close(FP);
      notice("Creating [FILE] $name/.deps");
      open(FP, ">${name}/.deps") or die "Cannot open ${name}/.deps: $!";
      close(FP);
  
      exit(0);
  }
  
  if ($opt_q) {
      ##
      ##  QUERY INFORMATION 
      ##
      my $result = get_vars(@args);
      print "$result\n";
  }
  
  my $apr_bindir = get_vars("APR_BINDIR");
  my $apu_bindir = get_vars("APU_BINDIR");
  
  my $apr_includedir = "-I$prefix/include";
  my $apu_includedir = "-I$prefix/include";
  
  if ($opt_c) {
      ##
      ##  SHARED OBJECT COMPILATION
      ##
      
      #   split files into sources and objects
      my @srcs = ();
      my @objs = ();
      my $f;
      foreach $f (@args) {
          if ($f =~ m|\.c$|) {
              push(@srcs, $f);
          }
          else {
              push(@objs, $f);
          }
      }
  
      #   determine output file
      my $dso_file;
      if ($opt_o eq '') {
          if ($#srcs > -1) {
              $dso_file = $srcs[0];
              $dso_file =~ s|\.[^.]+$|.so|;
          }
          elsif ($#objs > -1) {
              $dso_file = $objs[0];
              $dso_file =~ s|\.[^.]+$|.so|;
          }
          else {
              $dso_file = "mod_unknown.so";
          }
      }
      else {
          $dso_file = $opt_o;
      }
  
      #   create compilation commands
      my @cmds = ();
      my $opt = '';
      my ($opt_Wc, $opt_I, $opt_D);
      foreach $opt_Wc (@opt_W) {
          $opt .= "$1 " if ($opt_Wc =~ m|^\s*c,(.*)$|);
      }
      foreach $opt_I (@opt_I) {
          $opt .= qq{ /I"$opt_I" };
      }
      foreach $opt_D (@opt_D) {
          $opt .= qq{ /D "$opt_D" };
      }
      my $cflags = "$CFG_CFLAGS";
      if ($opt_d) {
          $cflags =~ s!NDEBUG!DEBUG!;
          $cflags .= ' /Zi';
          $cflags =~ s!/MD !/MDd !;
      }
      my $s;
      my $mod;
      foreach $s (@srcs) {
          my $slo = $s;
          $slo =~ s|\.c$|.slo|;
          my $lo = $s;
          $lo =~ s|\.c$|.lo|;
          my $la = $s;
          $la =~ s|\.c$|.la|;
          my $o = $s;
          $o =~ s|\.c$|.o|;
          push(@cmds, "$CFG_CC $cflags -I$CFG_INCLUDEDIR $opt /c /Fo$lo $s");
          unshift(@objs, $lo);
      }
  
      #   create link command
      my $o;
      my $lo;
      $opt = '';
      foreach $o (@objs) {
          $lo .= " $o";
      }
      my ($opt_Wl, $opt_L, $opt_l);
      foreach $opt_Wl (@opt_W) {
          if ($CFG_CC !~ m/gcc$/) {
              $opt .= " $1" if ($opt_Wl =~ m|^\s*l,(.*)$|);
          } else {
              $opt .= " -W$opt_Wl";
          }
      }
      foreach $opt_L (@opt_L) {
          $opt .= qq{ /libpath:"$opt_L" };
      }
      foreach $opt_l (@opt_l) {
          $opt_l .= '.lib' unless ($opt_l =~ /\.lib$/); 
          $opt .= " $opt_l";
      }
  
      if ($opt_p == 1) {
          my $apr_libs = qq{$prefix/lib/libapr.lib};
          my $apu_libs = qq{$prefix/lib/libaprutil.lib};
          $opt .= " ".$apu_libs." ".$apr_libs;
      }
      else {
          my $apr_ldflags;
          $opt .= " $apr_ldflags";
      }
      my $ldflags = "$CFG_LDFLAGS";
      if ($opt_d) {
          $ldflags .= ' /debug';
      }
      push(@cmds, "$CFG_LD $ldflags /out:$dso_file $opt $lo");
  
      #   execute the commands
      &execute_cmds(@cmds);
  
      #   allow one-step compilation and installation
      if ($opt_i or $opt_e) {
          @args = ( $dso_file );
      }
  }
  
  if ($opt_i or $opt_e) {
      ##
      ##  SHARED OBJECT INSTALLATION
      ##
      unless (-d $CFG_LIBEXECDIR) {
          die "Directory $CFG_LIBEXECDIR not found";
      }
      #   determine installation commands
      #   and corresponding LoadModule/AddModule directives
      my @lmd = ();
      my @amd = ();
      my @cmds = ();
      my $f;
      foreach $f (@args) {
          my $end = qr{(\.so|\.la)$};
          if ($f !~ m!$end!) {
              error("file $f is not a shared object");
              exit(1);
          }
          my $t = $f;
          $t =~ s|^.+/([^/]+)$|$1|;
          $t =~ s|\.la$|\.so|;
          (my $libf = $f) =~ s!$end!.lib!;
          (my $libt = $t) =~ s!$end!.lib!;
          (my $pdbf = $f) =~ s!$end!.pdb!;
          (my $pdbt = $t) =~ s!$end!.pdb!;
  
          if ($opt_i) {
              push(@cmds, "$CP $f $CFG_LIBEXECDIR");
              push(@cmds, "$CHMOD 755 $CFG_LIBEXECDIR/$t");
              if (-f $libf) {
                  push(@cmds, "$CP $libf $CFG_LIBDIR");
                  push(@cmds, "$CHMOD 755 $CFG_LIBDIR/$libt");
              }
              if ($opt_d and -f $pdbf) {
                  push(@cmds, "$CP $pdbf $CFG_LIBEXECDIR");
                  push(@cmds, "$CHMOD 755 $CFG_LIBEXECDIR/$pdbt");
              }
          }
  
          #   determine module symbolname and filename
          my $filename = '';
          if ($name eq 'unknown') {
              $name = '';
              my $base = $f;
              $base =~ s|\.[^.]+$||;
              if (-f "$base.c") {
                  open(FP, "<$base.c");
                  my $content = join('', <FP>);
                  close(FP);
                  if ($content =~ m|.*module\s+(?:AP_MODULE_DECLARE_DATA\s+)?([a-zA-Z0-9_]+)_module\s*=\s*.*|s) {
                      $name = "$1";
                      $filename = "$base.c";
                      $filename =~ s|^[^/]+/||;
                  }
              }
              if ($name eq '') {
                  if ($base =~ m|.*mod_([a-zA-Z0-9_]+)\..+|) {
                      $name = "$1";
                      $filename = $base;
                      $filename =~ s|^[^/]+/||;
                  }
              }
              if ($name eq '') {
                  error("Sorry, cannot determine bootstrap symbol name");
                  error("Please specify one with option `-n'");
                  exit(1);
              }
          }
          if ($filename eq '') {
              $filename = "mod_${name}.c";
          }
          my $dir = $CFG_LIBEXECDIR;
          $dir =~ s|^$CFG_PREFIX/?||;
          $dir =~ s|(.)$|$1/|;
          $t =~ s|\.la$|.so|;
          push(@lmd, sprintf("LoadModule %-18s %s", "${name}_module", "$dir$t"));
          push(@amd, sprintf("AddModule %s", $filename));
      }
  
      #   execute the commands
      &execute_cmds(@cmds);
  
      #   activate module via LoadModule/AddModule directive
      if ($opt_a or $opt_A) {
          if (not -f "$CFG_SYSCONFDIR/$CFG_SYSCONF") {
              error("Config file $CFG_SYSCONFDIR/$CFG_SYSCONF not found");
              exit(1);
          }
  
          open(FP, "<$CFG_SYSCONFDIR/$CFG_SYSCONF") 
              || die "Cannot open $CFG_SYSCONFDIR/$CFG_SYSCONF: $!";
          my $content = join('', <FP>);
          close(FP);
  
          if ($content !~ m|\n\#?\s*LoadModule\s+|) {
              error("Activation failed for custom $CFG_SYSCONFDIR/$CFG_SYSCONF file.");
              error("At least one `LoadModule' directive already has to exist.");
              exit(1);
          }
  
          my $lmd;
          my $c = '';
          $c = '#' if ($opt_A);
          foreach $lmd (@lmd) {
              my $what = $opt_A ? "preparing" : "activating";
              if ($content !~ m|\n\#?\s*$lmd|) {
                  # check for open <containers>, so that the new LoadModule
                  # directive always appears *outside* of an <container>.
  
                  my $before = 
                      ($content =~ m|^(.*\n)\#?\s*LoadModule\s+[^\n]+\n|s)[0];
  
                  # the '()=' trick forces list context and the scalar
                  # assignment counts the number of list members (aka number
                  # of matches) then
                  my $cntopen = () = ($before =~ m|^\s*<[^/].*$|mg);
                  my $cntclose = () = ($before =~ m|^\s*</.*$|mg);
  
                  if ($cntopen == $cntclose) {
                      # fine. Last LoadModule is contextless.
                      $content =~ s|^(.*\n\#?\s*LoadModule\s+[^\n]+\n)|$1$c$lmd\n|s;
                  }
                  elsif ($cntopen < $cntclose) {
                      error('Configuration file is not valid. There are sections'
                            . ' closed before opened.');
                      exit(1);
                  }
                  else {
                      # put our cmd after the section containing the last
                      # LoadModule.
                      my $found =
                          $content =~ s!\A (  # string and capture start
                                            (?:(?:
                                                ^\s*  # start of conf line with a
                                                (?:[^<]|<[^/]) # directive which
                                                               # does not
                                                               # start with '</'
                                                
                                                .*(?:$)\n  # rest of the line.
                                                   # the '$' is in parentheses
                                                   # to avoid misinterpreting
                                                   # the string "$\" as
                                                   # perl variable.
                                                   
                                                  )* # catch as much as possible
                                                     # of such lines. (including
                                                     # zero)
                                                
                                                ^\s*</.*(?:$)\n? 
                                                     # after the above, we
                                                     # expect a config line with
                                                     # a closing container (</)
                                                         
                                                        ) {$cntopen}       
                                                # the whole pattern (bunch
                                                # of lines that end up with
                                                # a closing directive) must
                                                # be repeated $cntopen
                                                # times. That's it.
                                                # Simple, eh? ;-)
                                      
                                               )  # capture end  
                                             !$1$c$lmd\n!mx;  
                      unless ($found) {
                          error('Configuration file is not valid. There are '
                                . 'sections opened and not closed.');
                          exit(1);
                      }
                  }
              }
              else {
                  # replace already existing LoadModule line
                  $content =~ s|^(.*\n)\#?\s*$lmd[^\n]*\n|$1$c$lmd\n|s;
              }
              $lmd =~ m|LoadModule\s+(.+?)_module.*|;
              notice("[$what module `$1' in $CFG_SYSCONFDIR/$CFG_SYSCONF]");
          } 
          my $amd;
          foreach $amd (@amd) {
              if ($content !~ m|\n\#?\s*$amd|) {
                  $content =~ s|^(.*\n\#?\s*AddModule\s+[^\n]+\n)|$1$c$amd\n|sg;
              } 
              else {
                  $content =~ s|^(.*\n)\#?\s*$amd[^\n]*\n|$1$c$amd\n|sg;
              }
          }
  
          if (@lmd or @amd) {
              if (open(FP, ">$CFG_SYSCONFDIR/$CFG_SYSCONF.new")) {
                  print FP $content;
                  close(FP);
                  copy("$CFG_SYSCONFDIR/$CFG_SYSCONF", 
                       "$CFG_SYSCONFDIR/$CFG_SYSCONF.bak") or
                           die "Backup of $CFG_SYSCONFDIR/$CFG_SYSCONF failed: $!";
                  copy("$CFG_SYSCONFDIR/$CFG_SYSCONF.new",
                       "$CFG_SYSCONFDIR/$CFG_SYSCONF") or
                           die "Copying $CFG_SYSCONFDIR/$CFG_SYSCONF.new to $CFG_SYSCONFDIR/$CFG_SYSCONF failed: $!";
                  unlink "$CFG_SYSCONFDIR/$CFG_SYSCONF.new" or
                      die "Removing $CFG_SYSCONFDIR/$CFG_SYSCONF.new failed: $!";
              } 
              else {
                  notice("unable to open configuration file");
              }
          }
      }
  }
  
  sub error{
      print STDERR "apxs:Error: $_[0].\n";
  }
  
  sub notice{
      print STDERR "$_[0]\n";
  }
  
  ##EOF##
  __DATA__
  ##
  ##  Makefile -- Build procedure for sample %NAME% Apache module
  ##  Autogenerated via ``apxs -n %NAME% -g''.
  ##
  
  builddir=.
  top_srcdir=%PREFIX%
  top_builddir=%PREFIX%
  
  #   the used tools
  APXS=apxs
  APACHECTL=Apache.exe -k
  
  #   additional defines, includes and libraries
  #DEFS=-Dmy_define=my_value
  #INCLUDES=-Imy/include/dir
  #LIBS=-Lmy/lib/dir -lmylib
  
  #   the default target
  all: local-shared-build
  
  #   install the shared object file into Apache 
  install: install-modules
  
  #   cleanup
  clean:
          -@erase mod_%NAME%.lo mod_%NAME%.ilk mod_%NAME%.so mod_%NAME%.lib mod_%NAME%.exp mod_%NAME%.pdb
  
  #   simple test
  test: reload
  	GET http://localhost/%NAME%
  
  #   install and activate shared object by reloading Apache to
  #   force a reload of the shared object file
  reload: install restart
  
  #   the general Apache start/restart/stop
  #   procedures
  start:
  	$(APACHECTL) start
  restart:
  	$(APACHECTL) restart
  stop:
  	$(APACHECTL) stop
  
  -=#=-
  /* 
  **  mod_%NAME%.c -- Apache sample %NAME% module
  **  [Autogenerated via ``apxs -n %NAME% -g'']
  **
  **  To play with this sample module first compile it into a
  **  DSO file and install it into Apache's modules directory 
  **  by running:
  **
  **    $ apxs -c -i mod_%NAME%.c
  **
  **  Then activate it in Apache's %SYSCONF% file for instance
  **  for the URL /%NAME% in as follows:
  **
  **    #   %SYSCONF%
  **    LoadModule %NAME%_module modules/mod_%NAME%.so
  **    <Location /%NAME%>
  **    SetHandler %NAME%
  **    </Location>
  **
  **  Then after restarting Apache via
  **
  **    $ apachectl restart
  **
  **  you immediately can request the URL /%NAME% and watch for the
  **  output of this module. This can be achieved for instance via:
  **
  **    $ lynx -mime_header http://localhost/%NAME% 
  **
  **  The output should be similar to the following one:
  **
  **    HTTP/1.1 200 OK
  **    Date: Tue, 31 Mar 1998 14:42:22 GMT
  **    Server: Apache/1.3.4 (Unix)
  **    Connection: close
  **    Content-Type: text/html
  **  
  **    The sample page from mod_%NAME%.c
  */ 
  
  #include "httpd.h"
  #include "http_config.h"
  #include "http_protocol.h"
  #include "ap_config.h"
  
  /* The sample content handler */
  static int %NAME%_handler(request_rec *r)
  {
      if (strcmp(r->handler, "%NAME%")) {
          return DECLINED;
      }
      r->content_type = "text/html";      
  
      if (!r->header_only)
          ap_rputs("The sample page from mod_%NAME%.c\n", r);
      return OK;
  }
  
  static void %NAME%_register_hooks(apr_pool_t *p)
  {
      ap_hook_handler(%NAME%_handler, NULL, NULL, APR_HOOK_MIDDLE);
  }
  
  /* Dispatch list for API hooks */
  module AP_MODULE_DECLARE_DATA %NAME%_module = {
      STANDARD20_MODULE_STUFF, 
      NULL,                  /* create per-dir    config structures */
      NULL,                  /* merge  per-dir    config structures */
      NULL,                  /* create per-server config structures */
      NULL,                  /* merge  per-server config structures */
      NULL,                  /* table of config file commands       */
      %NAME%_register_hooks  /* register hooks                      */
  };
  
  
  
  1.1                  httpd-apreq-2/win32/apxs_win32_PL
  
  Index: apxs_win32_PL
  ===================================================================
  #!C:/Perl/bin/perl
  use strict;
  use warnings;
  use Getopt::Long;
  require Win32;
  use Config;
  use ExtUtils::MakeMaker;
  my ($apache, $debug, $help);
  my $result = GetOptions( 'with-apache2=s' => \$apache,
  			 'help' => \$help,
                         );
  usage() if $help;
  
  my @path_ext;
  path_ext();
  $apache ||= search(); 
  (my $perl = which('perl')) =~ s!\\!/!g;
  my %subs_cfg = (
                  '%APACHE2%' => $apache,
                  '%AWK%' => which('awk') || which('gawk') || '',
                  '%CC%' => $Config{cc},
                  '%CPP%' => $Config{cpp},
                  '%SHELL%' => $ENV{COMSPEC},
                  '%LD%' => $Config{ld},
                 );
  
  my $pat = join '|', keys %subs_cfg;
  my $build_dir = $apache . '/build';
  my $cfg_mk = $build_dir . '/config_vars.mk';
  unless (-d $build_dir) {
      mkdir $build_dir or die "Cannot mkdir $build_dir: $!";
  }
  print "\nCreating $cfg_mk ...\n";
  open(my $cfg, ">$cfg_mk")
      or die qq{Cannot open $cfg_mk: $!};
  while (<DATA>) {
      s/($pat)/$subs_cfg{$1}/;
      print $cfg $_;
  }
  close $cfg;
  
  my %subs_apxs = (
                   '%perlbin%' => which('perl'),
                   '%exp_installbuilddir%' => $build_dir,
                   '%RM_F%' => qq{$perl -MExtUtils::Command -e rm_f},
                   '%CP%' => qq{$perl -MExtUtils::Command -e cp},
                   '%CHMOD%' => qq{$perl -MExtUtils::Command -e chmod},
                   '%TOUCH%' => qq{$perl -MExtUtils::Command -e touch},
                   );
  $pat = join '|', keys %subs_apxs;
  my $apxs_out = $apache . '/bin/apxs.pl';
  my $apxs_in = 'apxs_win32';
  print "Using template $apxs_in ...\n";
  open(my $out, ">$apxs_out")
      or die "Cannot open $apxs_out: $!";
  open(my $in, $apxs_in)
      or die "Cannot open $apxs_in: $!";
  print "Creating $apxs_out ...\n"; 
  while (<$in>) {
      s/($pat)/$subs_apxs{$1}/;
      print $out $_;
  }
  close $in;
  close $out;
  
  system ('pl2bat', $apxs_out) == 0 
      or die "system pl2bat $apxs_out failed: $?";
  print "An apxs bat file has been created under $apache/bin.\n\n";
  
  sub usage {
      print <<'END';
  
   Usage: perl Configure.pl [--with-apache2=C:\Path\to\Apache2]
          perl Configure.pl --help
  
  Options:
  
    --with-apache2=C:\Path\to\Apache2 : specify the top-level Apache2 directory
    --help                            : print this help message
  
  With no options specified, an attempt will be made to find a suitable 
  Apache2 directory.
  
  END
      exit;
  }
  
  sub search {
      my $apache;
    SEARCH: {
          my $candidate;
          if (my $bin = which('Apache')) {
              ($candidate = $bin) =~ s!bin$!!;
              if (-d $candidate and check($candidate)) {
                  $apache = $candidate;
                  last SEARCH;
              }
          }
          my @drives = drives();
          last SEARCH unless (@drives > 0);
          for my $drive (@drives) {
              for ('Apache2', 'Program Files/Apache2',
                   'Program Files/Apache Group/Apache2') {
                  $candidate = File::Spec->catpath($drive, $_);
                  if (-d $candidate and check($candidate)) {
                      $apache = $candidate;
                      last SEARCH;
                  }
              }
          }
      }
      unless (-d $apache) {
          $apache = prompt("Please give the path to your Apache2 installation:",
                           $apache);
      }
      die "Can't find a suitable Apache2 installation!" 
          unless (-d $apache and check($apache));
      
      $apache = Win32::GetShortPathName($apache);
      $apache =~ s!\\!/!g;
      my $ans = prompt(qq{\nUse "$apache" for your Apache2 directory?}, 'yes');
      unless ($ans =~ /^y/i) {
          die <<'END';
  
  Please run this configuration script again, and give
  the --with-apache2=C:\Path\to\Apache2 option to specify
  the desired top-level Apache2 directory.
  
  END
  
      }
      return $apache;
  }
  
  sub drives {
      my @drives = ();
      eval{require Win32API::File;};
      return map {"$_:\\"} ('C' .. 'Z') if $@;
      my @r = Win32API::File::getLogicalDrives();
      return unless @r > 0;
      for (@r) {
          my $t = Win32API::File::GetDriveType($_);
          push @drives, $_ if ($t == 3 or $t == 4);
      }
      return @drives > 0 ? @drives : undef;
  }
  
  sub check {
      my $apache = shift;
      die qq{No libhttpd library found under $apache/lib}
          unless -e qq{$apache/lib/libhttpd.lib};
      die qq{No httpd header found under $apache/include}
          unless -e qq{$apache/include/httpd.h};
      my $vers = qx{"$apache/bin/Apache.exe" -v};
      die qq{"$apache" does not appear to be version 2.0}
          unless $vers =~ m!Apache/2.0!;
      return 1;
  }
  
  sub path_ext {
      if ($ENV{PATHEXT}) {
          push @path_ext, split ';', $ENV{PATHEXT};
          for my $ext (@path_ext) {
              $ext =~ s/^\.*(.+)$/$1/;
          }
      }
      else {
          #Win9X: doesn't have PATHEXT
          push @path_ext, qw(com exe bat);
      }
  }
  
  sub which {
      my $program = shift;
      return undef unless $program;
      my @a = map {File::Spec->catfile($_, $program) } File::Spec->path();
      for my $base(@a) {
          return $base if -x $base;
          for my $ext (@path_ext) {
              return "$base.$ext" if -x "$base.$ext";
          }
      }
  }
  
  __DATA__
  exp_exec_prefix = %APACHE2%
  rel_exec_prefix =
  exp_bindir = %APACHE2%/bin
  rel_bindir = bin
  exp_sbindir = %APACHE2%/bin
  rel_sbindir = bin
  exp_libdir = %APACHE2%/lib
  rel_libdir = lib
  exp_libexecdir = %APACHE2%/modules
  rel_libexecdir = modules
  exp_sysconfdir = %APACHE2%/conf
  rel_sysconfdir = conf
  exp_datadir = %APACHE2%
  rel_datadir =
  exp_installbuilddir = %APACHE2%/build
  rel_installbuilddir = build
  exp_errordir = %APACHE2%/error
  rel_errordir = error
  exp_iconsdir = %APACHE2%/icons
  rel_iconsdir = icons
  exp_htdocsdir = %APACHE2%/htdocs
  rel_htdocsdir = htdocs
  exp_manualdir = %APACHE2%/manual
  rel_manualdir = manual
  exp_cgidir = %APACHE2%/cgi-bin
  rel_cgidir = cgi-bin
  exp_includedir = %APACHE2%/include
  rel_includedir = include
  exp_localstatedir = %APACHE2%
  rel_localstatedir =
  exp_runtimedir = %APACHE2%/logs
  rel_runtimedir = logs
  exp_logfiledir = %APACHE2%/logs
  rel_logfiledir = logs
  exp_proxycachedir = %APACHE2%/proxy
  rel_proxycachedir = proxy
  SHLTCFLAGS = 
  LTCFLAGS =
  MPM_NAME = winnt
  MPM_SUBDIR_NAME = winnt
  htpasswd_LTFLAGS =
  htdigest_LTFLAGS =
  rotatelogs_LTFLAGS =
  logresolve_LTFLAGS =
  htdbm_LTFLAGS =
  ab_LTFLAGS =
  checkgid_LTFLAGS =
  APACHECTL_ULIMIT =
  progname = Apache.exe
  MPM_LIB = server/mpm/winnt/
  OS = win32
  OS_DIR = win32
  BUILTIN_LIBS =
  SHLIBPATH_VAR = 
  OS_SPECIFIC_VARS =
  PRE_SHARED_CMDS =
  POST_SHARED_CMDS = 
  shared_build =
  AP_LIBS =
  AP_BUILD_SRCLIB_DIRS = apr apr-util
  AP_CLEAN_SRCLIB_DIRS = apr-util apr
  abs_srcdir = 
  bindir = ${exec_prefix}/bin
  sbindir = ${exec_prefix}/bin
  cgidir = ${datadir}/cgi-bin
  logfiledir = ${localstatedir}/logs
  exec_prefix = ${prefix}
  datadir = ${prefix}
  localstatedir = ${prefix}
  mandir = ${prefix}/man
  libdir = ${exec_prefix}/lib
  libexecdir = ${exec_prefix}/modules
  htdocsdir = ${datadir}/htdocs
  manualdir = ${datadir}/manual
  includedir = ${prefix}/include
  errordir = ${datadir}/error
  iconsdir = ${datadir}/icons
  sysconfdir = ${prefix}/conf
  sysconf = httpd.conf
  installbuilddir = ${datadir}/build
  runtimedir = ${localstatedir}/logs
  proxycachedir = ${localstatedir}/proxy
  other_targets =
  unix_progname = httpd
  prefix = %APACHE2%
  AWK = %AWK%
  CC = %CC%
  LD = %LD%
  CPP = %CPP%
  CXX =
  CPPFLAGS =
  CFLAGS = /nologo /MD /W3 /O2 /D "WIN32" /D "_WINDOWS" /D "NDEBUG"
  CXXFLAGS =
  LTFLAGS =
  LDFLAGS = kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /libpath:"${prefix}/lib"
  LT_LDFLAGS = 
  SH_LDFLAGS =
  HTTPD_LDFLAGS =
  UTIL_LDFLAGS =
  LIBS =
  DEFS =
  INCLUDES =
  NOTEST_CPPFLAGS = 
  NOTEST_CFLAGS =
  NOTEST_CXXFLAGS =
  NOTEST_LDFLAGS =
  NOTEST_LIBS =
  EXTRA_CPPFLAGS = 
  EXTRA_CFLAGS = 
  EXTRA_CXXFLAGS =
  EXTRA_LDFLAGS =
  EXTRA_LIBS =
  EXTRA_INCLUDES = 
  LIBTOOL = 
  SHELL = %SHELL%
  MODULE_DIRS = aaa filters loggers metadata proxy http generators mappers
  MODULE_CLEANDIRS = arch/win32 cache echo experimental ssl test dav/main dav/fs
  PORT = 80
  nonssl_listen_stmt_1 =
  nonssl_listen_stmt_2 = Listen @@Port@@
  CORE_IMPLIB_FILE =
  CORE_IMPLIB =
  SH_LIBS =
  SH_LIBTOOL =
  MK_IMPLIB =
  INSTALL_PROG_FLAGS =
  DSO_MODULES =
  APR_BINDIR = %APACHE2%/bin
  APR_INCLUDEDIR = 
  APU_BINDIR = %APACHE2%/bin
  APU_INCLUDEDIR =