]> granicus.if.org Git - postgresql/commitdiff
Add support for OpenSSL 1.1.0 and newer versions in MSVC scripts
authorMichael Paquier <michael@paquier.xyz>
Wed, 26 Jun 2019 14:06:14 +0000 (23:06 +0900)
committerMichael Paquier <michael@paquier.xyz>
Wed, 26 Jun 2019 14:06:14 +0000 (23:06 +0900)
Up to now, the MSVC build scripts are able to support only one fixed
version of OpenSSL, and they lacked logic to detect the version of
OpenSSL a given compilation of Postgres is linking to (currently 1.0.2,
the latest LTS of upstream which will be EOL'd at the end of 2019).

This commit adds more logic to detect the version of OpenSSL used by a
build and makes use of it to add support for compilation with OpenSSL
1.1.0 which requires a new set of compilation flags to work properly.

The supported OpenSSL installers have changed their library layer with
various library renames with the upgrade to 1.1.0, making the logic a
bit more complicated.  The scripts are now able to adapt to the new
world order.

Reported-by: Sergey Pashkov
Author: Juan José Santamaría Flecha, Michael Paquier
Reviewed-by: Álvaro Herrera
Discussion: https://postgr.es/m/15789-8fc75dea3c5a17c8@postgresql.org
Backpatch-through: 9.4

src/tools/msvc/Solution.pm

index d1a791c5ad97019b2f7e99960a4ad9e64de0b7a9..6e6e6de4dd6234b4f617630fa8177b68d1f229e8 100644 (file)
@@ -122,6 +122,34 @@ sub copyFile
        close(O);
 }
 
+# Fetch version of OpenSSL based on a parsing of the command shipped with
+# the installer this build is linking to.  This returns as result an array
+# made of the three first digits of the OpenSSL version, which is enough
+# to decide which options to apply depending on the version of OpenSSL
+# linking with.
+sub GetOpenSSLVersion
+{
+       my $self = shift;
+
+       # Attempt to get OpenSSL version and location.  This assumes that
+       # openssl.exe is in the specified directory.
+       my $opensslcmd =
+         $self->{options}->{openssl} . "\\bin\\openssl.exe version 2>&1";
+       my $sslout = `$opensslcmd`;
+
+       $? >> 8 == 0
+         or croak
+         "Unable to determine OpenSSL version: The openssl.exe command wasn't found.";
+
+       if ($sslout =~ /(\d+)\.(\d+)\.(\d+)(\D)/m)
+       {
+               return ($1, $2, $3);
+       }
+
+       croak
+         "Unable to determine OpenSSL version: The openssl.exe version could not be determined.";
+}
+
 sub GenerateFiles
 {
        my $self = shift;
@@ -181,7 +209,6 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
                  if ($self->{options}->{integer_datetimes});
                print O "#define USE_LDAP 1\n"   if ($self->{options}->{ldap});
                print O "#define HAVE_LIBZ 1\n"  if ($self->{options}->{zlib});
-               print O "#define USE_SSL 1\n"    if ($self->{options}->{openssl});
                print O "#define ENABLE_NLS 1\n" if ($self->{options}->{nls});
 
                print O "#define BLCKSZ ", 1024 * $self->{options}->{blocksize}, "\n";
@@ -232,6 +259,22 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
                {
                        print O "#define ENABLE_GSS 1\n";
                }
+               if ($self->{options}->{openssl})
+               {
+                       print O "#define USE_SSL 1\n";
+
+                       my ($digit1, $digit2, $digit3) = $self->GetOpenSSLVersion();
+
+                       # More symbols are needed with OpenSSL 1.1.0 and above.
+                       if ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0')
+                       {
+                               print O "#define HAVE_ASN1_STRING_GET0_DATA 1\n";
+                               print O "#define HAVE_BIO_GET_DATA 1\n";
+                               print O "#define HAVE_BIO_METH_NEW 1\n";
+                               print O "#define HAVE_OPENSSL_INIT_SSL 1\n";
+                               print O "#define HAVE_RAND_OPENSSL 1\n";
+                       }
+               }
                if (my $port = $self->{options}->{"--with-pgport"})
                {
                        print O "#undef DEF_PGPORT\n";
@@ -502,21 +545,70 @@ sub AddProject
        if ($self->{options}->{openssl})
        {
                $proj->AddIncludeDir($self->{options}->{openssl} . '\include');
-               if (-e "$self->{options}->{openssl}/lib/VC/ssleay32MD.lib")
+               my ($digit1, $digit2, $digit3) = $self->GetOpenSSLVersion();
+
+               # Starting at version 1.1.0 the OpenSSL installers have
+               # changed their library names from:
+               # - libeay to libcrypto
+               # - ssleay to libssl
+               if ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0')
                {
-                       $proj->AddLibrary(
-                               $self->{options}->{openssl} . '\lib\VC\ssleay32.lib', 1);
-                       $proj->AddLibrary(
-                               $self->{options}->{openssl} . '\lib\VC\libeay32.lib', 1);
+                       my $dbgsuffix;
+                       my $libsslpath;
+                       my $libcryptopath;
+
+                       # The format name of the libraries is slightly
+                       # different between the Win32 and Win64 platform, so
+                       # adapt.
+                       if (-e "$self->{options}->{openssl}/lib/VC/sslcrypto32MD.lib")
+                       {
+                               # Win32 here, with a debugging library set.
+                               $dbgsuffix     = 1;
+                               $libsslpath    = '\lib\VC\libssl32.lib';
+                               $libcryptopath = '\lib\VC\libcrypto32.lib';
+                       }
+                       elsif (-e "$self->{options}->{openssl}/lib/VC/sslcrypto64MD.lib")
+                       {
+                               # Win64 here, with a debugging library set.
+                               $dbgsuffix     = 1;
+                               $libsslpath    = '\lib\VC\libssl64.lib';
+                               $libcryptopath = '\lib\VC\libcrypto64.lib';
+                       }
+                       else
+                       {
+                               # On both Win32 and Win64 the same library
+                               # names are used without a debugging context.
+                               $dbgsuffix     = 0;
+                               $libsslpath    = '\lib\libssl.lib';
+                               $libcryptopath = '\lib\libcrypto.lib';
+                       }
+
+                       $proj->AddLibrary($self->{options}->{openssl} . $libsslpath,
+                               $dbgsuffix);
+                       $proj->AddLibrary($self->{options}->{openssl} . $libcryptopath,
+                               $dbgsuffix);
                }
                else
                {
-                       # We don't expect the config-specific library to be here,
-                       # so don't ask for it in last parameter
-                       $proj->AddLibrary(
-                               $self->{options}->{openssl} . '\lib\ssleay32.lib', 0);
-                       $proj->AddLibrary(
-                               $self->{options}->{openssl} . '\lib\libeay32.lib', 0);
+                       # Choose which set of libraries to use depending on if
+                       # debugging libraries are in place in the installer.
+                       if (-e "$self->{options}->{openssl}/lib/VC/ssleay32MD.lib")
+                       {
+                               $proj->AddLibrary(
+                                       $self->{options}->{openssl} . '\lib\VC\ssleay32.lib', 1);
+                               $proj->AddLibrary(
+                                       $self->{options}->{openssl} . '\lib\VC\libeay32.lib', 1);
+                       }
+                       else
+                       {
+                               # We don't expect the config-specific library
+                               # to be here, so don't ask for it in last
+                               # parameter.
+                               $proj->AddLibrary(
+                                       $self->{options}->{openssl} . '\lib\ssleay32.lib', 0);
+                               $proj->AddLibrary(
+                                       $self->{options}->{openssl} . '\lib\libeay32.lib', 0);
+                       }
                }
        }
        if ($self->{options}->{nls})