📄 build.pm
字号:
# Copyright 2000-2005 The Apache Software Foundation## Licensed 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 Apache2::Build;use 5.006;use strict;use warnings;use Config;use Cwd ();use File::Spec::Functions qw(catfile catdir canonpath rel2abs devnull catpath splitpath);use File::Basename;use ExtUtils::Embed ();use File::Copy ();use constant IS_MOD_PERL_BUILD => grep { -e "$_/Makefile.PL" && -e "$_/lib/mod_perl2.pm" } qw(. ..);use constant AIX => $^O eq 'aix';use constant DARWIN => $^O eq 'darwin';use constant CYGWIN => $^O eq 'cygwin';use constant IRIX => $^O eq 'irix';use constant HPUX => $^O eq 'hpux';use constant OPENBSD => $^O eq 'openbsd';use constant WIN32 => $^O eq 'MSWin32';use constant MSVC => WIN32() && ($Config{cc} eq 'cl');use constant REQUIRE_ITHREADS => grep { $^O eq $_ } qw(MSWin32);use constant PERL_HAS_ITHREADS => $Config{useithreads} && ($Config{useithreads} eq 'define');use constant BUILD_APREXT => WIN32() || CYGWIN();use ModPerl::Code ();use ModPerl::BuildOptions ();use Apache::TestTrace;use Apache::TestConfig ();our $VERSION = '0.01';our $AUTOLOAD;sub AUTOLOAD { my $self = shift; my $name = uc ((split '::', $AUTOLOAD)[-1]); unless ($name =~ /^MP_/) { die "no such method: $AUTOLOAD"; } unless ($self->{$name}) { return wantarray ? () : undef; } return wantarray ? (split /\s+/, $self->{$name}) : $self->{$name};}#--- apxs stuff ---our $APXS;my %apxs_query = ( INCLUDEDIR => 'include', LIBEXECDIR => 'modules', CFLAGS => undef, PREFIX => '',);sub ap_prefix_invalid { my $self = shift; my $prefix = $self->{MP_AP_PREFIX}; unless (-d $prefix) { return "$prefix: No such file or directory"; } my $include_dir = $self->apxs(-q => 'INCLUDEDIR'); unless (-d $include_dir) { return "include/ directory not found in $prefix"; } return '';}sub httpd_is_source_tree { my $self = shift; return $self->{httpd_is_source_tree} if exists $self->{httpd_is_source_tree}; my $prefix = $self->dir; $self->{httpd_is_source_tree} = defined $prefix && -d $prefix && -e "$prefix/CHANGES";}# try to find the apxs utility, set $apxs to the path if found,# otherwise to ''my $apxs; # undef so we know we haven't tried to set it yetsub find_apxs_util { my $self = shift; $apxs = ''; # not found my @trys = ($Apache2::Build::APXS, $self->{MP_APXS}, $ENV{MP_APXS}); push @trys, catfile $self->{MP_AP_PREFIX}, 'bin', 'apxs' if exists $self->{MP_AP_PREFIX}; if (WIN32) { my $ext = '.bat'; for (@trys) { $_ .= $ext if ($_ and $_ !~ /$ext$/); } } unless (IS_MOD_PERL_BUILD) { #if we are building mod_perl via apxs, apxs should already be known #these extra tries are for things built outside of mod_perl #e.g. libapreq # XXX: this may pick a wrong apxs version! push @trys, Apache::TestConfig::which('apxs'), '/usr/local/apache/bin/apxs'; } my $apxs_try; for (@trys) { next unless ($apxs_try = $_); chomp $apxs_try; if (-x $apxs_try) { $apxs = $apxs_try; last; } }}# if MP_AP_DESTDIR was specified this sub will prepend this path to# any Apache-specific installation path (that option is used only by# package maintainers).sub ap_destdir { my $self = shift; my $path = shift || ''; return $path unless $self->{MP_AP_DESTDIR}; if (WIN32) { my ($dest_vol, $dest_dir) = splitpath $self->{MP_AP_DESTDIR}, 1; my $real_dir = (splitpath $path)[1]; $path = catpath $dest_vol, catdir($dest_dir, $real_dir), ''; } else { $path = catdir $self->{MP_AP_DESTDIR}, $path; } return canonpath $path;}sub apxs { my $self = shift; $self->find_apxs_util() unless defined $apxs; my $is_query = (@_ == 2) && ($_[0] eq '-q'); $self = $self->build_config unless ref $self; my $query_key; if ($is_query) { $query_key = 'APXS_' . uc $_[1]; if (exists $self->{$query_key}) { return $self->{$query_key}; } } unless ($apxs) { my $prefix = $self->{MP_AP_PREFIX} || ""; return '' unless -d $prefix and $is_query; my $val = $apxs_query{$_[1]}; return defined $val ? ($val ? "$prefix/$val" : $prefix) : ""; } my $devnull = devnull(); my $val = qx($apxs @_ 2>$devnull); chomp $val if defined $val; unless ($val) { # do we have an error or is it just an empty value? my $error = qx($apxs @_ 2>&1); chomp $error if defined $error; if ($error) { error "'$apxs @_' failed:"; error $error; } else { $val = ''; } } $self->{$query_key} = $val;}sub apxs_cflags { my $who = caller_package(shift); my $cflags = $who->apxs('-q' => 'CFLAGS'); $cflags =~ s/\"/\\\"/g; $cflags;}sub apxs_extra_cflags { my $who = caller_package(shift); my $flags = $who->apxs('-q' => 'EXTRA_CFLAGS'); $flags =~ s/\"/\\\"/g; $flags;}sub apxs_extra_cppflags { my $who = caller_package(shift); my $flags = $who->apxs('-q' => 'EXTRA_CPPFLAGS'); $flags =~ s/\"/\\\"/g; $flags;}sub caller_package { my $arg = shift; return ($arg and ref($arg) eq __PACKAGE__) ? $arg : __PACKAGE__;}my %threaded_mpms = map { $_ => 1 } qw(worker winnt beos mpmt_os2 netware leader perchild threadpool);sub mpm_is_threaded { my $self = shift; my $mpm_name = $self->mpm_name(); return $threaded_mpms{$mpm_name} || 0;}sub mpm_name { my $self = shift; return $self->{mpm_name} if $self->{mpm_name}; # XXX: hopefully apxs will work on win32 one day return $self->{mpm_name} = 'winnt' if WIN32; my $mpm_name = $self->apxs('-q' => 'MPM_NAME'); # building against the httpd source dir unless (($mpm_name and $self->httpd_is_source_tree)) { if ($self->dir) { my $config_vars_file = catfile $self->dir, "build", "config_vars.mk"; if (open my $fh, $config_vars_file) { while (<$fh>) { if (/MPM_NAME = (\w+)/) { $mpm_name = $1; last; } } close $fh; } } } unless ($mpm_name) { my $msg = 'Failed to obtain the MPM name.'; $msg .= " Please specify MP_APXS=/full/path/to/apxs to solve " . "this problem." unless exists $self->{MP_APXS}; error $msg; die "\n"; } return $self->{mpm_name} = $mpm_name;}sub should_build_apache { my ($self) = @_; return $self->{MP_USE_STATIC} ? 1 : 0;}sub configure_apache { my ($self) = @_; unless ($self->{MP_AP_CONFIGURE}) { error "You specified MP_USE_STATIC but did not specify the " . "arguments to httpd's ./configure with MP_AP_CONFIGURE"; exit 1; } unless ($self->{MP_AP_PREFIX}) { error "You specified MP_USE_STATIC but did not speficy the " . "location of httpd's source tree with MP_AP_PREFIX"; exit 1; } debug "Configuring httpd in $self->{MP_AP_PREFIX}"; my $httpd = File::Spec->catfile($self->{MP_AP_PREFIX}, 'httpd'); $self->{'httpd'} ||= $httpd; push @Apache::TestMM::Argv, ('httpd' => $self->{'httpd'}); my $mplibpath = ''; my $ldopts = $self->ldopts; if (CYGWIN) { # Cygwin's httpd port links its modules into httpd2core.dll, # instead of httpd.exe. In this case, we have a problem, # because libtool doesn't want to include static libs (.a) # into a dynamic lib (.dll). Workaround this by setting # mod_perl.a as a linker argument (including all other flags # and libs). my $mplib = "$self->{MP_LIBNAME}$Config{lib_ext}"; $ldopts = join ' ', '--export-all-symbols', '--enable-auto-image-base', "$self->{cwd}/src/modules/perl/$mplib", $ldopts; $ldopts =~ s/(\S+)/-Wl,$1/g; } else { my $mplib = "$self->{MP_LIBNAME}$Config{lib_ext}"; $mplibpath = catfile($self->{cwd}, qw(src modules perl), $mplib); } local $ENV{BUILTIN_LIBS} = $mplibpath; local $ENV{AP_LIBS} = $ldopts; local $ENV{MODLIST} = 'perl'; # XXX: -Wall and/or -Werror at httpd configure time breaks things local $ENV{CFLAGS} = join ' ', grep { ! /\-Wall|\-Werror/ } split /\s+/, $ENV{CFLAGS} || ''; my $cd = qq(cd $self->{MP_AP_PREFIX}); # We need to clean the httpd tree before configuring it if (-f File::Spec->catfile($self->{MP_AP_PREFIX}, 'Makefile')) { my $cmd = qq(make clean); debug "Running $cmd"; system("$cd && $cmd") == 0 or die "httpd: $cmd failed"; } my $cmd = qq(./configure $self->{MP_AP_CONFIGURE}); debug "Running $cmd"; system("$cd && $cmd") == 0 or die "httpd: $cmd failed"; # Got to build in srclib/* early to have generated files present. my $srclib = File::Spec->catfile($self->{MP_AP_PREFIX}, 'srclib'); $cd = qq(cd $srclib); $cmd = qq(make); debug "Building srclib in $srclib"; system("$cd && $cmd") == 0 or die "srclib: $cmd failed";}#--- Perl Config stuff ---my %gtop_config = ();sub find_gtop { my $self = shift; return %gtop_config if %gtop_config; if (%gtop_config = find_gtop_config()) { return %gtop_config; } if ($self->find_dlfile('gtop')) { $gtop_config{ldopts} = $self->gtop_ldopts_old(); $gtop_config{ccopts} = ''; return %gtop_config; } return ();}sub find_gtop_config { my %c = (); my $ver_2_5_plus = 0; if (system('pkg-config --exists libgtop-2.0') == 0) { # 2.x chomp($c{ccopts} = qx|pkg-config --cflags libgtop-2.0|); chomp($c{ldopts} = qx|pkg-config --libs libgtop-2.0|); # 2.0.0 bugfix chomp(my $libdir = qx|pkg-config --variable=libdir libgtop-2.0|); $c{ldopts} =~ s|\$\(libdir\)|$libdir|; chomp($c{ver} = qx|pkg-config --modversion libgtop-2.0|); ($c{ver_maj}, $c{ver_min}) = split /\./, $c{ver}; $ver_2_5_plus++ if $c{ver_maj} == 2 && $c{ver_min} >= 5; if ($ver_2_5_plus) { # some headers were removed in libgtop 2.5.0 so we need to # be able to exclude them at compile time $c{ccopts} .= ' -DGTOP_2_5_PLUS'; } } elsif (system('gnome-config --libs libgtop') == 0) { chomp($c{ccopts} = qx|gnome-config --cflags libgtop|); chomp($c{ldopts} = qx|gnome-config --libs libgtop|); # buggy ( < 1.0.9?) versions fixup $c{ccopts} =~ s|^/|-I/|; $c{ldopts} =~ s|^/|-L/|; } # starting from 2.5.0 'pkg-config --cflags libgtop-2.0' already # gives us all the cflags that are needed if ($c{ccopts} && !$ver_2_5_plus) { chomp(my $ginc = `glib-config --cflags`); $c{ccopts} .= " $ginc"; } if (%c) { $c{ccopts} = " $c{ccopts}"; $c{ldopts} = " $c{ldopts}"; } return %c;}my @Xlib = qw(/usr/X11/lib /usr/X11R6/lib);sub gtop_ldopts_old { my $self = shift; my $xlibs = ""; my ($path) = $self->find_dlfile('Xau', @Xlib); if ($path) { $xlibs = "-L$path -lXau"; } if ($self->find_dlfile('intl')) { $xlibs .= ' -lintl'; } return " -lgtop -lgtop_sysdeps -lgtop_common $xlibs";}sub gtop_ldopts { exists $gtop_config{ldopts} ? $gtop_config{ldopts} : '';}sub gtop_ccopts { exists $gtop_config{ccopts} ? $gtop_config{ccopts} : '';}sub ldopts { my ($self) = @_; my $config = tied %Config; my $ldflags = $config->{ldflags}; if (WIN32) { $config->{ldflags} = ''; #same as lddlflags } elsif (DARWIN) { #not sure how this can happen, but it shouldn't my @bogus_flags = ('flat_namespace', 'bundle', 'undefined suppress'); for my $flag (@bogus_flags) { $config->{ldflags} =~ s/-$flag\s*//; } } my $ldopts = ExtUtils::Embed::ldopts(); chomp $ldopts; my $ld = $self->perl_config('ld'); if (HPUX && $ld eq 'ld') { while ($ldopts =~ s/-Wl,(\S+)/$1/) { my $cp = $1; (my $repl = $cp) =~ s/,/ /g; $ldopts =~ s/\Q$cp/$repl/; } } if ($self->{MP_USE_GTOP}) { $ldopts .= $self->gtop_ldopts; } $config->{ldflags} = $ldflags; #reset # on Irix mod_perl.so needs to see the libperl.so symbols, which # requires the -exports option immediately before -lperl. if (IRIX) { ($ldopts =~ s/-lperl\b/-exports -lperl/) or warn "Failed to fix Irix symbol exporting\n"; } $ldopts;}my $Wall = "-Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations";# perl v5.6.1 and earlier produces lots of warnings, so we can't use# -Werror with those versions.$Wall .= " -Werror" if $] >= 5.006002;sub ap_ccopts { my ($self) = @_; my $ccopts = "-DMOD_PERL"; if ($self->{MP_USE_GTOP}) { $ccopts .= " -DMP_USE_GTOP"; $ccopts .= $self->gtop_ccopts; } if ($self->{MP_MAINTAINER}) { $self->{MP_DEBUG} = 1; if ($self->perl_config('gccversion')) { #same as --with-maintainter-mode $ccopts .= " $Wall -DAP_DEBUG"; $ccopts .= " -DAP_HAVE_DESIGNATED_INITIALIZER"; } if ($self->has_gcc_version('3.3.2') && $ccopts !~ /declaration-after-statement/) { debug "Adding -Wdeclaration-after-statement to ccopts"; $ccopts .= " -Wdeclaration-after-statement"; } } if ($self->{MP_COMPAT_1X}) { $ccopts .= " -DMP_COMPAT_1X"; } if ($self->{MP_DEBUG}) { $self->{MP_TRACE} = 1; my $win32_flags = MSVC ? '-Od -MD -Zi' : ''; my $debug_flags = WIN32 ? $win32_flags : '-g'; $ccopts .= " $debug_flags" unless $Config{optimize} =~ /$debug_flags/; $ccopts .= ' -DMP_DEBUG'; } if ($self->{MP_CCOPTS}) { $ccopts .= " $self->{MP_CCOPTS}"; } if ($self->{MP_TRACE}) { $ccopts .= " -DMP_TRACE"; } # make sure apr.h can be safely included # for example Perl's included -D_GNU_SOURCE implies # -D_LARGEFILE64_SOURCE on linux, but this won't happen on # Solaris, so we need apr flags living in apxs' EXTRA_CPPFLAGS my $extra_cppflags = $self->apxs_extra_cppflags; $ccopts .= " " . $extra_cppflags; $ccopts;}sub has_gcc_version {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -