Configure - Allow CODErefs and ARRAYrefs in configuration setting arrays
[openssl.git] / Configure
index 7942a593b8fa54b91da10eee3c9522d3f8d296c1..ce8fac77be4d08ba1e8aa46e97a24cce935e90dc 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -47,7 +47,7 @@ my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lx
 #               know how to do it)
 # [no-]shared  [don't] try to create shared libraries when supported.
 # [no-]pic      [don't] try to build position independent code when supported.
-#               If disabled, it also disables shared and dynamic-engines.
+#               If disabled, it also disables shared and dynamic-engine.
 # no-asm        do not use assembler
 # no-dso        do not compile in any native shared-library methods. This
 #               will ensure that all methods just return NULL.
@@ -94,11 +94,11 @@ my $gcc_devteam_warn = "-DPEDANTIC -DREF_DEBUG -DDEBUG_UNUSED -DBIO_DEBUG"
 # TODO(openssl-team): fix problems and investigate if (at least) the
 # following warnings can also be enabled:
 #       -Wswitch-enum
-#       -Wunused-macros
 #       -Wcast-align
 #       -Wunreachable-code
-#       -Wlanguage-extension-token
-#       -Wextended-offsetof
+#       -Wlanguage-extension-token -- no, we use asm()
+#       -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
+#       -Wextended-offsetof -- no, needed in CMS ASN1 code
 my $clang_devteam_warn = ""
         . " -Qunused-arguments"
         . " -Wextra"
@@ -208,13 +208,7 @@ $config{cross_compile_prefix}="";
 $config{fipslibdir}="/usr/local/ssl/fips-2.0/lib/";
 my $nofipscanistercheck=0;
 $config{baseaddr}="0xFB00000";
-my $no_threads=0;
 my $threads=0;
-$config{no_shared}=0; # but "no-shared" is default
-my $zlib=1;      # but "no-zlib" is default
-my $no_rfc3779=0;
-my $no_asm=0;
-my $no_dso=0;
 my $default_ranlib;
 $config{fips}=0;
 
@@ -328,22 +322,26 @@ foreach my $proto ((@tls, @dtls))
        push(@disablables, "$proto-method");
        }
 
+my @deprecated_disablables = (
+    "ssl2",
+    );
+
 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
 
-my %disabled = ( # "what"         => "comment"
-                "ec_nistp_64_gcc_128" => "default",
-                "egd"            => "default",
-                "md2"            => "default",
-                "rc5"            => "default",
-                "sctp"           => "default",
-                "shared"         => "default",
-                "ssl-trace"      => "default",
-                "static-engine"  => "default",
-                "unit-test"      => "default",
-                "zlib"           => "default",
-                "crypto-mdebug"  => "default",
-                "heartbeats"     => "default",
-              );
+our %disabled = ( # "what"         => "comment"
+                 "ec_nistp_64_gcc_128" => "default",
+                 "egd"            => "default",
+                 "md2"            => "default",
+                 "rc5"            => "default",
+                 "sctp"           => "default",
+                 "shared"         => "default",
+                 "ssl-trace"      => "default",
+                 "static-engine"  => "default",
+                 "unit-test"      => "default",
+                 "zlib"           => "default",
+                 "crypto-mdebug"  => "default",
+                 "heartbeats"     => "default",
+               );
 
 # Note: => pair form used for aesthetics, not to truly make a hash table
 my @disable_cascades = (
@@ -496,6 +494,7 @@ if (grep /^reconf(igure)?$/, @argvcopy) {
 $config{perlargv} = [ @argvcopy ];
 
 my %unsupported_options = ();
+my %deprecated_options = ();
 foreach (@argvcopy)
        {
        # VMS is a case insensitive environment, and depending on settings
@@ -517,7 +516,12 @@ foreach (@argvcopy)
         if (/^(no|disable|enable)-(.+)$/)
                {
                my $word = $2;
-               if (!grep { $word =~ /^${_}$/ } @disablables)
+               if (grep { $word =~ /^${_}$/ } @deprecated_disablables)
+                       {
+                       $deprecated_options{$_} = 1;
+                       next;
+                       }
+               elsif (!grep { $word =~ /^${_}$/ } @disablables)
                        {
                        $unsupported_options{$_} = 1;
                        next;
@@ -673,11 +677,6 @@ foreach (@argvcopy)
                        $user_cflags.=" ".$_;
                        }
                }
-       elsif ($_ =~ /^([^:]+):(.+)$/)
-               {
-               eval "\$table{\$1} = \"$2\""; # allow $xxx constructs in the string
-               $target=$1;
-               }
        else
                {
                die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
@@ -700,6 +699,11 @@ foreach (@argvcopy)
                die "***** Unsupported api compatibility level: $config{api}\n",
         }
 
+       if (keys %deprecated_options)
+               {
+               warn "***** Deprecated options: ",
+                       join(", ", keys %deprecated_options), "\n";
+               }
        if (keys %unsupported_options)
                {
                die "***** Unsupported options: ",
@@ -765,15 +769,15 @@ foreach (sort (keys %disabled))
        printf "    no-%-12s %-10s", $_, "[$disabled{$_}]";
 
        if (/^dso$/)
-               { $no_dso = 1; }
+               { }
        elsif (/^threads$/)
-               { $no_threads = 1; }
+               { }
        elsif (/^shared$/)
-               { $config{no_shared} = 1; }
+               { }
        elsif (/^pic$/)
                { }
        elsif (/^zlib$/)
-               { $zlib = 0; }
+               { }
        elsif (/^dynamic-engine$/)
                { }
        elsif (/^zlib-dynamic$/)
@@ -791,14 +795,13 @@ foreach (sort (keys %disabled))
                my ($ALGO, $algo);
                ($ALGO = $algo = $_) =~ tr/[\-a-z]/[_A-Z]/;
 
-               if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/
+               if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/ || /^async$/
                                || /^autoalginit/ || /^autoerrinit/)
                        {
                        push @{$config{openssl_other_defines}}, "OPENSSL_NO_$ALGO";
                        print " OPENSSL_NO_$ALGO";
 
                        if (/^err$/)    { push @user_defines, "OPENSSL_NO_ERR"; }
-                       elsif (/^asm$/) { $no_asm = 1; }
                        }
                else
                        {
@@ -833,10 +836,13 @@ if ($d) {
 }
 $config{target} = $target;
 delete $table{$base_target}->{template}; # or the next test will fail.
-my %target = ( %{$table{$base_target}}, resolve_config($target) );
+my %target = resolve_config($target);
 
 &usage if (!%target || $target{template});
 
+# Set up defaults
+my %target = ( %{$table{$base_target}}, %target );
+
 $target{exe_extension}="";
 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
                                   || $config{target} =~ /^(?:Cygwin|mingw)/);
@@ -850,15 +856,15 @@ $target{dso_extension}=$target{shared_extension_simple};
     if ($config{target} =~ /^(?:Cygwin|mingw)/);
 
 
-$default_ranlib        = which("ranlib") || "true";
-$config{perl}  = $ENV{'PERL'} || which("perl5") || which("perl") || "perl";
-my $make       = $ENV{'MAKE'} || "make";
-
 $config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'}
     if $config{cross_compile_prefix} eq "";
 
-# Allow environment CC to override compiler...
-$target{cc} = $ENV{CC} || $target{cc};
+# Allow overriding the names of some tools.  USE WITH CARE
+$config{perl} =    $ENV{'PERL'}    || which("perl5") || which("perl") || "perl";
+$target{cc} =      $ENV{'CC'}      || $target{cc}      || "cc";
+$target{ranlib} =  $ENV{'RANLIB'}  || $target{ranlib}  || which("ranlib") || "true";
+$target{ar} =      $ENV{'AR'}      || $target{ar}      || "ar";
+$target{nm} =      $ENV{'NM'}      || $target{nm}      || "nm";
 
 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
 # or release_ attributes.
@@ -878,10 +884,6 @@ $config{ex_libs} = join(" ",
                        grep { $_  ne "" } ($target{ex_libs},
                                            $target{$build_prefix."ex_libs"}));
 
-$target{ranlib} = $ENV{'RANLIB'} || $target{ranlib} || $default_ranlib;
-$target{ar} = $ENV{'AR'} || "ar";
-$target{arflags} = "" if !defined($target{arflags});
-$target{nm} = "nm";
 # Make sure build_scheme is consistent.
 $target{build_scheme} = [ $target{build_scheme} ]
     if ref($target{build_scheme}) ne "ARRAY";
@@ -905,7 +907,7 @@ if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
        $target{shared_ldflag} .= " -mno-cygwin";
        }
 
-if ($target =~ /linux.*-mips/ && !$no_asm && $user_cflags !~ /-m(ips|arch=)/) {
+if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
        # minimally required architecture flags for assembly modules
        $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
        $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
@@ -921,7 +923,7 @@ my $no_user_defines=0;
 # has support compiled in for them. Currently each method is enabled
 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
 # string entry into using the following logic;
-if (!$no_dso && $target{dso_scheme} ne "")
+if (!$disabled{dso} && $target{dso_scheme} ne "")
        {
        $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
        if ($target{dso_scheme} eq "DLFCN")
@@ -942,7 +944,7 @@ if (!$no_dso && $target{dso_scheme} ne "")
 
 my $thread_cflags = "";
 my @thread_defines;
-if ($target{thread_cflag} ne "(unknown)" && !$no_threads)
+if ($target{thread_cflag} ne "(unknown)" && !$disabled{threads})
        {
        # If we know how to do it, support threads by default.
        $threads = 1;
@@ -968,7 +970,7 @@ else
 
 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
 
-if ($no_asm)
+if ($disabled{asm})
        {
        @{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}}
            if ($config{fips});
@@ -981,7 +983,7 @@ if ($threads)
        push @{$config{openssl_thread_defines}}, @thread_defines;
        }
 
-if ($zlib)
+unless ($disabled{zlib})
        {
        push @{$config{defines}}, "ZLIB";
        if (defined($disabled{"zlib-dynamic"}))
@@ -1009,9 +1011,9 @@ if (defined($disabled{"deprecated"})) {
 if ($target{shared_target} eq "")
        {
        $no_shared_warn = 1
-           if ((!$config{no_shared} || !$disabled{"dynamic-engine"})
+           if ((!$disabled{shared} || !$disabled{"dynamic-engine"})
                && !$config{fips});
-       $config{no_shared} = 1;
+       $disabled{shared} = "no-shared-target";
        $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
            "no-shared-target";
        }
@@ -1034,18 +1036,17 @@ if ($disabled{pic})
        $target{shared_cflag} = $target{shared_ldflag} =
                $target{shared_rcflag} = "";
        }
-
-if ($target{sys_id} ne "")
+else
        {
-       push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
+       push @{$config{defines}}, "OPENSSL_PIC";
        }
 
-if ($target{ranlib} eq "")
+if ($target{sys_id} ne "")
        {
-       $target{ranlib} = $default_ranlib;
+       push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
        }
 
-if (!$no_asm) {
+unless ($disabled{asm}) {
     $target{cpuid_asm_src}=$table{BASE}->{cpuid_asm_src} if ($config{processor} eq "386");
     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
 
@@ -1256,6 +1257,8 @@ if ($builder eq "unified") {
             if (-f catfile($srcdir, "engines", $_, "build.info"));
     }
 
+    $config{build_infos} = [ ];
+
     foreach (@build_infos) {
         my $sourced = catdir($srcdir, $_->[0]);
         my $buildd = catdir($blddir, $_->[0]);
@@ -1279,6 +1282,7 @@ if ($builder eq "unified") {
         my %renames = ();
         my %sharednames = ();
 
+        push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
         my $template = Text::Template->new(TYPE => 'FILE',
                                            SOURCE => catfile($sourced, $f));
         die "Something went wrong with $sourced/$f: $!\n" unless $template;
@@ -1286,6 +1290,7 @@ if ($builder eq "unified") {
             split /^/m,
             $template->fill_in(HASH => { config => \%config,
                                          target => \%target,
+                                         disabled => \%disabled,
                                          builddir => abs2rel($buildd, $blddir),
                                          sourcedir => abs2rel($sourced, $blddir),
                                          buildtop => abs2rel($blddir, $blddir),
@@ -1431,7 +1436,7 @@ EOF
 
         push @{$unified_info{rawlines}}, @rawlines;
 
-        if (!$config{no_shared}) {
+        unless ($disabled{shared}) {
             # Check sharednames.
             foreach (keys %sharednames) {
                 my $dest = cleanfile($buildd, $_, $blddir);
@@ -1590,7 +1595,7 @@ use warnings;
 use Exporter;
 #use vars qw(\@ISA \@EXPORT);
 our \@ISA = qw(Exporter);
-our \@EXPORT = qw(\%config \%target %withargs %unified_info);
+our \@EXPORT = qw(\%config \%target %disabled %withargs %unified_info);
 
 EOF
 print OUT "our %config = (\n";
@@ -1703,7 +1708,9 @@ print "DEFINES       =",join(" ", @{$config{defines}}),"\n";
 print "LFLAG         =$config{lflags}\n";
 print "PLIB_LFLAG    =$config{plib_lflags}\n";
 print "EX_LIBS       =$config{ex_libs}\n";
+print "APPS_OBJ      =$target{apps_obj}\n";
 print "CPUID_OBJ     =$target{cpuid_obj}\n";
+print "UPLINK_OBJ    =$target{uplink_obj}\n";
 print "BN_ASM        =$target{bn_obj}\n";
 print "EC_ASM        =$target{ec_obj}\n";
 print "DES_ENC       =$target{des_obj}\n";
@@ -1860,7 +1867,7 @@ print <<"EOF";
 Configured for $target.
 EOF
 
-print <<"EOF" if (!$no_threads && !$threads);
+print <<"EOF" if (!$disabled{threads} && !$threads);
 
 The library could not be configured for supporting multi-threaded
 applications as the compiler options required on this system are not known.
@@ -1919,14 +1926,14 @@ exit(0);
 # Configuration file reading #########################################
 
 # Helper function to implement conditional inheritance depending on the
-# value of $no_asm.  Used in inherit_from values as follows:
+# value of $disabled{asm}.  Used in inherit_from values as follows:
 #
 #      inherit_from => [ "template", asm("asm_tmpl") ]
 #
 sub asm {
     my @x = @_;
     sub {
-       $no_asm ? () : @x;
+       $disabled{asm} ? () : @x;
     }
 }
 
@@ -1942,27 +1949,43 @@ sub _add {
 
     my @values =
        map {
-           if (ref($_) eq "ARRAY") {
-               $found_array = 1;
-               @$_;
+           my $res = $_;
+           while (ref($res) eq "CODE") {
+               $res = $res->();
+           }
+           if (defined($res)) {
+               if (ref($res) eq "ARRAY") {
+                   $found_array = 1;
+                   @$res;
+               } else {
+                   $res;
+               }
            } else {
-               $_;
+               ();
            }
     } (@_);
 
     if ($found_array) {
        [ @values ];
     } else {
-       join($separator, @values);
+       join($separator, grep { defined($_) && $_ ne "" } @values);
     }
 }
 sub add_before {
-    my $separator = shift;
+    my $separator = " ";
+    if (ref($_[$#_]) eq "HASH") {
+        my $opts = pop;
+        $separator = $opts->{separator};
+    }
     my @x = @_;
     sub { _add($separator, @x, @_) };
 }
 sub add {
-    my $separator = shift;
+    my $separator = " ";
+    if (ref($_[$#_]) eq "HASH") {
+        my $opts = pop;
+        $separator = $opts->{separator};
+    }
     my @x = @_;
     sub { _add($separator, @_, @x) };
 }
@@ -2060,11 +2083,35 @@ sub resolve_config {
     #   value.
     # - Otherwise, this target's value is assumed to be a string that
     #   will simply override the inherited list of values.
-    my $default_combiner = add(" ");
+    my $default_combiner = add();
 
     my %all_keys =
        map { $_ => 1 } (keys %combined_inheritance,
                         keys %{$table{$target}});
+
+    sub process_values {
+       my $object    = shift;
+       my $inherited = shift;  # Always a [ list ]
+       my $target    = shift;
+       my $entry     = shift;
+
+        while(ref($object) eq "CODE") {
+            $object = $object->(@$inherited);
+        }
+        if (!defined($object)) {
+            return ();
+        }
+        elsif (ref($object) eq "ARRAY") {
+            return [ map { process_values($_, $inherited, $target, $entry) }
+                     @$object ];
+        } elsif (ref($object) eq "") {
+            return $object;
+        } else {
+            die "cannot handle reference type ",ref($object)
+                ," found in target ",$target," -> ",$entry,"\n";
+        }
+    }
+
     foreach (sort keys %all_keys) {
 
        # Current target doesn't have a value for the current key?
@@ -2074,20 +2121,12 @@ sub resolve_config {
            $table{$target}->{$_} = $default_combiner;
        }
 
-       my $valuetype = ref($table{$target}->{$_});
-       if ($valuetype eq "CODE") {
-           # CODE reference, execute it with the inherited values as
-           # arguments.
-           $table{$target}->{$_} =
-               $table{$target}->{$_}->(@{$combined_inheritance{$_}});
-       } elsif ($valuetype eq "ARRAY" || $valuetype eq "") {
-           # ARRAY or Scalar, just leave it as is.
-       } else {
-           # Some other type of reference that we don't handle.
-           # Better to abort at this point.
-           die "cannot handle reference type $valuetype,"
-               ," found in target $target -> $_\n";
-       }
+       $table{$target}->{$_} = process_values($table{$target}->{$_},
+                                              $combined_inheritance{$_},
+                                              $target, $_);
+        unless(defined($table{$target}->{$_})) {
+            delete $table{$target}->{$_};
+        }
     }
 
     # Finally done, return the result.
@@ -2217,14 +2256,24 @@ sub print_table_entry
     if ($type eq "TABLE") {
        print "\n";
        print "*** $target\n";
-       printf "\$%-12s = %s\n", $_, $target{$_} foreach (@sequence);
+        foreach (@sequence) {
+            if (ref($target{$_}) eq "ARRAY") {
+                printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
+            } else {
+                printf "\$%-12s = %s\n", $_, $target{$_};
+            }
+        }
     } elsif ($type eq "HASH") {
        my $largest =
            length((sort { length($a) <=> length($b) } @sequence)[-1]);
        print "    '$target' => {\n";
        foreach (@sequence) {
            if ($target{$_}) {
-               print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
+                if (ref($target{$_}) eq "ARRAY") {
+                    print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
+                } else {
+                    print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
+                }
            }
        }
        print "    },\n";