blob: 0b3e50a48f2e3c614b4efafb7fd147df74c0c535 [file] [log] [blame]
# 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 ModPerl::BuildOptions;
use strict;
use warnings;
use Apache2::Build ();
use Apache::TestTrace;
my $param_qr = qr([\s=]+);
use constant VERBOSE => 1;
use constant UNKNOWN_FATAL => 2;
use File::Spec;
sub init {
my ($self, $build) = @_;
#@ARGV should override what's in .makepl_args.mod_perl2
#but @ARGV might also override the default MP_OPTS_FILE
#so snag that first
parse($build, [grep { /^MP_OPTIONS_FILE/ } @ARGV]);
parse_file($build);
parse_argv($build);
# if AP_PREFIX is used apxs and apr-config from the apache build
# tree won't work, so it can't co-exist with APXS and APR_CONFIG
# options
if ($build->{MP_AP_PREFIX} and $build->{MP_APXS}) {
error "You need to pass either MP_AP_PREFIX or MP_APXS, but not both";
die "\n";
}
if ($build->{MP_AP_PREFIX} and $build->{MP_APR_CONFIG}) {
error "You need to pass either MP_AP_PREFIX or MP_APR_CONFIG, " .
"but not both";
die "\n";
}
if ($build->{MP_DEBUG} and $build->{MP_USE_GTOP} and !$build->find_gtop) {
error "Can't find libgtop, resetting MP_USE_GTOP=0";
$build->{MP_USE_GTOP} = 0;
}
unless ($build->{MP_USE_DSO} or $build->{MP_USE_STATIC}) {
# default to DSO
$build->{MP_USE_DSO} = 1;
}
$build->{MP_GENERATE_XS} = 1 unless exists $build->{MP_GENERATE_XS};
# define MP_COMPAT_1X unless explicitly told to disable it
$build->{MP_COMPAT_1X} = 1
unless exists $build->{MP_COMPAT_1X} && !$build->{MP_COMPAT_1X};
}
sub parse {
my ($self, $lines, $opts) = @_;
$opts = VERBOSE|UNKNOWN_FATAL unless defined $opts;
my $table = table();
my @unknown;
my $continue = "";
my @data = ();
for (@$lines) {
chomp;
s/^\s+//; s/\s+$//;
next if /^\#/ || /^$/;
last if /^__END__/;
# more than one entry on the same line (but make sure to leave
# -DMP_* alone)
push @data, split /(?=\WMP_)/, $_;
}
for (@data) {
#XXX: this "parser" should be more robust
s/^\s+//; s/\s+$//;
$_ = "$continue $_" if $continue;
#example: +"MP_CCOPTS=-Werror" if $] >= 5.007
if (s/^\+//) {
$_ = eval $_;
}
if (/^MP_/) {
my ($key, $val) = split $param_qr, $_, 2;
$val ||= "" unless defined $val && $val eq '0';
$continue = $val =~ s/\\$// ? $key : "";
if (!$table->{$key} and $opts & UNKNOWN_FATAL) {
my $usage = usage();
die "Unknown Option: $key\nUsage:\n$usage\n";
}
if ($key eq 'MP_APXS') {
$val = File::Spec->canonpath(File::Spec->rel2abs($val));
}
if ($key eq 'MP_AP_PREFIX') {
$val = File::Spec->canonpath(File::Spec->rel2abs($val));
if (Apache2::Build::WIN32()) {
# MP_AP_PREFIX may not contain spaces
require Win32;
$val = Win32::GetShortPathName($val);
}
}
if ($table->{$key}->{append}){
$self->{$key} = join " ", grep $_, $self->{$key}, $val;
}
else {
$self->{$key} = $val;
}
print " $key = $val\n" if $opts & VERBOSE;
}
else {
push @unknown, $_;
}
}
return \@unknown;
}
sub parse_file {
my $self = shift;
my $fh;
my @dirs = qw(./ ../ ./. ../.);
push @dirs, "$ENV{HOME}/." if exists $ENV{HOME};
my @files = map { $_ . 'makepl_args.mod_perl2' } @dirs;
unshift @files, $self->{MP_OPTIONS_FILE} if $self->{MP_OPTIONS_FILE};
for my $file (@files) {
if (open $fh, $file) {
$self->{MP_OPTIONS_FILE} = $file;
last;
}
$fh = undef;
}
return unless $fh;
print "Reading Makefile.PL args from $self->{MP_OPTIONS_FILE}\n";
my $unknowns = parse($self, [<$fh>]);
push @ARGV, @$unknowns if $unknowns;
close $fh;
}
sub parse_argv {
my $self = shift;
return unless @ARGV;
my @args = @ARGV;
@ARGV = ();
print "Reading Makefile.PL args from \@ARGV\n";
my $unknowns = parse($self, \@args);
push @ARGV, @$unknowns if $unknowns;
}
sub usage {
my $table = table();
my @opts = map { "$_ - $table->{$_}->{val}" } sort keys %$table;
join "\n", @opts;
}
sub parse_table {
my ($fh) = @_;
my %table;
local $_;
while (<$fh>) {
chomp;
s/^\s+//; s/\s+$//;
next if /^\#/ || /^$/;
last if /^__END__/;
my ($key, $append, $val) = split /\s+/, $_, 3;
$table{'MP_' . $key} = { append => $append, val => $val };
}
return \%table;
}
my $Table;
sub table {
$Table ||= parse_table(\*DATA);
}
1;
# __DATA__ format:
# key append description
# where:
# key: is the option name
# append: is whether we want to replace a default option (0)
# or append the arg to the option (1)
# desc: description for this option
__DATA__
USE_GTOP 0 Link with libgtop and enable libgtop reporting
DEBUG 0 Turning on debugging (-g -lperld) and tracing
MAINTAINER 0 Maintainer mode: DEBUG=1 -DAP_DEBUG -Wall ...
CCOPTS 1 Add to compiler flags
TRACE 0 Turn on tracing
USE_DSO 0 Build mod_perl as a dso
USE_STATIC 0 Build mod_perl static
PROMPT_DEFAULT 0 Accept default value for all would-be prompts
OPTIONS_FILE 0 Read options from given file
STATIC_EXTS 0 Build Apache2::*.xs as static extensions
APXS 0 Path to apxs
AP_DESTDIR 0 Destination for Apache specific mod_perl bits
AP_PREFIX 0 Apache installation or source tree prefix
AP_CONFIGURE 0 Apache ./configure arguments
APR_CONFIG 0 Path to apr-config
APU_CONFIG 0 Path to apu-config
XS_GLUE_DIR 1 Directories containing extension glue
INCLUDE_DIR 1 Add directories to search for header files
GENERATE_XS 0 Generate XS code based on httpd version
LIBNAME 0 Name of the modperl dso library (default is mod_perl)
COMPAT_1X 0 Compile-time mod_perl 1.0 backcompat (default is on)
APR_LIB 0 Lib used to build APR::* on Win32 (default is aprext)