1use strict; 2use warnings; 3 4use Config; 5use ExtUtils::MakeMaker; 6use File::Basename qw(dirname); 7use Getopt::Long; 8 9eval "use ExtUtils::MakeMaker::Coverage"; 10$@ or print "Adding testcover target\n"; 11 12use vars qw($opt_default $opt_libpath $opt_static); 13 14GetOptions( 15 "default", \$opt_default, 16 "lib=s", \$opt_libpath, 17 "static", \$opt_static, 18); 19 20$opt_default ||= $ENV{CRYPT_SSLEAY_DEFAULT}; 21 22# FIND POSSIBLE SSL INSTALLATIONS 23 24my @POSSIBLE_SSL_DIRS; 25if ($opt_libpath) { 26 # explicit from command-line 27 @POSSIBLE_SSL_DIRS = ($opt_libpath); 28 $opt_default = 1; 29} 30elsif ($^O eq 'MSWin32') { 31 @POSSIBLE_SSL_DIRS = 'c:\\openssl'; 32} 33elsif ($^O eq 'VMS') { 34 @POSSIBLE_SSL_DIRS = '/ssl$root'; 35} 36else { 37 # Unix and the rest 38 @POSSIBLE_SSL_DIRS = qw( 39 /local 40 /local/ssl 41 /opt/ssl 42 /usr 43 /usr/local 44 /usr/local/ssl 45 /usr/local/openssl 46 ); 47} 48 49my @CANDIDATE = do { 50 my %seen; 51 grep {!$seen{$_->{check}}++} 52 map {Candidate($_)} 53 @POSSIBLE_SSL_DIRS 54}; 55 56if (@CANDIDATE == 0) { 57 $opt_default = 0; 58 my $bar = '=' x 72; 59 print <<"INFO"; 60$bar 61No installed SSL libraries found in any of the following places. 62INFO 63 print " $_\n" for @POSSIBLE_SSL_DIRS; 64 print <<"INFO"; 65You will have to either specify a directory location at the following 66prompt, or rerun the Makefile.PL program and use the --lib switch 67to specify the path. If the path in question is considered standard 68on your platform, please consider filing a bug report in order to 69have it taken into account in a subsequent version of Crypt::SSLeay. 70 71INFO 72 73 if (-f '/etc/debian_version') { 74 print <<"DEBIAN_INFO"; 75 76This host looks like it is running Debian. Crypt::SSLeay needs to 77be compiled with C headers that the libssl-dev package makes 78available. Please install that package before trying to build this 79module. (You can always deinstall the package afterwards, once 80Crypt::SSLeay has been built). 81DEBIAN_INFO 82 } 83} 84 85my $SSL_DIR; 86my $pkg_config; 87 88if (@CANDIDATE == 1) { 89 $pkg_config = $CANDIDATE[0]; 90 if ($opt_default) { 91 $SSL_DIR = $pkg_config->{dir}; 92 } 93 else { 94 print <<"INFO"; 95======================================================= 96Only one $pkg_config->{type} installation found at $pkg_config->{dir} 97Consider running 'perl Makefile.PL --default' the next 98time Crypt::SSLeay is upgraded to select this directory 99automatically thereby avoiding the following prompt. 100======================================================= 101INFO 102 } 103} 104elsif (@CANDIDATE > 1) { 105 print "Found multiple possibilities for OpenSSL\n"; 106 for my $c (@CANDIDATE) { 107 print " $c->{dir} ($c->{type} $c->{ver})\n"; 108 } 109} 110 111if (not $SSL_DIR) { 112 my %cand; 113 for my $c (@CANDIDATE) { 114 $cand{$c->{dir}} = {%$c}; 115 } 116 117 $SSL_DIR = prompt "Which SSL install path do you want to use?", 118 $CANDIDATE[0]->{dir}; 119 120 if (exists $cand{$SSL_DIR}) { 121 # we've already determined that this directory is usable 122 $pkg_config = $cand{$SSL_DIR}; 123 } 124 else { 125 # unknown directory, better check it out 126 $pkg_config = Candidate($SSL_DIR); 127 if (not $pkg_config) { 128 die <<"INFO"; 129$SSL_DIR does not appear to be an SSL library installation, since 130the required header files were not found. The build cannot proceed. 131INFO 132 } 133 } 134} 135 136# note: $SSL_DIR is now sane at this point 137 138my (@INC_FLAGS, @LIB_FLAGS); 139 140if ($^O eq 'VMS') { 141 push @INC_FLAGS, "-I$pkg_config->{inc}"; 142 push @LIB_FLAGS, qw(-L/SYS$SHARE -lSSL$LIBSSL_SHR32 -lSSL$LIBCRYPTO_SHR32); 143} 144elsif ($^O eq 'MSWin32') { 145 # external tools probably expect \ and not / for path separators 146 $SSL_DIR =~ tr{/}{\\}; 147 148 # default to drive C: if no drive or relative path 149 $SSL_DIR = "c:$SSL_DIR" if $SSL_DIR !~ m{\A(?:[a-z]:|\.\.[\\/])}i; 150 151 my $inc = $pkg_config->{inc}; 152 $inc =~ tr{/}{\\}; 153 $inc = "c:$inc" if $inc !~ m{\A(?:[a-z]:|\.\.[\\/])}i; 154 push @INC_FLAGS, "-I$inc"; 155 push @INC_FLAGS, "-I$SSL_DIR\\inc32" if -d "$SSL_DIR/inc32"; 156 157 my $vanilla = $Config{cc} eq 'gcc' ? 1 : 0; 158 $vanilla and print "Assuming Vanilla/Strawberry Perl installation\n"; 159 160 if ($vanilla and -d "$SSL_DIR\\lib\\MinGW") { 161 push @LIB_FLAGS, "-L$SSL_DIR\\lib\\MinGW"; 162 } 163 elsif(-d "$SSL_DIR/lib") { 164 push @LIB_FLAGS, "-L$SSL_DIR\\lib"; 165 } 166 else { 167 my $dir = $opt_static ? "$SSL_DIR\\out32" : "$SSL_DIR\\out32dll"; 168 if (-d $dir) { 169 push @LIB_FLAGS, "-L$dir"; 170 } 171 else { 172 # Allow developers to point at OpenSSL source... 173 push @LIB_FLAGS, "-L$SSL_DIR"; 174 } 175 } 176 177 push @LIB_FLAGS, qw(-lssleay32 -llibeay32); 178 push @LIB_FLAGS, qw(-lRSAglue -lrsaref) if $pkg_config->{type} ne 'OpenSSL'; 179} 180else { 181 push @INC_FLAGS, "-I$pkg_config->{inc}"; 182 183 push @LIB_FLAGS, "-L$pkg_config->{lib}", qw(-lssl -lcrypto -lgcc); 184 push @LIB_FLAGS, qw(-lRSAglue -lrsaref) if $pkg_config->{type} ne 'OpenSSL'; 185 186 # ccc on alpha support 187 if ($^O eq 'linux' 188 and `uname -m` =~ /alpha/ 189 and !(system("nm $SSL_DIR/lib/libssl.a|grep -q 'U _Ots'")>>8) 190 ) { 191 push @LIB_FLAGS, '-lots'; 192 } 193 194 # this fix was suggested for building on RedHat 9 195 push @INC_FLAGS, '-I/usr/kerberos/include' if -d '/usr/kerberos/include'; 196} 197 198# write include file that determines ssl support 199# we need to include crypto.h for SSLeay so the version gets picked up in SSLeay.xs 200 201open(INCLUDE, ">crypt_ssleay_version.h") || die("can't open crypt_ssleay_version.h for writing: $!"); 202print INCLUDE <<"INFO"; 203#include "$pkg_config->{prefix}ssl.h" 204#include "$pkg_config->{prefix}crypto.h" 205#include "$pkg_config->{prefix}err.h" 206#include "$pkg_config->{prefix}rand.h" 207#include "$pkg_config->{prefix}pkcs12.h" 208 209INFO 210 211if ($] < 5.005) { 212 print "adding PL_sv_undef symbol for this ancient perl installation"; 213 print INCLUDE <<"INFO"; 214/* defining PL_sv_undef for very old perls ($]) */ 215#ifndef PL_sv_undef 216#define PL_sv_undef sv_undef 217#endif 218 219INFO 220} 221 222if ($pkg_config->{type} eq 'OpenSSL') { 223 # OPENSSL_free defined in OpenSSL 0.9.6 and higher 224 if ($pkg_config->{ver} =~ /\b0\.9\.[2-5]/) { 225 print INCLUDE "#define CRYPT_SSLEAY_free free\n"; 226 } 227 else { 228 print INCLUDE "#define CRYPT_SSLEAY_free OPENSSL_free\n"; 229 } 230} 231else { 232 print INCLUDE "#define CRYPT_SSLEAY_free free\n"; 233} 234 235close INCLUDE or die "Cannot close crypt_ssleay_version.h for output: $!\n"; 236 237print <<"INFO"; 238 239BUILD INFORMATION 240================================================ 241ssl library: $pkg_config->{type} $pkg_config->{ver} in $SSL_DIR 242ssl header: $pkg_config->{prefix}ssl.h 243libraries: @LIB_FLAGS 244include dir: @INC_FLAGS 245================================================ 246INFO 247 248my @license = 249 do { 250 my $version = $ExtUtils::MakeMaker::VERSION; 251 $version =~ tr/_//d; 252 $version} > 6.30 253 ? qw(LICENSE perl) 254 : (); 255 256WriteMakefile( 257 NAME => 'Crypt::SSLeay', 258 AUTHOR => 'David Landgren', 259 ABSTRACT_FROM => 'SSLeay.pm', 260 VERSION_FROM => 'SSLeay.pm', 261 LIBS => ["@LIB_FLAGS"], 262 INC => "@INC_FLAGS", 263 NEEDS_LINKING => 1, 264 clean => { 265 FILES => 'crypt_ssleay_version.h test.config', 266 }, 267 @license, 268); 269 270if (open OUT, '> test.config') { 271 print OUT <<"INFO"; 272ssl $pkg_config->{type} $pkg_config->{ver} in $SSL_DIR 273lib @LIB_FLAGS 274inc @INC_FLAGS 275cc $Config{cc} 276INFO 277 278 print <<"INFO"; 279The test suite can attempt to connect to public servers 280to ensure that the code is working properly. If you are 281behind a strict firewall or have no network connectivity, 282these tests may fail (through no fault of the code). 283 284INFO 285 my $network_tests = prompt 286 "Do you want to run the live tests (y/N) ?", 287 'N'; 288 print OUT "network_tests ", ($network_tests =~ /y/i) ? 1 : 0, "\n"; 289 close OUT; 290} 291 292## HELPERS 293 294sub Candidate { 295 my $dir = shift; 296 return unless -d $dir; 297 298 my $inc_dir; 299 my $version_file; 300 for ( 301 "$dir/inc32/openssl/opensslv.h", # old win32 builds 302 "$dir/crypto/opensslv.h", # cygwin32 builds 303 "$dir/include/openssl/opensslv.h", 304 "$dir/../include/openssl/opensslv.h", # Solaris 305 "$dir/include/opensslv.h", 306 "$dir/include/crypto.h" 307 ) { 308 if (-e $_) { 309 $version_file = $_; 310 last; 311 } 312 } 313 return unless defined $version_file; 314 my $fingerprint = join(':', (stat $version_file)[0,1]); 315 316 my $open_ssl = ($version_file =~ /openssl/i) ? 1 : 0; 317 $inc_dir = dirname($version_file); 318 return unless -e "$inc_dir/ssl.h"; 319 320 my $prefix; 321 if ($^O eq 'MSWin32') { 322 $inc_dir =~ s{[\\/]openssl\z}{}; 323 $prefix = 'openssl/'; 324 } 325 elsif (index($inc_dir, '/../') > -1) { 326 # OpenSSL include directory is in a sibling directory 327 $inc_dir =~ s{\/openssl\z}{}; 328 $prefix = 'openssl/'; 329 } 330 else { 331 $prefix = ($inc_dir =~ /\bopenssl/i) ? 'openssl/' : ''; 332 } 333 334 open(VERSION_FILE, $version_file) or return; 335 my $version_match = $open_ssl ? "OPENSSL_VERSION_NUMBER" : "SSLEAY_VERSION_NUMBER"; 336 my $version; 337 my $type; 338 while (<VERSION_FILE>) { 339 if (/^#define\s+$version_match\s+0x0+(\d\d\d)/) { 340 $version = $1; 341 $version =~ s/(\d)0(\d)/$1$2/; 342 $type = ($version > 92) ? "OpenSSL" : "SSLeay"; 343 $version = join('.', split(//, "0$version")); 344 last; 345 } 346 } 347 close(VERSION_FILE); 348 349 # Silly test to look for the library files 350 my $found_lib; 351 my $libd; 352 my $subdir = $opt_static ? 'out32' : 'out32dll'; 353 if (-d "$dir/$subdir") { 354 $libd = [$subdir]; 355 } 356 elsif ($^O eq 'MSWin32' and $Config{cc} eq 'gcc') { 357 $libd = ['lib/MinGW']; 358 } 359 else { 360 # second attempt is for Solaris, like the include directory, the 361 # library directory may be in a sibling directory 362 $libd = ['lib', '../lib']; 363 } 364 365 SCAN: 366 for my $d (@$libd) { 367 my $lib_dir = "$dir/$d"; 368 if (opendir(LIBDIR, $lib_dir)) { 369 while (defined($_ = readdir(LIBDIR))) { 370 if (/\A(?:lib(?:crypto|eay32|ssl)|ssleay32)/) { 371 $found_lib = $lib_dir; 372 last SCAN; 373 } 374 } 375 closedir(LIBDIR); 376 } 377 } 378 379 if (!$found_lib) { 380 my @tried = join( ',' => map {"$dir/$_"} @$libd); 381 print "Did not locate expected SSL library files in @tried\n"; 382 } 383 384 return { 385 dir => $dir, 386 inc => $inc_dir, 387 lib => $found_lib, 388 ver => $version, 389 type => $type, 390 prefix => $prefix, 391 check => $fingerprint, 392 }; 393} 394 395