https://github.com/openssl/openssl/pull/24687
https://bugs.gentoo.org/936576

https://github.com/openssl/openssl/commit/aa099dba7c80c723cf4babf5adc0c801f1c28363
https://github.com/openssl/openssl/commit/1c437b5704c9ee5f667bc2b11e5fdf176dfb714f

From aa099dba7c80c723cf4babf5adc0c801f1c28363 Mon Sep 17 00:00:00 2001
From: Richard Levitte <levitte@openssl.org>
Date: Thu, 20 Jun 2024 14:30:16 +0200
Subject: [PATCH] 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 86acf2df9467c..9241dc9b0a658 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 59a432d28c601..5fadb708e1b77 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 @@
     $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 @@ package OpenSSL::safe::installdata;
 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}');
 

From 1c437b5704c9ee5f667bc2b11e5fdf176dfb714f Mon Sep 17 00:00:00 2001
From: Richard Levitte <levitte@openssl.org>
Date: Thu, 20 Jun 2024 14:33:15 +0200
Subject: [PATCH] Adapt all the exporter files to the new vars from
 util/mkinstallvars.pl

With this, the pkg-config files take better advantage of relative directory
values.

Fixes #24298

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 30dc37d798a0428fd477d3763086e7e97b3d596f)
---
 exporters/cmake/OpenSSLConfig.cmake.in |  7 ++++---
 exporters/pkg-config/libcrypto.pc.in   | 12 ++++++++----
 exporters/pkg-config/libssl.pc.in      |  8 ++++++--
 exporters/pkg-config/openssl.pc.in     |  8 ++++++--
 4 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/exporters/cmake/OpenSSLConfig.cmake.in b/exporters/cmake/OpenSSLConfig.cmake.in
index 2d2321931de1d..06f796158b2fa 100644
--- a/exporters/cmake/OpenSSLConfig.cmake.in
+++ b/exporters/cmake/OpenSSLConfig.cmake.in
@@ -89,9 +89,10 @@ unset(_ossl_undefined_targets)
 # Set up the import path, so all other import paths are made relative this file
 get_filename_component(_ossl_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
 {-
-  # For each component in $OpenSSL::safe::installdata::CMAKECONFIGDIR_REL, have CMake
-  # out the parent directory.
-  my $d = unixify($OpenSSL::safe::installdata::CMAKECONFIGDIR_REL);
+  # For each component in $OpenSSL::safe::installdata::CMAKECONFIGDIR relative to
+  # $OpenSSL::safe::installdata::PREFIX, have CMake figure out the parent directory.
+  my $d = join('/', unixify($OpenSSL::safe::installdata::LIBDIR_REL_PREFIX),
+                    unixify($OpenSSL::safe::installdata::CMAKECONFIGDIR_REL_LIBDIR));
   $OUT = '';
   $OUT .= 'get_filename_component(_ossl_prefix "${_ossl_prefix}" PATH)' . "\n"
       foreach (split '/', $d);
diff --git a/exporters/pkg-config/libcrypto.pc.in b/exporters/pkg-config/libcrypto.pc.in
index 14ed339f3c3a0..fbc8ea4c79b06 100644
--- a/exporters/pkg-config/libcrypto.pc.in
+++ b/exporters/pkg-config/libcrypto.pc.in
@@ -1,7 +1,11 @@
-libdir={- $OpenSSL::safe::installdata::LIBDIR -}
-includedir={- $OpenSSL::safe::installdata::INCLUDEDIR -}
-enginesdir={- $OpenSSL::safe::installdata::ENGINESDIR -}
-modulesdir={- $OpenSSL::safe::installdata::MODULESDIR -}
+prefix={- $OpenSSL::safe::installdata::PREFIX -}
+exec_prefix=${prefix}
+libdir={- $OpenSSL::safe::installdata::LIBDIR_REL_PREFIX
+          ? '${exec_prefix}/' . $OpenSSL::safe::installdata::LIBDIR_REL_PREFIX
+          : $OpenSSL::safe::installdata::libdir -}
+includedir=${prefix}/{- $OpenSSL::safe::installdata::INCLUDEDIR_REL_PREFIX -}
+enginesdir=${libdir}/{- $OpenSSL::safe::installdata::ENGINESDIR_REL_LIBDIR -}
+modulesdir=${libdir}/{- $OpenSSL::safe::installdata::MODULESDIR_REL_LIBDIR -}
 
 Name: OpenSSL-libcrypto
 Description: OpenSSL cryptography library
diff --git a/exporters/pkg-config/libssl.pc.in b/exporters/pkg-config/libssl.pc.in
index a7828b3cc6a49..963538807bb2b 100644
--- a/exporters/pkg-config/libssl.pc.in
+++ b/exporters/pkg-config/libssl.pc.in
@@ -1,5 +1,9 @@
-libdir={- $OpenSSL::safe::installdata::LIBDIR -}
-includedir={- $OpenSSL::safe::installdata::INCLUDEDIR -}
+prefix={- $OpenSSL::safe::installdata::PREFIX -}
+exec_prefix=${prefix}
+libdir={- $OpenSSL::safe::installdata::LIBDIR_REL_PREFIX
+          ? '${exec_prefix}/' . $OpenSSL::safe::installdata::LIBDIR_REL_PREFIX
+          : $OpenSSL::safe::installdata::libdir -}
+includedir=${prefix}/{- $OpenSSL::safe::installdata::INCLUDEDIR_REL_PREFIX -}
 
 Name: OpenSSL-libssl
 Description: Secure Sockets Layer and cryptography libraries
diff --git a/exporters/pkg-config/openssl.pc.in b/exporters/pkg-config/openssl.pc.in
index dbb77aa39add2..225bef9e2384d 100644
--- a/exporters/pkg-config/openssl.pc.in
+++ b/exporters/pkg-config/openssl.pc.in
@@ -1,5 +1,9 @@
-libdir={- $OpenSSL::safe::installdata::LIBDIR -}
-includedir={- $OpenSSL::safe::installdata::INCLUDEDIR -}
+prefix={- $OpenSSL::safe::installdata::PREFIX -}
+exec_prefix=${prefix}
+libdir={- $OpenSSL::safe::installdata::LIBDIR_REL_PREFIX
+          ? '${exec_prefix}/' . $OpenSSL::safe::installdata::LIBDIR_REL_PREFIX
+          : $OpenSSL::safe::installdata::libdir -}
+includedir=${prefix}/{- $OpenSSL::safe::installdata::INCLUDEDIR_REL_PREFIX -}
 
 Name: OpenSSL
 Description: Secure Sockets Layer and cryptography libraries and tools
