From 1190e53a1a6523ce6ab44b34f348e60d0dac3cbb Mon Sep 17 00:00:00 2001
From: Richard Levitte <levitte@openssl.org>
Date: Thu, 20 Jun 2024 14:30:16 +0200
Subject: [PATCH 1/3] Give util/mkinstallvars.pl more fine grained control over
 var dependencies

Essentially, we try to do what GNU does.  'prefix' is used to define the
defaults for 'exec_prefix' and 'libdir', and these are then used to define
further directory values.  util/mkinstallvars.pl is changed to reflect that
to the best of our ability.

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24687)

(cherry picked from commit 6e0fd246e7a6e51f92b2ef3520bfc4414b7773c0)
---
 exporters/build.info  |   2 +-
 util/mkinstallvars.pl | 133 ++++++++++++++++++++++++++----------------
 2 files changed, 85 insertions(+), 50 deletions(-)

diff --git a/exporters/build.info b/exporters/build.info
index 86acf2df94..9241dc9b0a 100644
--- a/exporters/build.info
+++ b/exporters/build.info
@@ -19,7 +19,7 @@ DEPEND[openssl.pc]=libcrypto.pc libssl.pc
 DEPEND[""]=openssl.pc
 
 GENERATE[../installdata.pm]=../util/mkinstallvars.pl \
-    "PREFIX=$(INSTALLTOP)" BINDIR=bin "LIBDIR=$(LIBDIR)" \
+    "PREFIX=$(INSTALLTOP)" BINDIR=bin "LIBDIR=$(LIBDIR)" "libdir=$(libdir)" \
     INCLUDEDIR=include APPLINKDIR=include/openssl \
     "ENGINESDIR=$(ENGINESDIR)" "MODULESDIR=$(MODULESDIR)" \
     "PKGCONFIGDIR=$(PKGCONFIGDIR)" "CMAKECONFIGDIR=$(CMAKECONFIGDIR)" \
diff --git a/util/mkinstallvars.pl b/util/mkinstallvars.pl
index 59a432d28c..5fadb708e1 100644
--- a/util/mkinstallvars.pl
+++ b/util/mkinstallvars.pl
@@ -11,13 +11,25 @@
 # The result is a Perl module creating the package OpenSSL::safe::installdata.
 
 use File::Spec;
+use List::Util qw(pairs);
 
 # These are expected to be set up as absolute directories
-my @absolutes = qw(PREFIX);
+my @absolutes = qw(PREFIX libdir);
 # These may be absolute directories, and if not, they are expected to be set up
-# as subdirectories to PREFIX
-my @subdirs = qw(BINDIR LIBDIR INCLUDEDIR APPLINKDIR ENGINESDIR MODULESDIR
-                 PKGCONFIGDIR CMAKECONFIGDIR);
+# as subdirectories to PREFIX or LIBDIR.  The order of the pairs is important,
+# since the LIBDIR subdirectories depend on the calculation of LIBDIR from
+# PREFIX.
+my @subdirs = pairs (PREFIX => [ qw(BINDIR LIBDIR INCLUDEDIR APPLINKDIR) ],
+                     LIBDIR => [ qw(ENGINESDIR MODULESDIR PKGCONFIGDIR
+                                    CMAKECONFIGDIR) ]);
+# For completeness, other expected variables
+my @others = qw(VERSION LDLIBS);
+
+my %all = ( );
+foreach (@absolutes) { $all{$_} = 1 }
+foreach (@subdirs) { foreach (@{$_->[1]}) { $all{$_} = 1 } }
+foreach (@others) { $all{$_} = 1 }
+print STDERR "DEBUG: all keys: ", join(", ", sort keys %all), "\n";
 
 my %keys = ();
 foreach (@ARGV) {
@@ -26,29 +38,47 @@ foreach (@ARGV) {
     $ENV{$k} = $v;
 }
 
-foreach my $k (sort keys %keys) {
-    my $v = $ENV{$k};
-    $v = File::Spec->rel2abs($v) if $v && grep { $k eq $_ } @absolutes;
-    $ENV{$k} = $v;
+# warn if there are missing values, and also if there are unexpected values
+foreach my $k (sort keys %all) {
+    warn "No value given for $k\n" unless $keys{$k};
 }
 foreach my $k (sort keys %keys) {
+    warn "Unknown variable $k\n" unless $all{$k};
+}
+
+# This shouldn't be needed, but just in case we get relative paths that
+# should be absolute, make sure they actually are.
+foreach my $k (@absolutes) {
     my $v = $ENV{$k} || '.';
+    print STDERR "DEBUG: $k = $v => ";
+    $v = File::Spec->rel2abs($v) if $v;
+    $ENV{$k} = $v;
+    print STDERR "$k = $ENV{$k}\n";
+}
 
-    # Absolute paths for the subdir variables are computed.  This provides
-    # the usual form of values for names that have become norm, known as GNU
-    # installation paths.
-    # For the benefit of those that need it, the subdirectories are preserved
-    # as they are, using the same variable names, suffixed with '_REL', if they
-    # are indeed subdirectories.
-    if (grep { $k eq $_ } @subdirs) {
+# Absolute paths for the subdir variables are computed.  This provides
+# the usual form of values for names that have become norm, known as GNU
+# installation paths.
+# For the benefit of those that need it, the subdirectories are preserved
+# as they are, using the same variable names, suffixed with '_REL_{var}',
+# if they are indeed subdirectories.  The '{var}' part of the name tells
+# which other variable value they are relative to.
+foreach my $pair (@subdirs) {
+    my ($var, $subdir_vars) = @$pair;
+    foreach my $k (@$subdir_vars) {
+        my $v = $ENV{$k} || '.';
+        print STDERR "DEBUG: $k = $v => ";
         if (File::Spec->file_name_is_absolute($v)) {
-            $ENV{"${k}_REL"} = File::Spec->abs2rel($v, $ENV{PREFIX});
+            my $kr = "${k}_REL_${var}";
+            $ENV{$kr} = File::Spec->abs2rel($v, $ENV{$var});
+            print STDERR "$kr = $ENV{$kr}\n";
         } else {
-            $ENV{"${k}_REL"} = $v;
-            $v = File::Spec->rel2abs($v, $ENV{PREFIX});
+            my $kr = "${k}_REL_${var}";
+            $ENV{$kr} = $v;
+            $ENV{$k} = File::Spec->rel2abs($v, $ENV{$var});
+            print STDERR "$k = $ENV{$k} ,  $kr = $v\n";
         }
     }
-    $ENV{$k} = $v;
 }
 
 print <<_____;
@@ -58,36 +88,41 @@ use strict;
 use warnings;
 use Exporter;
 our \@ISA = qw(Exporter);
-our \@EXPORT = qw(\$PREFIX
-                  \$BINDIR \$BINDIR_REL
-                  \$LIBDIR \$LIBDIR_REL
-                  \$INCLUDEDIR \$INCLUDEDIR_REL
-                  \$APPLINKDIR \$APPLINKDIR_REL
-                  \$ENGINESDIR \$ENGINESDIR_REL
-                  \$MODULESDIR \$MODULESDIR_REL
-                  \$PKGCONFIGDIR \$PKGCONFIGDIR_REL
-                  \$CMAKECONFIGDIR \$CMAKECONFIGDIR_REL
-                  \$VERSION \@LDLIBS);
-
-our \$PREFIX             = '$ENV{PREFIX}';
-our \$BINDIR             = '$ENV{BINDIR}';
-our \$BINDIR_REL         = '$ENV{BINDIR_REL}';
-our \$LIBDIR             = '$ENV{LIBDIR}';
-our \$LIBDIR_REL         = '$ENV{LIBDIR_REL}';
-our \$INCLUDEDIR         = '$ENV{INCLUDEDIR}';
-our \$INCLUDEDIR_REL     = '$ENV{INCLUDEDIR_REL}';
-our \$APPLINKDIR         = '$ENV{APPLINKDIR}';
-our \$APPLINKDIR_REL     = '$ENV{APPLINKDIR_REL}';
-our \$ENGINESDIR         = '$ENV{ENGINESDIR}';
-our \$ENGINESDIR_REL     = '$ENV{ENGINESDIR_REL}';
-our \$MODULESDIR         = '$ENV{MODULESDIR}';
-our \$MODULESDIR_REL     = '$ENV{MODULESDIR_REL}';
-our \$PKGCONFIGDIR       = '$ENV{PKGCONFIGDIR}';
-our \$PKGCONFIGDIR_REL   = '$ENV{PKGCONFIGDIR_REL}';
-our \$CMAKECONFIGDIR     = '$ENV{CMAKECONFIGDIR}';
-our \$CMAKECONFIGDIR_REL = '$ENV{CMAKECONFIGDIR_REL}';
-our \$VERSION            = '$ENV{VERSION}';
-our \@LDLIBS             =
+our \@EXPORT = qw(
+_____
+
+foreach my $k (@absolutes) {
+    print "    \$$k\n";
+}
+foreach my $pair (@subdirs) {
+    my ($var, $subdir_vars) = @$pair;
+    foreach my $k (@$subdir_vars) {
+        my $k2 = "${k}_REL_${var}";
+        print "    \$$k \$$k2\n";
+    }
+}
+
+print <<_____;
+    \$VERSION \@LDLIBS
+);
+
+_____
+
+foreach my $k (@absolutes) {
+    print "our \$$k" . ' ' x (27 - length($k)) . "= '$ENV{$k}';\n";
+}
+foreach my $pair (@subdirs) {
+    my ($var, $subdir_vars) = @$pair;
+    foreach my $k (@$subdir_vars) {
+        my $k2 = "${k}_REL_${var}";
+        print "our \$$k" . ' ' x (27 - length($k)) . "= '$ENV{$k}';\n";
+        print "our \$$k2" . ' ' x (27 - length($k2)) . "= '$ENV{$k2}';\n";
+    }
+}
+
+print <<_____;
+our \$VERSION                    = '$ENV{VERSION}';
+our \@LDLIBS                     =
     # Unix and Windows use space separation, VMS uses comma separation
     split(/ +| *, */, '$ENV{LDLIBS}');
 
