Codebase list libcrypt-ssleay-perl / fresh-snapshots/main Makefile.PL
fresh-snapshots/main

Tree @fresh-snapshots/main (Download .tar.gz)

Makefile.PL @fresh-snapshots/mainraw · history · blame

use 5.006;
use strict;
use warnings;

use Config;
use ExtUtils::CBuilder;
use ExtUtils::MakeMaker;
use File::Spec::Functions qw( catfile rel2abs );
use Getopt::Long qw( GetOptionsFromArray );

BEGIN {
  # Must use a bundled version
  # "./" prefix required to subvert @INC traversal
  # "catfile" not useful here as it eats "." and may produces wrong \
  #  under windows ( require always takes / )
  local $@;
  eval { require "./inc/IO/Interactive/Tiny.pm" } or
    die "Your distribution is incomplete: Failed to load bundled IO::Interactive::Tiny\n$@";
}

run(\@ARGV, [qw{ssl crypto ssl32 ssleay32 eay32 libeay32 z}]);

sub run {
    my $argv = shift;
    my $libs = shift;

    eval "use ExtUtils::MakeMaker::Coverage";
    $@ or print "Adding testcover target\n";

    my @authors = reverse ( # reverse chronological order
        'Gisle Aas',
        'Joshua Chamas',
        'David Landgren',
        'A. Sinan Unur <nanis@cpan.org>',
    );

    my $mm_version = $ExtUtils::MakeMaker::VERSION;
    $mm_version =~ tr/_//d;

    my %opt;
    GetOptionsFromArray(
        $argv,
        \%opt,
        'incpath=s',
        'libpath=s',
        'openssl-prefix=s',
        'live-tests!',
        'static',
        'verbose!',
    ) or die "Error parsing command line options\n";

    if ($ENV{AUTOMATED_TESTING}) {
        $opt{verbose} = 1;
    }

    $opt{incpath} = select_first_realpath(
        $opt{incpath},
        $ENV{OPENSSL_INCLUDE},
        catfile($ENV{OPENSSL_PREFIX}, 'include'),
    );

    $opt{libpath} = select_first_realpath(
        $opt{libpath},
        $ENV{OPENSSL_LIB},
        catfile($ENV{OPENSSL_PREFIX}, 'lib'),
    );

    unless ($ENV{AUTOMATED_TESTING}) {
        show_do_you_need_crypt_ssleay();
    }

    $libs = filter_libs(\%opt, $libs);

    my $my_openssl_version_cmd = eval {
        build_openssl_version(\%opt, 'openssl-version.c');
    };

    unless (defined $my_openssl_version_cmd) {
        print "Failed to build and link a simple executable using OpenSSL\n";
        exit 0;
    };

    show_cmd_output($my_openssl_version_cmd);

    if ($ENV{PERL_MM_USE_DEFAULT}) {
        $opt{'live-tests'} = 0;
    }
    elsif (not exists $opt{'live-tests'}) {
        if (exists $ENV{CRYPT_SSLEAY_LIVE_TEST_WANTED}) {
            $opt{'live-tests'} = $ENV{CRYPT_SSLEAY_LIVE_TEST_WANTED};
        }
        elsif (IO::Interactive::Tiny::is_interactive()) {
            $opt{'live-tests'} = is_live_test_wanted();
        }
    }

    my %params = (
        META_MERGE => {
            keywords => [ qw(lwp lwp-useragent openssl https) ],
            no_index => {
                directory => [ 'inc' ],
            },
            build => {
                recommends => {
                    'Devel::CheckLib' => '0.99',
                },
            },
            resources => {
                repository => 'https://github.com/nanis/Crypt-SSLeay',
            },
        },

        NAME => 'Crypt::SSLeay',

        AUTHOR => \@authors,

        ABSTRACT_FROM => 'SSLeay.pm',

        VERSION_FROM => 'SSLeay.pm',

        INC => $opt{incpath} ? qq{-I$opt{incpath}} : q{},

        LIBS => $opt{libpath}
                ? [ join ' ', "-L$opt{libpath}", map "-l$_", @$libs ]
                : [ join ' ', map "-l$_", @$libs ]
        ,

        ($opt{static} ? (LINK_TYPE => 'static') : ()),

        TEST_REQUIRES => {
            'Test::More' => '0.19',
            'Try::Tiny' => '0.19',
        },

        CONFIGURE_REQUIRES => {
            'Devel::CheckLib' => '1.09',
            'ExtUtils::CBuilder' => '0.280205',
            'Getopt::Long' => 0,
        },

        PREREQ_PM => {
            'Bytes::Random::Secure' => '0.28',
            'LWP::Protocol::https' => '6.02',
            'MIME::Base64' => 0, # for Net::SSL
        },

        clean => {
            FILES => join(' ',
                'test.config',
                'openssl-version.o',
                $my_openssl_version_cmd,
                'assertlib*',
            ),
        },

        LICENSE => 'artistic_2',

        MIN_PERL_VERSION => 5.006,
    );

    $mm_version = eval $mm_version;

    die "EXTRA_META is deprecated" if exists $params{EXTRA_META};
    die "License not specified" if not exists $params{LICENSE};

    if (
        $params{AUTHOR} and
        ref($params{AUTHOR}) eq ref([]) and
        $mm_version < 6.5705
    ) {
        $params{META_ADD}->{author} = $params{AUTHOR};
        $params{AUTHOR}=join(', ', @{$params{AUTHOR}});
    }

    if ($params{TEST_REQUIRES} and $mm_version < 6.64) {
        $params{BUILD_REQUIRES} = {
            %{ $params{BUILD_REQUIRES} || {} },
            %{ $params{TEST_REQUIRES} },
        };
        delete $params{TEST_REQUIRES};
    }

    if ($params{BUILD_REQUIRES} and $mm_version < 6.5503) {
        #EUMM 6.5502 has problems with BUILD_REQUIRES
        $params{PREREQ_PM} = {
            %{ $params{PREREQ_PM} || {} },
            %{ $params{BUILD_REQUIRES}},
        };
        delete $params{BUILD_REQUIRES};
    }

    delete $params{CONFIGURE_REQUIRES} if $mm_version < 6.52;
    delete $params{MIN_PERL_VERSION} if $mm_version < 6.48;
    delete $params{META_MERGE} if $mm_version < 6.46;
    delete $params{META_ADD} if $mm_version < 6.46;
    delete $params{LICENSE} if $mm_version < 6.31;
    delete $params{AUTHOR} if $] < 5.005;
    delete $params{ABSTRACT_FROM} if $] < 5.005;
    delete $params{BINARY_LOCATION} if $] < 5.005;

    WriteMakefile(%params);

    write_test_config('test.config' =>
        {
            network_tests => ($opt{'live-tests'} ? 1 : 0),
        }
    );
}

sub is_live_test_wanted {
    print <<EO_CHUNK;
The test suite can attempt to connect to public servers to ensure that the
code is working properly. If you are behind a strict firewall or have no
network connectivity, these tests may fail (through no fault of the code).
EO_CHUNK
    my $wanted = prompt "Do you want to run the live tests (y/N)?", 'N';
    $wanted =~ s/\A\s+//;
    $wanted =~ s/\s+\z//;

    return $wanted =~ /\Ay(?:es)?\z/i ? 1 : 0;
}

sub write_test_config {
    my $file = shift;
    my $config = shift;

    open my $fh, '>', $file
        or die "Failed to open '$file' to write config: $!";

    for my $k ( sort keys %$config) {
        print join("\t", $k, $config->{$k}), "\n";
    }

    close $fh
        or die "Failed to close '$file' after writing config: $!";

    return;
}

sub show_cmd_output {
    my ($cmd) = @_;
    my $sep = '=' x 80 . "\n";

    my $output = `$cmd`;

    print $sep,
        defined($output) ? "Output from '$cmd':\n$output"
                         : "No output from '$cmd'",
        $sep
    ;

    return;
}

sub build_openssl_version {
    my $opt = shift;
    my $source = shift;

    my $builder = ExtUtils::CBuilder->new(quiet => !($opt->{verbose} ? 1 : 0));

    my $object = $builder->compile(
        source => $source,
        $opt->{incpath} ? (include_dirs => "$opt->{incpath}") : (),
    );

    my $executable = $builder->link_executable(
        objects => $object,
    );

    -e $executable
        and return rel2abs($executable);

    return;
}

sub select_first_realpath {
    my ($ret) = map rel2abs($_), grep defined && -d, @_;
    $ret;
}

sub filter_libs {
    my $opt = shift;
    my $libs = shift;

    if (eval { require ExtUtils::PkgConfig } &&
            ExtUtils::PkgConfig->exists('openssl')) {
        my @libs = map { s/^-l//; $_ }
            split(' ', ExtUtils::PkgConfig->libs_only_l('openssl'));
        $opt->{libpath} = ExtUtils::PkgConfig->libs_only_L('openssl') // '';
        $opt->{libpath} =~ s/^-L//;
        $opt->{incpath} = ExtUtils::PkgConfig->cflags_only_I('openssl') // '';
        $opt->{incpath} =~ s/-I//;
        return \@libs;
    }

    return $libs unless eval {
        require Devel::CheckLib;
        1;
    };

    my @found;
    for my $lib (@$libs) {
       eval {
           Devel::CheckLib::assert_lib(
                debug => ($opt->{verbose} ? 1 : 0),
                lib => $lib,
                header => 'openssl/ssl.h',
                $opt->{libpath} ? (libpath => "$opt->{libpath}") : (),
                $opt->{incpath} ? (incpath => "$opt->{incpath}") : (),
            );
            push @found, $lib;
        };
    }
    unless (grep /crypt|ssl|eay/, @found) {
        printf(
            "Cannot link with any of the requested SSL libraries '%s'\n",
            join(', ' => @$libs),
        );
        exit 0;
    }

    printf "Found libraries '%s'\n", join(', ' => @found);
    return \@found;
}

sub show_do_you_need_crypt_ssleay {
    print <<EO_DO_YOU_NEED_CRYPT_SSLEAY;

    *** THIS IS NOT AN ERROR, JUST A MESSAGE FOR YOUR INFORMATION ***

    Do you really need Crypt::SSLeay?

    Starting with version 6.02 of LWP, https support was unbundled into
    LWP::Protocol::https. This module specifies as one of its prerequisites
    IO::Socket::SSL which is automatically used by LWP::UserAgent unless
    this preference is overridden separately. IO::Socket::SSL is a more
    complete implementation, and, crucially, it allows hostname
    verification. Crypt::SSLeay does not support this. At this point,
    Crypt::SSLeay is maintained to support existing software that already
    depends on it.

    However, it is possible that your software does not really depend on
    Crypt::SSLeay, only on the ability of LWP::UserAgent class to
    communicate with sites over SSL/TLS.

    If are using version LWP 6.02 or later, and therefore have installed
    LWP::Protocol::https and its dependencies, and do not explicitly use
    Net::SSL before loading LWP::UserAgent, or override the default socket
    class, you are probably using IO::Socket::SSL and do not really need
    Crypt::SSLeay.

    Before installing Crypt::SSLeay, you may want to try specifying a
    dependency on LWP::Protocol::https.

EO_DO_YOU_NEED_CRYPT_SSLEAY
}