| #!C:/Perl/bin/perl |
| use strict; |
| use warnings; |
| use FindBin; |
| use Getopt::Long; |
| use File::Spec::Functions qw(devnull catfile catdir path); |
| use Cwd; |
| require Win32; |
| use ExtUtils::MakeMaker; |
| use File::Basename; |
| use Archive::Tar; |
| use File::Path; |
| use LWP::Simple; |
| my ($apache, $debug, $help, $no_perl, $perl); |
| my $VERSION = '2.03-dev'; |
| my $result = GetOptions( 'with-apache2=s' => \$apache, |
| 'debug' => \$debug, |
| 'help' => \$help, |
| 'with-perl=s' => \$perl, |
| 'disable-perl-glue' => \$no_perl, |
| ); |
| usage() if $help; |
| |
| my @path_ext; |
| path_ext(); |
| $apache ||= search(); |
| my $apreq_home = Win32::GetShortPathName($FindBin::Bin); |
| $apreq_home =~ s!/?win32$!!; |
| $apreq_home =~ s!/!\\!g; |
| |
| my $doxygen = which('doxygen'); |
| my $doxysearch = which('doxysearch'); |
| my $cfg = $debug ? 'Debug' : 'Release'; |
| |
| check_depends(); |
| |
| my @tests = qw(cookie parsers params version); |
| my @test_files = map {catfile('t', "$_.t")} @tests; |
| generate_tests($apreq_home, \@tests); |
| |
| my %apr_libs; |
| my %map = (apr => 'libapr.lib', apu => 'libaprutil.lib'); |
| my $devnull = devnull(); |
| foreach (qw(apr apu)) { |
| my $cfg = catfile $apache, 'bin', "$_.bat"; |
| $cfg =~ s!\\!/!g; |
| my $lib; |
| eval {$lib = qx{"$cfg" --$_-lib-file 2>$devnull;}}; |
| if ($@ or not $lib or $lib =~ /usage/i) { |
| $apr_libs{$_} = catfile $apache, 'lib', $map{$_}; |
| } |
| else { |
| $apr_libs{$_} = chomp $lib; |
| } |
| } |
| |
| open(my $make, '>Makefile') or die qq{Cannot open Makefile: $!}; |
| print $make <<"END"; |
| # Microsoft Developer Studio Generated NMAKE File. |
| |
| APREQ_HOME=$apreq_home |
| APR_LIB=$apr_libs{apr} |
| APU_LIB=$apr_libs{apu} |
| CFG=$cfg |
| APACHE=$apache |
| PERL=$^X |
| RM_F=\$(PERL) -MExtUtils::Command -e rm_f |
| DOXYGEN_CONF=\$(APREQ_HOME)\\build\\doxygen.conf.win32 |
| TEST_FILES = @test_files |
| END |
| |
| print $make $_ while (<DATA>); |
| |
| my $apxs_trial = catfile $apache, 'bin', 'apxs.bat'; |
| my $apxs = (-e $apxs_trial) ? $apxs_trial : which('apxs'); |
| unless ($apxs) { |
| $apxs = fetch_apxs() ? which('apxs') : ''; |
| } |
| |
| my $test = << 'END'; |
| TEST: $(LIBAPREQ) $(MOD) |
| $(MAKE) /nologo /f $(CFG_HOME)\$(APREQ2_TEST).mak CFG="$(APREQ2_TEST) - Win32 $(CFG)" APACHE="$(APACHE)" APREQ_HOME="$(APREQ_HOME)" APR_LIB="$(APR_LIB)" APU_LIB="$(APU_LIB)" |
| set PATH=$(APREQ_HOME)\win32\libs;$(APACHE)\bin;$(PATH) |
| $(PERL) "-MExtUtils::Command::MM" "-e" "test_harness()" $(TEST_FILES) |
| cd $(APREQ_HOME) |
| $(MAKE) /nologo /f $(CFG_HOME)\$(CGITEST).mak CFG="$(CGITEST) - Win32 $(CFG)" APACHE="$(APACHE)" APREQ_HOME="$(APREQ_HOME)" APR_LIB="$(APR_LIB)" APU_LIB="$(APU_LIB)" |
| if not exist "$(APREQ_ENV)\t\cgi-bin" mkdir "$(APREQ_ENV)\t\cgi-bin" |
| copy $(LIBDIR)\test_cgi.exe $(APREQ_ENV)\t\cgi-bin\test_cgi.exe |
| cd $(APREQ_HOME) |
| END |
| |
| my $clean = << 'END'; |
| CLEAN: |
| cd $(LIBDIR) |
| $(RM_F) *.pch *.exe *.exp *.lib *.pdb *.ilk *.idb *.so *.dll *.obj |
| cd $(TDIR) |
| $(RM_F) *.pch *.exe *.exp *.lib *.pdb *.ilk *.idb *.so *.dll *.obj |
| cd $(APREQ_ENV) |
| $(PERL) t\TEST.PL -clean |
| cd $(APREQ_HOME) |
| !IF EXIST("$(PERLGLUE)\Makefile") |
| cd $(PERLGLUE) |
| $(MAKE) /nologo clean |
| cd $(APREQ_HOME) |
| !ENDIF |
| END |
| |
| if ($apxs) { |
| $test .= << "END"; |
| cd \$(APREQ_ENV) |
| \$(PERL) t\\TEST.PL -apxs $apxs |
| cd \$(APREQ_HOME) |
| END |
| $clean .= << 'END'; |
| cd $(APREQ_ENV) |
| $(PERL) t\TEST.PL -clean |
| cd $(APREQ_HOME) |
| END |
| } |
| |
| print $make "\n", $test, "\n"; |
| print $make "\n", $clean, "\n"; |
| |
| if ($doxygen and $doxysearch) { |
| print $make <<"END"; |
| |
| docs: \$(DOXYGEN_CONF) |
| cd \$(APREQ_HOME) |
| "$doxygen" \$(DOXYGEN_CONF) |
| cd \$(APREQ_HOME) |
| |
| END |
| |
| my $bin_abspath = Win32::GetShortPathName(dirname($doxysearch)); |
| open(my $conf, "$apreq_home/build/doxygen.conf.in") |
| or die "Cannot read $apreq_home/build/doxygen.conf.in: $!"; |
| open(my $win32_conf, ">$apreq_home/build/doxygen.conf.win32") |
| or die "Cannot write to $apreq_home/build/doxygen.conf.win32: $!"; |
| while (<$conf>) { |
| s/\@PERL\@/"$^X"/; |
| s/\@PACKAGE\@/libapreq2/; |
| s/\@VERSION\@/$VERSION/; |
| print $win32_conf $_; |
| } |
| close $conf; |
| close $win32_conf; |
| } |
| |
| close $make; |
| # generate_defs(); |
| |
| if (not $no_perl and $] >= 5.008) { |
| my @args = ($^X, "$apreq_home/build/xsbuilder.pl", 'run', 'run'); |
| chdir "$apreq_home/glue/perl"; |
| system(@args) == 0 or die "system @args failed: $?"; |
| chdir $apreq_home; |
| } |
| |
| print << "END"; |
| |
| A Makefile has been generated in $apreq_home. |
| You can now run |
| |
| nmake - builds the libapreq2 library |
| nmake test - runs the supplied tests |
| nmake mod_apreq - builds mod_apreq |
| nmake clean - clean |
| nmake install - install the C libraries |
| nmake perl_glue - build the perl glue |
| nmake perl_test - test the perl glue |
| nmake perl_install - install the perl glue |
| nmake help - list the nmake targets |
| END |
| if ($doxygen) { |
| print << 'END'; |
| nmake docs - builds documents |
| |
| END |
| } |
| |
| my @args = ($^X, "$apreq_home/win32/apreq2_win32.pl", |
| "--with-apache2=$apache"); |
| system(@args) == 0 or warn "system @args failed: $?"; |
| |
| sub usage { |
| print <<'END'; |
| |
| Usage: perl Configure.pl [--with-apache2=C:\Path\to\Apache2] [--debug] |
| perl Configure.pl --help |
| |
| Options: |
| |
| --with-apache2=C:\Path\to\Apache2 : specify the top-level Apache2 directory |
| --debug : build a debug version |
| --disable-perl-glue : skip building the perl glue |
| --help : print this 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. |
| |
| END |
| exit; |
| } |
| |
| sub search { |
| my $apache; |
| if (my $bin = which('Apache')) { |
| (my $candidate = dirname($bin)) =~ s!bin$!!; |
| if (-d $candidate and check($candidate)) { |
| $apache = $candidate; |
| } |
| } |
| unless ($apache and -d $apache) { |
| $apache = prompt("Please give the path to your Apache2 installation:", |
| $apache); |
| } |
| die "Can't find a suitable Apache2 installation!" |
| unless ($apache and -d $apache and check($apache)); |
| |
| $apache = Win32::GetShortPathName($apache); |
| $apache =~ s!\\!/!g; |
| $apache =~ s!/$!!; |
| 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.x} |
| unless $vers =~ m!Apache/2.\d!; |
| 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 unless $program; |
| my @extras = (); |
| my @drives = drives(); |
| (my $program_files = $ENV{ProgramFiles}) =~ s!^\w+:\\!!; |
| if (@drives > 0) { |
| for my $drive (@drives) { |
| for ('Apache2', "$program_files/Apache2", |
| "$program_files/Apache Group/Apache2") { |
| my $bin = catdir $drive, $_, 'bin'; |
| push @extras, $bin if (-d $bin); |
| } |
| } |
| } |
| my @a = map {catfile $_, $program} |
| (path(), @extras); |
| for my $base(@a) { |
| return $base if -x $base; |
| for my $ext (@path_ext) { |
| return "$base.$ext" if -x "$base.$ext"; |
| } |
| } |
| return; |
| } |
| |
| sub generate_defs { |
| my $preamble =<<'END'; |
| LIBRARY |
| |
| EXPORTS |
| |
| END |
| chdir "$apreq_home/env"; |
| my $match = qr{^apreq_env}; |
| my %fns = (); |
| open my $fh, "<mod_apreq.c" |
| or die "Cannot open env/mod_apreq.c: $!"; |
| while (<$fh>) { |
| next unless /^APREQ_DECLARE\([^\)]+\)\s*(\w+)/; |
| my $fn = $1; |
| $fns{$fn}++ if $fn =~ /$match/; |
| } |
| close $fh; |
| open my $def, ">../win32/mod_apreq.def" |
| or die "Cannot open win32/mod_apreq.def: $!"; |
| print $def $preamble; |
| print $def $_, "\n" for (sort keys %fns); |
| close $def; |
| } |
| |
| sub check_depends { |
| my $rep = $] < 5.008 ? |
| 'http://theoryx5.uwinnipeg.ca/ppmpackages' : |
| 'http://theoryx5.uwinnipeg.ca/ppms'; |
| eval {require Apache2;}; |
| for my $mod (qw(ExtUtils::XSBuilder Apache::Test)) { |
| eval "require $mod"; |
| if ($@) { |
| if ($] < 5.008 and $mod eq 'ExtUtils::XSBuilder') { |
| warn "Perl 5.8 or higher is required for the Perl glue\n"; |
| next; |
| } |
| print "I could not find $mod. "; |
| my $ans = prompt('Would you like to install it?', 'yes'); |
| next unless $ans =~ /^y/i; |
| (my $ppd = $mod) =~ s!(\w+)::(\w+)!$1-$2.ppd!; |
| my @args = ('ppm', 'install', "$rep/$ppd"); |
| system(@args) == 0 |
| or warn "system @args failed: $?"; |
| } |
| } |
| } |
| |
| sub generate_tests { |
| my ($top, $test_files) = @_; |
| my $t = catdir $top, 't'; |
| foreach my $test(@$test_files) { |
| my $file = catfile $t, $test; |
| open my $fh, '>', "$file.t" || die "Cannot open $file.t: $!"; |
| print $fh <<"EOT"; |
| #!$^X |
| exec '$file'; |
| EOT |
| close $fh; |
| } |
| } |
| |
| sub fetch_apxs { |
| print << 'END'; |
| |
| I could not find an apxs utility on your system, which is |
| needed to run tests in the env/ subdirectory. The apxs |
| utiltity (and apr-config and apu-config utilties) have not |
| yet been ported to Apache2 on Win32, but a development port |
| is available, which I can install for you, if you like. |
| |
| END |
| |
| my $ans = prompt('Install apxs?', 'yes'); |
| return unless $ans =~ /^y/i; |
| my $file = 'apxs_win32.tar.gz'; |
| my $remote = 'http://perl.apache.org/dist/win32-bin/' . $file; |
| print "Fetching $remote ... "; |
| unless (is_success(getstore($remote, $file))) { |
| warn "Download of $remote failed"; |
| return; |
| } |
| print " done!\n"; |
| |
| my $arc = Archive::Tar->new($file, 1); |
| $arc->extract($arc->list_files()); |
| my $dir = 'apxs'; |
| unless (-d $dir) { |
| warn "Unpacking $file failed"; |
| return; |
| } |
| print "chdir $dir\n"; |
| chdir $dir or do { |
| warn "chdir to $dir failed: $!"; |
| return; |
| }; |
| my @args = ($^X, 'Configure.pl', "-with-apache2=$apache"); |
| print "@args\n\n"; |
| system(@args) == 0 or do { |
| warn "system @args failed: $?"; |
| return; |
| }; |
| chdir '..'; |
| rmtree($dir, 1, 1) or warn "rmtree of $dir failed: $!"; |
| print "unlink $file\n"; |
| unlink $file or warn "unlink of $file failed: $!"; |
| return 1; |
| } |
| |
| __DATA__ |
| |
| LIBAPREQ=libapreq2 |
| APREQ2_TEST=apreq2_test |
| CGITEST=test_cgi |
| MOD=mod_apreq |
| |
| !IF "$(CFG)" != "Release" && "$(CFG)" != "Debug" |
| !MESSAGE Invalid configuration "$(CFG)" specified. |
| !MESSAGE You can specify a configuration when running NMAKE |
| !MESSAGE by defining the macro CFG on the command line. For example: |
| !MESSAGE |
| !MESSAGE NMAKE CFG="Release" |
| !MESSAGE |
| !MESSAGE Possible choices for configuration are: |
| !MESSAGE |
| !MESSAGE "Release" (based on "Win32 (x86) Console Application") |
| !MESSAGE "Debug" (based on "Win32 (x86) Console Application") |
| !MESSAGE |
| !ERROR An invalid configuration is specified. |
| !ENDIF |
| |
| !IF "$(APACHE)" == "" |
| !MESSAGE No Apache directory was specified. |
| !MESSAGE Please run Configure.bat to specify a valid Apache directory. |
| !ERROR |
| !ENDIF |
| |
| !IF "$(OS)" == "Windows_NT" |
| NULL= |
| !ELSE |
| NULL=nul |
| !ENDIF |
| |
| CFG_HOME=$(APREQ_HOME)\win32 |
| LIBDIR=$(CFG_HOME)\libs |
| PERLGLUE=$(APREQ_HOME)\glue\perl |
| APACHE_LIB=$(APACHE)\lib |
| APREQ_ENV=$(APREQ_HOME)\env |
| TDIR=$(APREQ_HOME)\t |
| |
| ALL : "$(LIBAPREQ)" |
| |
| $(LIBAPREQ): |
| $(MAKE) /nologo /f $(CFG_HOME)\$(LIBAPREQ).mak CFG="$(LIBAPREQ) - Win32 $(CFG)" APACHE="$(APACHE)" APREQ_HOME="$(APREQ_HOME)" APR_LIB="$(APR_LIB)" APU_LIB="$(APU_LIB)" |
| |
| $(MOD): $(LIBAPREQ) |
| $(MAKE) /nologo /f $(CFG_HOME)\$(MOD).mak CFG="$(MOD) - Win32 $(CFG)" APACHE="$(APACHE)" APREQ_HOME="$(APREQ_HOME)" APR_LIB="$(APR_LIB)" APU_LIB="$(APU_LIB)" |
| |
| PERL_GLUE: $(MOD) |
| cd $(PERLGLUE) |
| $(PERL) Makefile.PL |
| $(MAKE) /nologo |
| cd $(APREQ_HOME) |
| |
| PERL_TEST: $(MOD) |
| cd $(PERLGLUE) |
| !IF !EXIST("$(PERLGLUE)\Makefile") |
| $(PERL) Makefile.PL |
| !ENDIF |
| set PATH=$(APREQ_HOME)\win32\libs;$(APACHE)\bin;$(PATH) |
| $(MAKE) /nologo test |
| cd $(APREQ_HOME) |
| |
| PERL_INSTALL: $(MOD) |
| cd $(PERLGLUE) |
| !IF !EXIST("$(PERLGLUE)\Makefile") |
| $(PERL) Makefile.PL |
| !ENDIF |
| $(MAKE) /nologo install |
| cd $(APREQ_HOME) |
| |
| INSTALL: $(LIBAPREQ) |
| cd $(LIBDIR) |
| !IF EXIST("$(LIBDIR)\$(MOD).so") |
| copy "$(MOD).so" "$(APACHE)\modules\$(MOD).so" |
| copy "$(MOD).lib" "$(APACHE_LIB)\$(MOD).lib" |
| !ENDIF |
| !IF EXIST("$(LIBDIR)\$(LIBAPREQ).lib") |
| copy "$(LIBAPREQ).lib" "$(APACHE_LIB)\$(LIBAPREQ).lib" |
| !ENDIF |
| !IF EXIST("$(LIBDIR)\$(LIBAPREQ).dll") |
| copy "$(LIBAPREQ).dll" "$(APACHE)\bin\$(LIBAPREQ).dll" |
| !ENDIF |
| cd $(APREQ_HOME) |
| |
| HELP: |
| @echo nmake - builds the libapreq2 library |
| @echo nmake test - runs the supplied tests |
| @echo nmake mod_apreq - builds mod_apreq |
| @echo nmake clean - clean |
| @echo nmake install - install the C libraries |
| @echo nmake perl_glue - build the perl glue |
| @echo nmake perl_test - test the perl glue |
| @echo nmake perl_install - install the perl glue |
| @echo nmake docs - builds documents (requires doxygen) |