Copyright consolidation 01/10
[openssl.git] / Configure
index 62e1b19..4d3346e 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -1,5 +1,11 @@
 #! /usr/bin/env perl
 # -*- mode: perl; -*-
+# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
 
 ##  Configure -- OpenSSL source tree configuration script
 
@@ -8,6 +14,7 @@ use strict;
 use File::Basename;
 use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
 use File::Path qw/mkpath/;
+use IPC::Cmd qw/can_run/;
 
 # see INSTALL for instructions.
 
@@ -77,10 +84,21 @@ my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lx
 # Minimum warning options... any contributions to OpenSSL should at least get
 # past these.
 
-my $gcc_devteam_warn = "-DPEDANTIC -DREF_DEBUG -DDEBUG_UNUSED -DBIO_DEBUG"
-        . " -pedantic"
+# DEBUG_UNUSED enables __owur (warn unused result) checks.
+my $gcc_devteam_warn = "-DDEBUG_UNUSED"
+        # -DPEDANTIC complements -pedantic and is meant to mask code that
+        # is not strictly standard-compliant and/or implementation-specifc,
+        # e.g. inline assembly, disregards to alignment requirements, such
+        # that -pedantic would complain about. Incidentally -DPEDANTIC has
+        # to be used even in sanitized builds, because sanitizer too is
+        # supposed to and does take notice of non-standard behaviour. Then
+        # -pedantic with pre-C9x compiler would also complain about 'long
+        # long' not being supported. As 64-bit algorithms are common now,
+        # it grew impossible to resolve this without sizeable additional
+        # code, so we just tell compiler to be pedantic about everything
+        # but 'long long' type.
+        . " -DPEDANTIC -pedantic -Wno-long-long"
         . " -Wall"
-        . " -Wno-long-long"
         . " -Wsign-compare"
         . " -Wmissing-prototypes"
         . " -Wshadow"
@@ -161,6 +179,8 @@ my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
 my $blddir = catdir(absolutedir("."));         # catdir ensures local syntax
 my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
 
+my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
+
 $config{sourcedir} = abs2rel($srcdir);
 $config{builddir} = abs2rel($blddir);
 
@@ -195,6 +215,20 @@ foreach (sort glob($pattern) ) {
     &read_config($_);
 }
 
+if (defined $ENV{$local_config_envname}) {
+    if ($^O eq 'VMS') {
+        # VMS environment variables are logical names,
+        # which can be used as is
+        $pattern = $local_config_envname . ':' . '*.conf';
+    } else {
+        $pattern = catfile($ENV{$local_config_envname}, '*.conf');
+    }
+
+    foreach (sort glob($pattern) ) {
+        &read_config($_);
+    }
+}
+
 
 print "Configuring OpenSSL version $config{version} (0x$config{version_num})\n";
 
@@ -232,8 +266,8 @@ my @dtls = qw(dtls1 dtls1_2);
 # For developers: keep it sorted alphabetically
 
 my @disablables = (
-    "aes",
     "afalgeng",
+    "asan",
     "asm",
     "async",
     "autoalginit",
@@ -267,15 +301,14 @@ my @disablables = (
     "engine",
     "err",
     "filenames",
+    "fuzz",
     "gost",
     "heartbeats",
-    "hmac",
     "hw(-.+)?",
     "idea",
     "makedepend",
     "md2",
     "md4",
-    "md5",
     "mdc2",
     "multiblock",
     "nextprotoneg",
@@ -292,12 +325,9 @@ my @disablables = (
     "rfc3779",
     "ripemd",
     "rmd160",
-    "rsa",
     "scrypt",
-    "sct",
     "sctp",
     "seed",
-    "sha",
     "shared",
     "sock",
     "srp",
@@ -310,6 +340,7 @@ my @disablables = (
     "threads",
     "tls",
     "ts",
+    "ubsan",
     "ui",
     "unit-test",
     "whirlpool",
@@ -330,15 +361,17 @@ my @deprecated_disablables = (
 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
 
 our %disabled = ( # "what"         => "comment"
+                  "asan"               => "default",
                  "ec_nistp_64_gcc_128" => "default",
                  "egd"                 => "default",
+                 "fuzz"                => "default",
                  "md2"                 => "default",
                  "rc5"                 => "default",
                  "sctp"                => "default",
-                 "shared"              => "default",
                  "ssl-trace"           => "default",
                  "ssl3"                => "default",
                  "ssl3-method"         => "default",
+                  "ubsan"              => "default",
                  "unit-test"           => "default",
                  "weak-ssl-ciphers"    => "default",
                  "zlib"                => "default",
@@ -359,7 +392,7 @@ my @disable_cascades = (
     "ec"               => [ "ecdsa", "ecdh" ],
 
     "dgram"            => [ "dtls", "sctp" ],
-    "sock"             => [ "sctp" ],
+    "sock"             => [ "dgram" ],
     "dtls"             => [ @dtls ],
 
     # SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA
@@ -394,6 +427,12 @@ my @disable_cascades = (
     "pic"               => [ "shared" ],
     "shared"            => [ "dynamic-engine" ],
     "engine"            => [ "afalgeng" ],
+
+    # no-autoalginit is only useful when building non-shared
+    "autoalginit"       => [ "shared", "apps" ],
+
+    "stdio"             => [ "apps" ],
+    "apps"              => [ "tests" ],
     "comp"             => [ "zlib" ],
     sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
     );
@@ -447,8 +486,6 @@ my $target="";
 $config{options}="";
 $config{build_type} = "release";
 
-my $classic = 0;
-
 my @argvcopy=@ARGV;
 
 if (grep /^reconf(igure)?$/, @argvcopy) {
@@ -633,11 +670,7 @@ foreach (@argvcopy)
                }
        elsif (/^[-+]/)
                {
-               if (/^--classic$/)
-                       {
-                       $classic=1;
-                       }
-               elsif (/^--prefix=(.*)$/)
+               if (/^--prefix=(.*)$/)
                        {
                        $config{prefix}=$1;
                        die "Directory given with --prefix MUST be absolute\n"
@@ -661,7 +694,7 @@ foreach (@argvcopy)
                        }
                elsif (/^--with-zlib-include=(.*)$/)
                        {
-                       $withargs{zlib_include}="-I$1";
+                       $withargs{zlib_include}=$1;
                        }
                elsif (/^--with-fipslibdir=(.*)$/)
                        {
@@ -743,9 +776,9 @@ while (@tocheckfor) {
     while (@cascade_copy) {
        my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
        if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
-           map {
+           foreach(grep { !defined($disabled{$_}) } @$descendents) {
                $new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
-           } grep { !defined($disabled{$_}) } @$descendents;
+           }
        }
     }
     @tocheckfor = (keys %new_tocheckfor);
@@ -877,9 +910,13 @@ $config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'}
 # Allow overriding the names of some tools.  USE WITH CARE
 $config{perl} =    $ENV{'PERL'}    || ($^O ne "VMS" ? $^X : "perl");
 $target{cc} =      $ENV{'CC'}      || $target{cc}      || "cc";
-$target{ranlib} =  $ENV{'RANLIB'}  || $target{ranlib}  || which("ranlib") || "true";
+$target{ranlib} =  $ENV{'RANLIB'}  || $target{ranlib}  ||
+                   (scalar can_run("$config{cross_compile_prefix}ranlib") ?
+                          "\$(CROSS_COMPILE)ranlib" : "true");
 $target{ar} =      $ENV{'AR'}      || $target{ar}      || "ar";
 $target{nm} =      $ENV{'NM'}      || $target{nm}      || "nm";
+$target{rc} =
+    $ENV{'RC'}  || $ENV{'WINDRES'} || $target{rc}      || "windres";
 
 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
 # or release_ attributes.
@@ -893,22 +930,6 @@ $config{shared_ldflag} = "";
 $target{build_scheme} = [ $target{build_scheme} ]
     if ref($target{build_scheme}) ne "ARRAY";
 
-###### TO BE REMOVED WHEN CLASSIC BUILD IS REMOVED
-######
-###### If the user has chosen --classic, we give it to them.
-###### If they try that with an out-of-source config, we complain.
-if ($target{build_scheme}->[0] eq "unified" && $classic) {
-    die "Can't perform a classic build out of source tree\n"
-        if $srcdir ne $blddir;
-
-    $target{build_scheme} = { unix    => [ "unixmake" ],
-                              windows => undef,
-                              VMS     => undef } -> {$target{build_scheme}->[1]};
-
-    die "Classic mode unavailable on this platform\n"
-        unless defined($target{build_scheme});
-}
-
 my ($builder, $builder_platform, @builder_opts) =
     @{$target{build_scheme}};
 
@@ -1019,6 +1040,24 @@ if ($disabled{"dynamic-engine"}) {
         $config{dynamic_engines} = 1;
 }
 
+unless ($disabled{fuzz}) {
+    push @{$config{dirs}}, "fuzz";
+    $config{cflags} .= "-fsanitize-coverage=edge,indirect-calls ";
+}
+
+unless ($disabled{asan}) {
+    $config{cflags} .= "-fsanitize=address ";
+}
+
+unless ($disabled{ubsan}) {
+    # -DPEDANTIC or -fnosanitize=aligmnent may also be required on some
+    # platforms.
+    $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all ";
+}
+
+unless ($disabled{fuzz} && $disabled{asan} && $disabled{ubsan}) {
+    $config{cflags} .= "-fno-omit-frame-pointer -g ";
+}
 #
 # Platform fix-ups
 #
@@ -1117,7 +1156,7 @@ if ($^O ne "VMS" && !$disabled{makedepend}) {
     }
     close(PIPE);
 
-    $config{makedepprog} = which('makedepend') unless $config{makedepprog};
+    $config{makedepprog} = scalar can_run('makedepend') unless $config{makedepprog};
     $disabled{makedepend} = "unavailable" unless $config{makedepprog};
 }
 
@@ -1228,12 +1267,27 @@ my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
 if ($builder eq "unified") {
     # Store the name of the template file we will build the build file from
     # in %config.  This may be useful for the build file itself.
-    my $build_file_template =
-        catfile($srcdir, "Configurations",
-                $builder_platform."-".$target{build_file}.".tmpl");
-    $build_file_template =
-        catfile($srcdir, "Configurations", $target{build_file}.".tmpl")
-        if (! -f $build_file_template);
+    my $build_file_template;
+
+    for my $filename (( $builder_platform."-".$target{build_file}.".tmpl",
+                        $target{build_file}.".tmpl" )) {
+        if (defined $ENV{$local_config_envname}) {
+            if ($^O eq 'VMS') {
+                # VMS environment variables are logical names,
+                # which can be used as is
+                $build_file_template = $local_config_envname . ':' . $filename;
+            } else {
+                $build_file_template = catfile($ENV{$local_config_envname},
+                                               $filename);
+            }
+        }
+
+        last if -f $build_file_template;
+
+        $build_file_template = catfile($srcdir, "Configurations", $filename);
+
+        last if -f $build_file_template;
+    }
     $config{build_file_template} = $build_file_template;
 
     use lib catdir(dirname(__FILE__),"util");
@@ -1617,9 +1671,15 @@ EOF
 
         foreach (keys %depends) {
             my $dest = $_;
-            my $ddest = cleanfile($buildd, $_, $blddir);
-            if ($unified_info{rename}->{$ddest}) {
-                $ddest = $unified_info{rename}->{$ddest};
+            my $ddest = cleanfile($sourced, $_, $blddir);
+
+            # If the destination doesn't exist in source, it can only be
+            # a generated file in the build tree.
+            if (! -f $ddest) {
+                $ddest = cleanfile($buildd, $_, $blddir);
+                if ($unified_info{rename}->{$ddest}) {
+                    $ddest = $unified_info{rename}->{$ddest};
+                }
             }
             foreach (@{$depends{$dest}}) {
                 my $d = cleanfile($sourced, $_, $blddir);
@@ -1640,9 +1700,9 @@ EOF
                     $d = $unified_info{rename}->{$d};
                 }
                 $unified_info{depends}->{$ddest}->{$d} = 1;
-                # If we depend on a header file, let's make sure it
-                # can get included
-                if ($d =~ /\.h$/) {
+                # If we depend on a header file or a perl module, let's make
+                # sure it can get included
+                if ($d =~ /\.(h|pm)$/) {
                     my $i = dirname($d);
                     push @{$unified_info{includes}->{$ddest}}, $i
                         unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
@@ -1652,9 +1712,15 @@ EOF
 
         foreach (keys %includes) {
             my $dest = $_;
-            my $ddest = cleanfile($buildd, $_, $blddir);
-            if ($unified_info{rename}->{$ddest}) {
-                $ddest = $unified_info{rename}->{$ddest};
+            my $ddest = cleanfile($sourced, $_, $blddir);
+
+            # If the destination doesn't exist in source, it can only be
+            # a generated file in the build tree.
+            if (! -f $ddest) {
+                $ddest = cleanfile($buildd, $_, $blddir);
+                if ($unified_info{rename}->{$ddest}) {
+                    $ddest = $unified_info{rename}->{$ddest};
+                }
             }
             foreach (@{$includes{$dest}}) {
                 my $i = cleandir($sourced, $_, $blddir);
@@ -1812,7 +1878,7 @@ print OUT "1;\n";
 close(OUT);
 
 
-print "CC            =$target{cc}\n";
+print "CC            =$config{cross_compile_prefix}$target{cc}\n";
 print "CFLAG         =$target{cflags} $config{cflags}\n";
 print "SHARED_CFLAG  =$target{shared_cflag}\n";
 print "DEFINES       =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
@@ -1840,7 +1906,9 @@ print "CHACHA_ENC    =$target{chacha_obj}\n";
 print "POLY1305_OBJ  =$target{poly1305_obj}\n";
 print "BLAKE2_OBJ    =$target{blake2_obj}\n";
 print "PROCESSOR     =$config{processor}\n";
-print "RANLIB        =$target{ranlib}\n";
+print "RANLIB        =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
+                             "$config{cross_compile_prefix}ranlib" :
+                             "$target{ranlib}", "\n";
 print "ARFLAGS       =$target{arflags}\n";
 print "PERL          =$config{perl}\n";
 print "\n";
@@ -1928,6 +1996,14 @@ or position independent code, please let us know (but please first make sure
 you have tried with a current version of OpenSSL).
 EOF
 
+print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
+
+WARNING: there are indications that another build was made in the source
+directory.  This build may have picked up artifacts from that build, the
+safest course of action is to clean the source directory and redo this
+configuration.
+EOF
+
 exit(0);
 
 ######################################################################
@@ -2128,12 +2204,12 @@ sub resolve_config {
            # the config that had it.
            delete $inherited_config{template};
 
-           map {
+           foreach (keys %inherited_config) {
                if (!$combined_inheritance{$_}) {
                    $combined_inheritance{$_} = [];
                }
                push @{$combined_inheritance{$_}}, $inherited_config{$_};
-           } keys %inherited_config;
+           }
        }
     }
 
@@ -2389,22 +2465,6 @@ sub absolutedir {
     return realpath($dir);
 }
 
-sub which
-       {
-       my($name)=@_;
-       my $path;
-       foreach $path (split /:/, $ENV{PATH})
-               {
-               my $fullpath = "$path/$name$target{exe_extension}";
-               if (-f $fullpath and -x $fullpath)
-                       {
-                       return $fullpath
-                           unless ($name eq "perl" and
-                                   system("$fullpath -e " . '\'exit($]<5.0);\''));
-                       }
-               }
-       }
-
 sub quotify {
     my %processors = (
        perl    => sub { my $x = shift;
@@ -2415,7 +2475,7 @@ sub quotify {
     my $processor =
        defined($processors{$for}) ? $processors{$for} : sub { shift; };
 
-    map { $processor->($_); } @_;
+    return map { $processor->($_); } @_;
 }
 
 # collect_from_file($filename, $line_concat_cond_re, $line_concat)