%PDF- %PDF-
Direktori : /home/rs/perl/fml/lib/perl5/site_perl/5.8/Crypt/OpenSSL/ |
Current File : //home/rs/perl/fml/lib/perl5/site_perl/5.8/Crypt/OpenSSL/Guess.pm |
package Crypt::OpenSSL::Guess; use 5.008001; use strict; use warnings; our $VERSION = "0.14"; use Config; use English qw( $OSNAME -no_match_vars ); use File::Spec; use Symbol qw(gensym); use Exporter 'import'; our @EXPORT = qw(openssl_inc_paths openssl_lib_paths find_openssl_prefix find_openssl_exec openssl_version); sub openssl_inc_paths { my $prefix = find_openssl_prefix(); my $exec = find_openssl_exec($prefix); return '' unless -x $exec; my @inc_paths; my @try_includes = ( 'include' => sub { 1 }, 'inc32' => sub { $OSNAME eq 'MSWin32' }, ); while ( !@inc_paths && defined( my $dir = shift @try_includes ) && defined( my $cond = shift @try_includes ) ) { if ( $cond->() && -f "$prefix/$dir/openssl/ssl.h" ) { @inc_paths = "$prefix/$dir"; } } return join ' ', map { "-I$_" } @inc_paths; } sub openssl_lib_paths { my $prefix = find_openssl_prefix(); my $exec = find_openssl_exec($prefix); return '' unless -x $exec; my @lib_paths; for ($prefix, "$prefix/lib64", "$prefix/lib", "$prefix/out32dll") { push @lib_paths, $_ if -d $_; } if ($^O eq 'MSWin32') { push @lib_paths, "$prefix/lib/VC" if -d "$prefix/lib/VC"; my $found = 0; my @pairs = (); # Library names depend on the compiler @pairs = (['eay32','ssl32'],['crypto.dll','ssl.dll'],['crypto','ssl']) if $Config{cc} =~ /gcc/; @pairs = (['libeay32','ssleay32'],['libeay32MD','ssleay32MD'],['libeay32MT','ssleay32MT'],['libcrypto','libssl'],['crypto','ssl']) if $Config{cc} =~ /cl/; for my $dir (@lib_paths) { for my $p (@pairs) { $found = 1 if ($Config{cc} =~ /gcc/ && -f "$dir/lib$p->[0].a" && -f "$dir/lib$p->[1].a"); $found = 1 if ($Config{cc} =~ /cl/ && -f "$dir/$p->[0].lib" && -f "$dir/$p->[1].lib"); if ($found) { @lib_paths = ($dir); last; } } } } elsif ($^O eq 'darwin') { for my $dir (@lib_paths) { if (-f "$dir/libcrypto.dylib" && -f "$dir/libssl.dylib") { @lib_paths = ($dir); last; } } } elsif ($^O eq 'VMS') { if (-r 'sslroot:[000000]openssl.cnf') { # openssl.org source install @lib_paths = ('SSLLIB'); } elsif (-r 'ssl1$root:[000000]openssl.cnf') { # VSI or HPE SSL1 install @lib_paths = ('SYS$SHARE'); } elsif (-r 'ssl$root:[000000]openssl.cnf') { # HP install @lib_paths = ('SYS$SHARE'); } } return join ' ', map { "-L$_" } @lib_paths; } my $other_try = 0; my @nopath; sub check_no_path { # On OS/2 it would be typically on default paths my $p; if (not($other_try++) and $] >= 5.008001) { use ExtUtils::MM; my $mm = MM->new(); my ($list) = $mm->ext("-lssl"); return unless $list =~ /-lssl\b/; for $p (split /\Q$Config{path_sep}/, $ENV{PATH}) { @nopath = ("$p/openssl$Config{_exe}", # exe name '.') # dummy lib path if -x "$p/openssl$Config{_exe}" } } @nopath; } sub find_openssl_prefix { my ($dir) = @_; if (defined $ENV{OPENSSL_PREFIX}) { return $ENV{OPENSSL_PREFIX}; } # Homebrew (macOS) or LinuxBrew if ($^O ne 'MSWin32' and my $prefix = `brew --prefix --installed openssl 2>@{[File::Spec->devnull]}`) { chomp $prefix; return $prefix; } my @guesses = ( '/home/linuxbrew/.linuxbrew/opt/openssl/bin/openssl' => '/home/linuxbrew/.linuxbrew/opt/openssl', # LinuxBrew openssl '/opt/homebrew/opt/openssl/bin/openssl' => '/opt/homebrew/opt/openssl', # macOS ARM homebrew '/usr/local/opt/openssl/bin/openssl' => '/usr/local/opt/openssl', # OSX homebrew openssl '/usr/local/bin/openssl' => '/usr/local', # OSX homebrew openssl '/opt/local/bin/openssl' => '/opt/local', # Macports openssl '/usr/bin/openssl' => '/usr', '/usr/sbin/openssl' => '/usr', '/opt/ssl/bin/openssl' => '/opt/ssl', '/opt/ssl/sbin/openssl' => '/opt/ssl', '/usr/local/ssl/bin/openssl' => '/usr/local/ssl', '/usr/local/openssl/bin/openssl' => '/usr/local/openssl', '/apps/openssl/std/bin/openssl' => '/apps/openssl/std', '/usr/sfw/bin/openssl' => '/usr/sfw', # Open Solaris 'C:\OpenSSL\bin\openssl.exe' => 'C:\OpenSSL', 'C:\OpenSSL-Win32\bin\openssl.exe' => 'C:\OpenSSL-Win32', $Config{prefix} . '\bin\openssl.exe' => $Config{prefix}, # strawberry perl $Config{prefix} . '\..\c\bin\openssl.exe' => $Config{prefix} . '\..\c', # strawberry perl '/sslexe/openssl.exe' => '/sslroot', # VMS, openssl.org '/ssl1$exe/openssl.exe' => '/ssl1$root',# VMS, VSI or HPE install '/ssl$exe/openssl.exe' => '/ssl$root', # VMS, HP install ); while (my $k = shift @guesses and my $v = shift @guesses) { if ( -x $k ) { return $v; } } (undef, $dir) = check_no_path() and return $dir; return; } sub find_openssl_exec { my ($prefix) = @_; my $exe_path; for my $subdir (qw( bin sbin out32dll ia64_exe alpha_exe )) { my $path = File::Spec->catfile($prefix, $subdir, "openssl$Config{_exe}"); if ( -x $path ) { return $path; } } ($prefix) = check_no_path() and return $prefix; return; } sub openssl_version { my ($major, $minor, $letter); my $prefix = find_openssl_prefix(); my $exec = find_openssl_exec($prefix); return unless -x $exec; { my $pipe = gensym(); open($pipe, qq{"$exec" version |}) or die "Could not execute $exec"; my $output = <$pipe>; chomp $output; close $pipe; if ( ($major, $minor, $letter) = $output =~ /^OpenSSL\s+(\d+\.\d+)\.(\d+)([a-z]?)/ ) { } elsif ( ($major, $minor) = $output =~ /^LibreSSL\s+(\d+\.\d+)(?:\.(\d+))?/ ) { # LibreSSL 2.0.x releases only identify themselves as "LibreSSL 2.0", # with no patch release number if ( !defined $minor ) { $minor = "x"; } } else { die <<EOM *** OpenSSL version test failed (`$output' has been returned) Either you have bogus OpenSSL or a new version has changed the version number format. Please inform the authors! EOM } } return ($major, $minor, $letter); } 1; __END__ =encoding utf-8 =head1 NAME Crypt::OpenSSL::Guess - Guess OpenSSL include path =head1 SYNOPSIS use ExtUtils::MakerMaker; use Crypt::OpenSSL::Guess; WriteMakefile( # ... LIBS => ['-lssl -lcrypto ' . openssl_lib_paths()], INC => openssl_inc_paths(), # guess include path or get from $ENV{OPENSSL_PREFIX} ); =head1 DESCRIPTION Crypt::OpenSSL::Guess provides helpers to guess OpenSSL include path on any platforms. Often macOS's homebrew OpenSSL cause a problem on installation due to include path is not added. Some CPAN module provides to modify include path with configure-args, but L<Carton> or L<Module::CPANfile> is not supported to pass configure-args to each modules. Crypt::OpenSSL::* modules should use it on your L<Makefile.PL>. This module resolves the include path by L<Net::SSLeay>'s workaround. Original code is taken from C<inc/Module/Install/PRIVATE/Net/SSLeay.pm> by L<Net::SSLeay>. =head1 FUNCTIONS =over 4 =item openssl_inc_paths() This functions returns include paths in the format passed to CC. If OpenSSL could not find, then empty string is returned. openssl_inc_paths(); # on macOS: "-I/usr/local/opt/openssl/include" =item openssl_lib_paths() This functions returns library paths in the format passed to CC. If OpenSSL could not find, then empty string is returned. openssl_lib_paths(); # on macOS: "-L/usr/local/opt/openssl/lib" =item find_openssl_prefix([$dir]) This function returns OpenSSL's prefix. If set C<OPENSSL_PREFIX> environment variable, you can overwrite the return value. find_openssl_prefix(); # on macOS: "/usr/local/opt/openssl" =item find_openssl_exec($prefix) This functions returns OpenSSL's executable path. find_openssl_exec(); # on macOS: "/usr/local/opt/openssl/bin/openssl" =item ($major, $minor, $letter) = openssl_version() This functions returns OpenSSL's version as major, minor, letter. openssl_version(); # ("1.0", "2", "n") =back =head1 SEE ALSO L<Net::SSLeay> =head1 LICENSE Copyright (C) Takumi Akiyama. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR Takumi Akiyama E<lt>t.akiym@gmail.comE<gt> =cut