Restore makedepend capabilities for Windows and VMS
[openssl.git] / Configure
index 6f2aee38cae08102ce7a2df7595ba21f387114ab..ba646f030a8480b1861bd035e266c655ff9f79c0 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -211,6 +211,8 @@ $config{builddir} = abs2rel($blddir);
 my @argvcopy=@ARGV;
 
 if (grep /^reconf(igure)?$/, @argvcopy) {
+    die "reconfiguring with other arguments present isn't supported"
+        if scalar @argvcopy > 1;
     if (-f "./configdata.pm") {
        my $file = "./configdata.pm";
        unless (my $return = do $file) {
@@ -538,6 +540,14 @@ my @seed_sources = ();
 while (@argvcopy)
        {
        $_ = shift @argvcopy;
+
+       # Support env variable assignments among the options
+       if (m|^(\w+)=(.+)?$|)
+               {
+               $config{perlenv}->{$1} = $2;
+               next;
+               }
+
        # VMS is a case insensitive environment, and depending on settings
        # out of our control, we may receive options uppercased.  Let's
        # downcase at least the part before any equal sign.
@@ -869,9 +879,48 @@ my %target = resolve_config($target);
 
 &usage if (!%target || $target{template});
 
+%target = ( %{$table{DEFAULTS}}, %target );
+
+# Make the flags to build DSOs the same as for shared libraries unless they
+# are already defined
+$target{dso_cflags} = $target{shared_cflag} unless defined $target{dso_cflags};
+$target{dso_cxxflags} = $target{shared_cxxflag} unless defined $target{dso_cxxflags};
+$target{dso_lflags} = $target{shared_ldflag} unless defined $target{dso_lflags};
+{
+    my $shared_info_pl =
+        catfile(dirname($0), "Configurations", "shared-info.pl");
+    my %shared_info = read_eval_file($shared_info_pl);
+    push @{$target{_conf_fname_int}}, $shared_info_pl;
+    my $si = $target{shared_target};
+    while (ref $si ne "HASH") {
+        last if ! defined $si;
+        if (ref $si eq "CODE") {
+            $si = $si->();
+        } else {
+            $si = $shared_info{$si};
+        }
+    }
+
+    # Some of the 'shared_target' values don't have any entried in
+    # %shared_info.  That's perfectly fine, AS LONG AS the build file
+    # template knows how to handle this.  That is currently the case for
+    # Windows and VMS.
+    if (defined $si) {
+        # Just as above, copy certain shared_* attributes to the corresponding
+        # dso_ attribute unless the latter is already defined
+        $si->{dso_cflags} = $si->{shared_cflag} unless defined $si->{dso_cflags};
+        $si->{dso_cxxflags} = $si->{shared_cxxflag} unless defined $si->{dso_cxxflags};
+        $si->{dso_lflags} = $si->{shared_ldflag} unless defined $si->{dso_lflags};
+        foreach (sort keys %$si) {
+            $target{$_} = defined $target{$_}
+                ? add($si->{$_})->($target{$_})
+                : $si->{$_};
+        }
+    }
+}
+
 my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
 $config{conf_files} = [ sort keys %conf_files ];
-%target = ( %{$table{DEFAULTS}}, %target );
 
 foreach my $feature (@{$target{disable}}) {
     if (exists $deprecated_disablables{$feature}) {
@@ -1153,8 +1202,11 @@ unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
 # This saves the build files from having to check
 if ($disabled{pic})
        {
-       $target{shared_cflag} = $target{shared_ldflag} =
-               $target{shared_rcflag} = "";
+       foreach (qw(shared_cflag shared_cxxflag shared_ldflag
+                   dso_cflags dso_cxxflags dso_lflags))
+               {
+               $target{$_} = "";
+               }
        }
 else
        {
@@ -1225,33 +1277,27 @@ unless ($disabled{asm}) {
     }
 }
 
-my %predefined;
-
-if ($^O ne "VMS") {
-    my $cc = "$config{cross_compile_prefix}$target{cc}";
-
-    # collect compiler pre-defines from gcc or gcc-alike...
-    open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
-    while (<PIPE>) {
-       m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
-       $predefined{$1} = $2 // "";
-    }
-    close(PIPE);
-
-    if (!$disabled{makedepend}) {
-       # We know that GNU C version 3 and up as well as all clang
-       # versions support dependency generation
-       if ($predefined{__GNUC__} >= 3) {
-           $config{makedepprog} = $cc;
-       } else {
-           $config{makedepprog} = which('makedepend');
-           $disabled{makedepend} = "unavailable" unless $config{makedepprog};
-       }
+my %predefined = compiler_predefined($target{cc});
+
+# Check for makedepend capabilities.
+if (!$disabled{makedepend}) {
+    if ($config{target} =~ /^(VC|vms)-/) {
+        # For VC- and vms- targets, there's nothing more to do here.  The
+        # functionality is hard coded in the corresponding build files for
+        # cl (Windows) and CC/DECC (VMS).
+    } elsif ($predefined{__GNUC__} >= 3) {
+        # We know that GNU C version 3 and up as well as all clang
+        # versions support dependency generation
+        $config{makedepprog} = "\$(CROSS_COMPILE)$target{cc}";
+    } else {
+        # In all other cases, we look for 'makedepend', and disable the
+        # capability if not found.
+        $config{makedepprog} = which('makedepend');
+        $disabled{makedepend} = "unavailable" unless $config{makedepprog};
     }
 }
 
 
-
 # Deal with bn_ops ###################################################
 
 $config{bn_ll}                 =0;
@@ -1836,14 +1882,27 @@ EOF
                 if (! -f $s) {
                     $s = cleanfile($buildd, $_, $blddir);
                 }
-                # We recognise C++, C and asm files
+
                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
+                    # We recognise C++, C and asm files
                     my $o = $_;
                     $o =~ s/\.[csS]$/.o/; # C and assembler
                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
                     $o = cleanfile($buildd, $o, $blddir);
                     $unified_info{shared_sources}->{$ddest}->{$o} = 1;
                     $unified_info{sources}->{$o}->{$s} = 1;
+                } elsif ($s =~ /\.rc$/) {
+                    # We also recognise resource files
+                    my $o = $_;
+                    $o =~ s/\.rc$/.res/; # Resource configuration
+                    my $o = cleanfile($buildd, $o, $blddir);
+                    $unified_info{shared_sources}->{$ddest}->{$o} = 1;
+                    $unified_info{sources}->{$o}->{$s} = 1;
+                } elsif ($s =~ /\.(def|map|opt)$/) {
+                    # We also recognise .def / .map / .opt files
+                    # We know they are generated files
+                    my $def = cleanfile($buildd, $s, $blddir);
+                    $unified_info{shared_sources}->{$ddest}->{$def} = 1;
                 } else {
                     die "unrecognised source file type for shared library: $s\n";
                 }
@@ -2295,25 +2354,38 @@ sub add {
     sub { _add($separator, @_, @x) };
 }
 
+sub read_eval_file {
+    my $fname = shift;
+    my $content;
+    my @result;
+
+    open F, "< $fname" or die "Can't open '$fname': $!\n";
+    {
+        undef local $/;
+        $content = <F>;
+    }
+    close F;
+    {
+        local $@;
+
+        @result = ( eval $content );
+        warn $@ if $@;
+    }
+    return wantarray ? @result : $result[0];
+}
+
 # configuration reader, evaluates the input file as a perl script and expects
 # it to fill %targets with target configurations.  Those are then added to
 # %table.
 sub read_config {
     my $fname = shift;
-    open(CONFFILE, "< $fname")
-       or die "Can't open configuration file '$fname'!\n";
-    my $x = $/;
-    undef $/;
-    my $content = <CONFFILE>;
-    $/ = $x;
-    close(CONFFILE);
-    my %targets = ();
+    my %targets;
+
     {
        # Protect certain tables from tampering
-       local %table = %::table;
+       local %table = ();
 
-       eval $content;
-       warn $@ if $@;
+       %targets = read_eval_file($fname);
     }
 
     # For each target, check that it's configured with a hash table.
@@ -2504,6 +2576,32 @@ sub run_dofile
     rename("$out.new", $out) || die "Can't rename $out.new, $!";
 }
 
+sub compiler_predefined {
+    state %predefined;
+    my $default_compiler = shift;
+
+    return () if $^O eq 'VMS';
+
+    die 'compiler_predefines called without a default compiler'
+        unless $default_compiler;
+
+    if (! $predefined{$default_compiler}) {
+        my $cc = "$config{cross_compile_prefix}$default_compiler";
+
+        $predefined{$default_compiler} = {};
+
+        # collect compiler pre-defines from gcc or gcc-alike...
+        open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
+        while (my $l = <PIPE>) {
+            $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
+            $predefined{$default_compiler}->{$1} = $2 // '';
+        }
+        close(PIPE);
+    }
+
+    return %{$predefined{$default_compiler}};
+}
+
 sub which
 {
     my ($name)=@_;
@@ -2529,8 +2627,12 @@ sub env
 {
     my $name = shift;
 
-    return $config{perlenv}->{$name} if exists $config{perlenv}->{$name};
-    $config{perlenv}->{$name} = $ENV{$name};
+    # Note that if $ENV{$name} doesn't exist or is undefined,
+    # $config{perlenv}->{$name} will be created with the value
+    # undef.  This is intentional.
+
+    $config{perlenv}->{$name} = $ENV{$name}
+        if ! exists $config{perlenv}->{$name};
     return $config{perlenv}->{$name};
 }