summaryrefslogtreecommitdiffstats
path: root/debian/perl-framework/Apache-Test/lib/Apache/TestBuild.pm
diff options
context:
space:
mode:
Diffstat (limited to 'debian/perl-framework/Apache-Test/lib/Apache/TestBuild.pm')
-rw-r--r--debian/perl-framework/Apache-Test/lib/Apache/TestBuild.pm699
1 files changed, 699 insertions, 0 deletions
diff --git a/debian/perl-framework/Apache-Test/lib/Apache/TestBuild.pm b/debian/perl-framework/Apache-Test/lib/Apache/TestBuild.pm
new file mode 100644
index 0000000..f0004e6
--- /dev/null
+++ b/debian/perl-framework/Apache-Test/lib/Apache/TestBuild.pm
@@ -0,0 +1,699 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+package Apache::TestBuild;
+
+use strict;
+use warnings FATAL => 'all';
+
+use subs qw(system chdir
+ info warning);
+
+use Config;
+use File::Spec::Functions;
+use File::Path ();
+use Cwd ();
+
+use constant DRYRUN => 0;
+
+my @min_modules = qw(access auth log-config env mime setenvif
+ mime autoindex dir alias);
+
+my %shared_modules = (
+ min => join(' ', @min_modules),
+);
+
+my %configs = (
+ all => {
+ 'apache-1.3' => [],
+ 'httpd-2.0' => enable20(qw(modules=all proxy)),
+ },
+ most => {
+ 'apache-1.3' => [],
+ 'httpd-2.0' => enable20(qw(modules=most)),
+ },
+ min => {
+ 'apache-1.3' => [],
+ 'httpd-2.0' => enable20(@min_modules),
+ },
+ exp => {
+ 'apache-1.3' => [],
+ 'httpd-2.0' => enable20(qw(example case_filter
+ case_filter_in cache
+ echo deflate bucketeer)),
+ },
+);
+
+my %builds = (
+ default => {
+ cflags => '-Wall',
+ config => {
+ 'apache-1.3' => [],
+ 'httpd-2.0' => [],
+ },
+ },
+ debug => {
+ cflags => '-g',
+ config => {
+ 'apache-1.3' => [],
+ 'httpd-2.0' => [qw(--enable-maintainer-mode)],
+ },
+ },
+ prof => {
+ cflags => '-pg -DGPROF',
+ },
+ shared => {
+ config => {
+ 'apache-1.3' => [],
+ 'httpd-2.0' => enable20_shared('all'),
+ },
+ },
+ mostshared => {
+ config => {
+ 'apache-1.3' => [],
+ 'httpd-2.0' => enable20_shared('most'),
+ },
+ },
+ minshared => {
+ config => {
+ 'apache-1.3' => [],
+ 'httpd-2.0' => enable20_shared('min'),
+ },
+ },
+ static => {
+ },
+);
+
+my %mpms = (
+ default => [qw(prefork worker)],
+ MSWin32 => [qw(winnt)],
+);
+
+my @cvs = qw(httpd-2.0 apache-1.3);
+
+my @dirs = qw(build tar src install);
+
+sub enable20 {
+ [ map { "--enable-$_" } @_ ];
+}
+
+sub enable20_shared {
+ my $name = shift;
+ my $modules = $shared_modules{$name} || $name;
+ enable20(qq(mods-shared="$modules"));
+}
+
+sub default_mpms {
+ $mpms{ $^O } || $mpms{'default'};
+}
+
+sub default_dir {
+ my($self, $dir) = @_;
+ $self->{$dir} ||= catdir $self->{prefix}, $dir,
+}
+
+sub new {
+ my $class = shift;
+
+ #XXX: not generating a BUILD script yet
+ #this way we can run:
+ #perl Apache-Test/lib/Apache/TestBuild.pm --cvsroot=anon --foo=...
+
+ require Apache::TestConfig;
+ require Apache::TestTrace;
+ Apache::TestTrace->import;
+
+ my $self = bless {
+ prefix => '/usr/local/apache',
+ cwd => Cwd::cwd(),
+ cvsroot => 'cvs.apache.org:/home/cvs',
+ cvs => \@cvs,
+ cvstag => "",
+ ssldir => "",
+ mpms => default_mpms(),
+ make => $Config{make},
+ builds => {},
+ name => "",
+ extra_config => {
+ 'httpd-2.0' => [],
+ },
+ @_,
+ }, $class;
+
+ #XXX
+ if (my $c = $self->{extra_config}->{'2.0'}) {
+ $self->{extra_config}->{'httpd-2.0'} = $c;
+ }
+
+ for my $dir (@dirs) {
+ $self->default_dir($dir);
+ }
+
+ if ($self->{ssldir}) {
+ push @{ $self->{extra_config}->{'httpd-2.0'} },
+ '--enable-ssl', "--with-ssl=$self->{ssldir}";
+ }
+
+ $self;
+}
+
+sub init {
+ my $self = shift;
+
+ for my $dir (@dirs) {
+ mkpath($self->{$dir});
+ }
+}
+
+use subs qw(symlink unlink);
+use File::Basename;
+use File::Find;
+
+sub symlink_tree {
+ my $self = shift;
+
+ my $httpd = 'httpd';
+ my $install = "$self->{install}/bin/$httpd";
+ my $source = "$self->{build}/.libs/$httpd";
+
+ unlink $install;
+ symlink $source, $install;
+
+ my %dir = (apr => 'apr',
+ aprutil => 'apr-util');
+
+ for my $libname (qw(apr aprutil)) {
+ my $lib = "lib$libname.so.0.0.0";
+ my $install = "$self->{install}/lib/$lib";
+ my $source = "$self->{build}/srclib/$dir{$libname}/.libs/$lib";
+
+ unlink $install;
+ symlink $source, $install;
+ }
+
+ $install = "$self->{install}/modules";
+ $source = "$self->{build}/modules";
+
+ for (<$install/*.so>) {
+ unlink $_;
+ }
+
+ finddepth(sub {
+ return unless /\.so$/;
+ my $file = "$File::Find::dir/$_";
+ symlink $file, "$install/$_";
+ }, $source);
+}
+
+sub unlink {
+ my $file = shift;
+
+ if (-e $file) {
+ print "unlink $file\n";
+ }
+ else {
+ print "$file does not exist\n";
+ }
+ CORE::unlink($file);
+}
+
+sub symlink {
+ my($from, $to) = @_;
+ print "symlink $from => $to\n";
+ unless (-e $from) {
+ print "source $from does not exist\n";
+ }
+ my $base = dirname $to;
+ unless (-e $base) {
+ print "target dir $base does not exist\n";
+ }
+ CORE::symlink($from, $to) or die $!;
+}
+
+sub cvs {
+ my $self = shift;
+
+ my $cmd = "cvs -d $self->{cvsroot} @_";
+
+ if (DRYRUN) {
+ info "$cmd";
+ }
+ else {
+ system $cmd;
+ }
+}
+
+my %cvs_names = (
+ '2.0' => 'httpd-2.0',
+ '1.3' => 'apache-1.3',
+);
+
+my %cvs_snames = (
+ '2.0' => 'httpd',
+ '1.3' => 'apache',
+);
+
+sub cvs_up {
+ my($self, $version) = @_;
+
+ my $name = $cvs_names{$version};
+
+ my $dir = $self->srcdir($version);
+
+ if ($self->{cvsroot} eq 'anon') {
+ $self->{cvsroot} = ':pserver:anoncvs@cvs.apache.org:/home/cvspublic';
+ unless (-d $dir) {
+ #XXX do something better than doesn't require prompt if
+ #we already have an entry in ~/.cvspass
+ #$self->cvs('login');
+
+ warning "may need to run the following command ",
+ "(password is 'anoncvs')";
+ warning "cvs -d $self->{cvsroot} login";
+ }
+ }
+
+ if (-d $dir) {
+ chdir $dir;
+ $self->cvs(up => "-dP $self->{cvstag}");
+ return;
+ }
+
+ my $co = checkout($name);
+ $self->$co($name, $dir);
+
+ my $post = post_checkout($name);
+ $self->$post($name, $dir);
+}
+
+sub checkout_httpd_2_0 {
+ my($self, $name, $dir) = @_;
+
+ my $tag = $self->{cvstag};
+
+ $self->cvs(co => "-d $dir $tag $name");
+ chdir "$dir/srclib";
+ $self->cvs(co => "$tag apr apr-util");
+}
+
+sub checkout_apache_1_3 {
+ my($self, $name, $dir) = @_;
+
+ $self->cvs(co => "-d $dir $self->{cvstag} $name");
+}
+
+sub post_checkout_httpd_2_0 {
+ my($self, $name, $dir) = @_;
+}
+
+sub post_checkout_apache_1_3 {
+}
+
+sub canon {
+ my $name = shift;
+ return $name unless $name;
+ $name =~ s/[.-]/_/g;
+ $name;
+}
+
+sub checkout {
+ my $name = canon(shift);
+ \&{"checkout_$name"};
+}
+
+sub post_checkout {
+ my $name = canon(shift);
+ \&{"post_checkout_$name"};
+}
+
+sub cvs_update {
+ my $self = shift;
+
+ my $cvs = shift || $self->{cvs};
+
+ chdir $self->{src};
+
+ for my $name (@$cvs) {
+ $self->cvs_up($name);
+ }
+}
+
+sub merge_build {
+ my($self, $version, $builds, $configs) = @_;
+
+ my $b = {
+ cflags => $builds{default}->{cflags},
+ config => [ @{ $builds{default}->{config}->{$version} } ],
+ };
+
+ for my $name (@$builds) {
+ next if $name eq 'default'; #already have this
+
+ if (my $flags = $builds{$name}->{cflags}) {
+ $b->{cflags} .= " $flags";
+ }
+ if (my $cfg = $builds{$name}->{config}) {
+ if (my $vcfg = $cfg->{$version}) {
+ push @{ $b->{config} }, @$vcfg;
+ }
+ }
+ }
+
+ for my $name (@$configs) {
+ my $cfg = $configs{$name}->{$version};
+ next unless $cfg;
+ push @{ $b->{config} }, @$cfg;
+ }
+
+ if (my $ex = $self->{extra_config}->{$version}) {
+ push @{ $b->{config} }, @$ex;
+ }
+
+ if (my $ex = $self->{extra_cflags}->{$version}) {
+ $b->{config} .= " $ex";
+ }
+
+ $b;
+}
+
+my @srclib_dirs = qw(
+ apr apr-util apr-util/xml/expat pcre
+);
+
+sub install_name {
+ my($self, $builds, $configs, $mpm) = @_;
+
+ return $self->{name} if $self->{name};
+
+ my $name = join '-', $mpm, @$builds, @$configs;
+
+ if (my $tag = $self->cvs_name) {
+ $name .= "-$tag";
+ }
+
+ $name;
+}
+
+#currently the httpd-2.0 build does not properly support static linking
+#of ssl libs, force the issue
+sub add_ssl_libs {
+ my $self = shift;
+
+ my $ssldir = $self->{ssldir};
+
+ return unless $ssldir and -d $ssldir;
+
+ my $name = $self->{current_install_name};
+
+ my $ssl_mod = "$name/modules/ssl";
+ info "editing $ssl_mod/modules.mk";
+
+ if (DRYRUN) {
+ return;
+ }
+
+ my $ssl_mk = "$self->{build}/$ssl_mod/modules.mk";
+
+ open my $fh, $ssl_mk or die "open $ssl_mk: $!";
+ my @lines = <$fh>;
+ close $fh;
+
+ for (@lines) {
+ next unless /SH_LINK/;
+ chomp;
+ $_ .= " -L$ssldir -lssl -lcrypto\n";
+ info 'added ssl libs';
+ last;
+ }
+
+ open $fh, '>', $ssl_mk or die $!;
+ print $fh join "\n", @lines;
+ close $fh;
+}
+
+sub cvs_name {
+ my $self = shift;
+
+ if (my $tag = $self->{cvstag}) {
+ $tag =~ s/^-[DAr]//;
+ $tag =~ s/\"//g;
+ $tag =~ s,[/ :],_,g; #-D"03/29/02 07:00pm"
+ return $tag;
+ }
+
+ return "";
+}
+
+sub srcdir {
+ my($self, $src) = @_;
+
+ my $prefix = "";
+ if ($src =~ s/^(apache|httpd)-//) {
+ $prefix = $1;
+ }
+ else {
+ $prefix = $cvs_snames{$src};
+ }
+
+ if ($src =~ /^\d\.\d$/) {
+ #release version will be \d\.\d\.\d+
+ if (my $tag = $self->cvs_name) {
+ $src .= "-$tag";
+ }
+ $src .= '-cvs';
+ }
+
+ join '-', $prefix, $src;
+}
+
+sub configure_httpd_2_0 {
+ my($self, $src, $builds, $configs, $mpm) = @_;
+
+ $src = $self->srcdir($src);
+
+ chdir $self->{build};
+
+ my $name = $self->install_name($builds, $configs, $mpm);
+
+ $self->{current_install_name} = $name;
+
+ $self->{builds}->{$name} = 1;
+
+ if ($self->{fresh}) {
+ rmtree($name);
+ }
+ else {
+ if (-e "$name/.DONE") {
+ warning "$name already configured";
+ warning "rm $name/.DONE to force";
+ return;
+ }
+ }
+
+ my $build = $self->merge_build('httpd-2.0', $builds, $configs);
+
+ $ENV{CFLAGS} = $build->{cflags};
+ info "CFLAGS=$ENV{CFLAGS}";
+
+ my $prefix = "$self->{install}/$name";
+
+ rmtree($prefix) if $self->{fresh};
+
+ my $source = "$self->{src}/$src";
+
+ my @args = ("--prefix=$prefix",
+ "--with-mpm=$mpm",
+ "--srcdir=$source",
+ @{ $build->{config} });
+
+ chdir $source;
+ system "./buildconf";
+
+ my $cmd = "$source/configure @args";
+
+ chdir $self->{build};
+
+ mkpath($name);
+ chdir $name;
+
+ for my $dir (@srclib_dirs) {
+ mkpath("srclib/$dir");
+ }
+
+ for my $dir (qw(build docs/conf)) {
+ mkpath($dir);
+ }
+
+ system $cmd;
+
+ open FH, ">.DONE" or die "open .DONE: $!";
+ print FH scalar localtime;
+ close FH;
+
+ chdir $self->{prefix};
+
+ $self->add_ssl_libs;
+}
+
+sub make {
+ my($self, @cmds) = @_;
+
+ push @cmds, 'all' unless @cmds;
+
+ for my $name (keys %{ $self->{builds} }) {
+ chdir "$self->{build}/$name";
+ for my $cmd (@cmds) {
+ system "$self->{make} $cmd";
+ }
+ }
+}
+
+sub system {
+ my $cmd = "@_";
+
+ info $cmd;
+ return if DRYRUN;
+
+ unless (CORE::system($cmd) == 0) {
+ my $status = $? >> 8;
+ die "system $cmd failed (exit status=$status)";
+ }
+}
+
+sub chdir {
+ my $dir = shift;
+ info "chdir $dir";
+ CORE::chdir $dir;
+}
+
+sub mkpath {
+ my $dir = shift;
+
+ return if -d $dir;
+ info "mkpath $dir";
+
+ return if DRYRUN;
+ File::Path::mkpath([$dir], 1, 0755);
+}
+
+sub rmtree {
+ my $dir = shift;
+
+ return unless -d $dir;
+ info "rmtree $dir";
+
+ return if DRYRUN;
+ File::Path::rmtree([$dir], 1, 1);
+}
+
+sub generate_script {
+ my($class, $file) = @_;
+
+ $file ||= catfile 't', 'BUILD';
+
+ my $content = join '', <DATA>;
+
+ Apache::Test::basic_config()->write_perlscript($file, $content);
+}
+
+unless (caller) {
+ $INC{'Apache/TestBuild.pm'} = __FILE__;
+ eval join '', <DATA>;
+ die $@ if $@;
+}
+
+1;
+__DATA__
+use strict;
+use warnings FATAL => 'all';
+
+use lib qw(Apache-Test/lib);
+use Apache::TestBuild ();
+use Getopt::Long qw(GetOptions);
+use Cwd ();
+
+my %options = (
+ prefix => "checkout/build/install prefix",
+ ssldir => "enable ssl with given directory",
+ cvstag => "checkout with given cvs tag",
+ cvsroot => "use 'anon' for anonymous cvs",
+ version => "apache version (e.g. '2.0')",
+ mpms => "MPMs to build (e.g. 'prefork')",
+ flavor => "build flavor (e.g. 'debug shared')",
+ modules => "enable modules (e.g. 'all exp')",
+ name => "change name of the build/install directory",
+);
+
+my %opts;
+
+Getopt::Long::Configure(qw(pass_through));
+#XXX: could be smarter here, being lazy for the moment
+GetOptions(\%opts, map "$_=s", sort keys %options);
+
+if (@ARGV) {
+ print "passing extra args to configure: @ARGV\n";
+}
+
+my $home = $ENV{HOME};
+
+$opts{prefix} ||= join '/', Cwd::cwd(), 'farm';
+#$opts{ssldir} ||= '';
+#$opts{cvstag} ||= '';
+#$opts{cvsroot} ||= '';
+$opts{version} ||= '2.0';
+$opts{mpms} ||= 'prefork';
+$opts{flavor} ||= 'debug-shared';
+$opts{modules} ||= 'all-exp';
+
+#my @versions = qw(2.0);
+
+#my @mpms = qw(prefork worker perchild);
+
+#my @flavors = ([qw(debug shared)], [qw(prof shared)],
+# [qw(debug static)], [qw(prof static)]);
+
+#my @modules = ([qw(all exp)]);
+
+my $split = sub { split '-', delete $opts{ $_[0] } };
+
+my @versions = $opts{version};
+
+my @mpms = $split->('mpms');
+
+my @flavors = ([ $split->('flavor') ]);
+
+my @modules = ([ $split->('modules') ]);
+
+my $tb = Apache::TestBuild->new(fresh => 1,
+ %opts,
+ extra_config => {
+ $opts{version} => \@ARGV,
+ });
+
+$tb->init;
+
+for my $version (@versions) {
+ $tb->cvs_update([ $version ]);
+
+ for my $mpm (@mpms) {
+ for my $flavor (@flavors) {
+ for my $mods (@modules) {
+ $tb->configure_httpd_2_0($version, $flavor,
+ $mods, $mpm);
+ $tb->make(qw(all install));
+ }
+ }
+ }
+}