Skip to content

Commit 05b2758

Browse files
committed
Add support for OpenSSL 1.1.0 and newer versions in MSVC scripts
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
1 parent ddfb1b2 commit 05b2758

File tree

1 file changed

+104
-12
lines changed

1 file changed

+104
-12
lines changed

src/tools/msvc/Solution.pm

Lines changed: 104 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,34 @@ sub copyFile
122122
close(O);
123123
}
124124

125+
# Fetch version of OpenSSL based on a parsing of the command shipped with
126+
# the installer this build is linking to. This returns as result an array
127+
# made of the three first digits of the OpenSSL version, which is enough
128+
# to decide which options to apply depending on the version of OpenSSL
129+
# linking with.
130+
sub GetOpenSSLVersion
131+
{
132+
my $self = shift;
133+
134+
# Attempt to get OpenSSL version and location. This assumes that
135+
# openssl.exe is in the specified directory.
136+
my $opensslcmd =
137+
$self->{options}->{openssl} . "\\bin\\openssl.exe version 2>&1";
138+
my $sslout = `$opensslcmd`;
139+
140+
$? >> 8 == 0
141+
or croak
142+
"Unable to determine OpenSSL version: The openssl.exe command wasn't found.";
143+
144+
if ($sslout =~ /(\d+)\.(\d+)\.(\d+)(\D)/m)
145+
{
146+
return ($1, $2, $3);
147+
}
148+
149+
croak
150+
"Unable to determine OpenSSL version: The openssl.exe version could not be determined.";
151+
}
152+
125153
sub GenerateFiles
126154
{
127155
my $self = shift;
@@ -181,7 +209,6 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
181209
if ($self->{options}->{integer_datetimes});
182210
print O "#define USE_LDAP 1\n" if ($self->{options}->{ldap});
183211
print O "#define HAVE_LIBZ 1\n" if ($self->{options}->{zlib});
184-
print O "#define USE_SSL 1\n" if ($self->{options}->{openssl});
185212
print O "#define ENABLE_NLS 1\n" if ($self->{options}->{nls});
186213

187214
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
232259
{
233260
print O "#define ENABLE_GSS 1\n";
234261
}
262+
if ($self->{options}->{openssl})
263+
{
264+
print O "#define USE_SSL 1\n";
265+
266+
my ($digit1, $digit2, $digit3) = $self->GetOpenSSLVersion();
267+
268+
# More symbols are needed with OpenSSL 1.1.0 and above.
269+
if ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0')
270+
{
271+
print O "#define HAVE_ASN1_STRING_GET0_DATA 1\n";
272+
print O "#define HAVE_BIO_GET_DATA 1\n";
273+
print O "#define HAVE_BIO_METH_NEW 1\n";
274+
print O "#define HAVE_OPENSSL_INIT_SSL 1\n";
275+
print O "#define HAVE_RAND_OPENSSL 1\n";
276+
}
277+
}
235278
if (my $port = $self->{options}->{"--with-pgport"})
236279
{
237280
print O "#undef DEF_PGPORT\n";
@@ -502,21 +545,70 @@ sub AddProject
502545
if ($self->{options}->{openssl})
503546
{
504547
$proj->AddIncludeDir($self->{options}->{openssl} . '\include');
505-
if (-e "$self->{options}->{openssl}/lib/VC/ssleay32MD.lib")
548+
my ($digit1, $digit2, $digit3) = $self->GetOpenSSLVersion();
549+
550+
# Starting at version 1.1.0 the OpenSSL installers have
551+
# changed their library names from:
552+
# - libeay to libcrypto
553+
# - ssleay to libssl
554+
if ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0')
506555
{
507-
$proj->AddLibrary(
508-
$self->{options}->{openssl} . '\lib\VC\ssleay32.lib', 1);
509-
$proj->AddLibrary(
510-
$self->{options}->{openssl} . '\lib\VC\libeay32.lib', 1);
556+
my $dbgsuffix;
557+
my $libsslpath;
558+
my $libcryptopath;
559+
560+
# The format name of the libraries is slightly
561+
# different between the Win32 and Win64 platform, so
562+
# adapt.
563+
if (-e "$self->{options}->{openssl}/lib/VC/sslcrypto32MD.lib")
564+
{
565+
# Win32 here, with a debugging library set.
566+
$dbgsuffix = 1;
567+
$libsslpath = '\lib\VC\libssl32.lib';
568+
$libcryptopath = '\lib\VC\libcrypto32.lib';
569+
}
570+
elsif (-e "$self->{options}->{openssl}/lib/VC/sslcrypto64MD.lib")
571+
{
572+
# Win64 here, with a debugging library set.
573+
$dbgsuffix = 1;
574+
$libsslpath = '\lib\VC\libssl64.lib';
575+
$libcryptopath = '\lib\VC\libcrypto64.lib';
576+
}
577+
else
578+
{
579+
# On both Win32 and Win64 the same library
580+
# names are used without a debugging context.
581+
$dbgsuffix = 0;
582+
$libsslpath = '\lib\libssl.lib';
583+
$libcryptopath = '\lib\libcrypto.lib';
584+
}
585+
586+
$proj->AddLibrary($self->{options}->{openssl} . $libsslpath,
587+
$dbgsuffix);
588+
$proj->AddLibrary($self->{options}->{openssl} . $libcryptopath,
589+
$dbgsuffix);
511590
}
512591
else
513592
{
514-
# We don't expect the config-specific library to be here,
515-
# so don't ask for it in last parameter
516-
$proj->AddLibrary(
517-
$self->{options}->{openssl} . '\lib\ssleay32.lib', 0);
518-
$proj->AddLibrary(
519-
$self->{options}->{openssl} . '\lib\libeay32.lib', 0);
593+
# Choose which set of libraries to use depending on if
594+
# debugging libraries are in place in the installer.
595+
if (-e "$self->{options}->{openssl}/lib/VC/ssleay32MD.lib")
596+
{
597+
$proj->AddLibrary(
598+
$self->{options}->{openssl} . '\lib\VC\ssleay32.lib', 1);
599+
$proj->AddLibrary(
600+
$self->{options}->{openssl} . '\lib\VC\libeay32.lib', 1);
601+
}
602+
else
603+
{
604+
# We don't expect the config-specific library
605+
# to be here, so don't ask for it in last
606+
# parameter.
607+
$proj->AddLibrary(
608+
$self->{options}->{openssl} . '\lib\ssleay32.lib', 0);
609+
$proj->AddLibrary(
610+
$self->{options}->{openssl} . '\lib\libeay32.lib', 0);
611+
}
520612
}
521613
}
522614
if ($self->{options}->{nls})

0 commit comments

Comments
 (0)