blob: b54bd8ef59141e23e17bb4b4fd92360c15938256 [file] [log] [blame]
# please insert nothing before this line: -*- mode: cperl; cperl-indent-level: 4; cperl-continued-statement-offset: 4; indent-tabs-mode: nil -*-
# 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 ModPerl::BuildOptions;
use strict;
use warnings;
use Apache2::Build ();
use Apache::TestTrace;
use Config ();
my $param_qr = qr([\s=]+);
use constant VERBOSE => 1;
use constant UNKNOWN_FATAL => 2;
use File::Spec;
sub init {
my ($class, $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};
# try to find apxs
if (!$build->{MP_AP_PREFIX} && !$build->{MP_APXS}) {
$build->find_apxs_util();
# make a last ditch effort to find apxs in $ENV{PATH}
if (!$build->{MP_APXS}) {
my @paths = split(/$Config::Config{path_sep}/, $ENV{PATH});
my $potential_apxs;
while (!$potential_apxs) {
last if scalar(@paths) == 0; # don't loop endlessly
$potential_apxs = File::Spec->catfile(shift @paths, 'apxs');
$potential_apxs .= '.bat' if Apache2::Build::WIN32();
if (-e $potential_apxs && -x $potential_apxs) {
$build->{MP_APXS} = $potential_apxs;
} else {
undef $potential_apxs;
}
}
}
}
}
sub parse {
my ($build, $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 (!$val || !-d $val) {
error "MP_AP_PREFIX must point to a valid directory.";
die "\n";
}
}
if ($table->{$key}->{append}){
$build->{$key} = join " ", grep $_, $build->{$key}, $val;
}
else {
$build->{$key} = $val;
}
print " $key = $val\n" if $opts & VERBOSE;
}
else {
push @unknown, $_;
}
}
return \@unknown;
}
sub parse_file {
my $build = shift;
my $fh;
my @dirs = qw(./ ../ ./. ../.);
push @dirs, "$ENV{HOME}/." if exists $ENV{HOME};
my @files = map { $_ . 'makepl_args.mod_perl2' } @dirs;
unshift @files, $build->{MP_OPTIONS_FILE} if $build->{MP_OPTIONS_FILE};
for my $file (@files) {
if (open $fh, $file) {
$build->{MP_OPTIONS_FILE} = $file;
last;
}
$fh = undef;
}
return unless $fh;
print "Reading Makefile.PL args from $build->{MP_OPTIONS_FILE}\n";
my $unknowns = parse($build, [<$fh>]);
push @ARGV, @$unknowns if $unknowns;
close $fh;
}
sub parse_argv {
my $build = shift;
return unless @ARGV;
my @args = @ARGV;
@ARGV = ();
print "Reading Makefile.PL args from \@ARGV\n";
my $unknowns = parse($build, \@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)
NO_THREADS 0 Build mod_perl without thread support with httpd >= 2.4