mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-11-27 07:21:09 +08:00
MSVC: Test whether 32-bit Perl needs -D_USE_32BIT_TIME_T.
Commits5a5c2feca3
andb5178c5d08
introduced support for modern MSVC-built, 32-bit Perl, but they broke use of MinGW-built, 32-bit Perl distributions like Strawberry Perl and modern ActivePerl. Perl has no robust means to report whether it expects a -D_USE_32BIT_TIME_T ABI, so test this. Back-patch to 9.3 (all supported versions). The chief alternative was a heuristic of adding -D_USE_32BIT_TIME_T when $Config{gccversion} is nonempty. That banks on every gcc-built Perl using the same ABI. gcc could change its default ABI the way MSVC once did, and one could build Perl with gcc and the non-default ABI. The GNU make build system could benefit from a similar test, without which it does not support MSVC-built Perl. For now, just add a comment. Most users taking the special step of building Perl with MSVC probably build PostgreSQL with MSVC. Discussion: https://postgr.es/m/20171130041441.GA3161526@rfd.leadboat.com
This commit is contained in:
parent
85a83a3cc6
commit
1c1a572d05
@ -51,19 +51,23 @@ AC_DEFUN([PGAC_CHECK_PERL_CONFIGS],
|
|||||||
|
|
||||||
# PGAC_CHECK_PERL_EMBED_CCFLAGS
|
# PGAC_CHECK_PERL_EMBED_CCFLAGS
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# We selectively extract stuff from $Config{ccflags}. We don't really need
|
# We selectively extract stuff from $Config{ccflags}. For debugging purposes,
|
||||||
# anything except -D switches, and other sorts of compiler switches can
|
# let's have the configure output report the raw ccflags value as well as the
|
||||||
# actively break things if Perl was compiled with a different compiler.
|
# set of flags we chose to adopt. We don't really need anything except -D
|
||||||
# Moreover, although Perl likes to put stuff like -D_LARGEFILE_SOURCE and
|
# switches, and other sorts of compiler switches can actively break things if
|
||||||
# -D_FILE_OFFSET_BITS=64 here, it would be fatal to try to compile PL/Perl
|
# Perl was compiled with a different compiler. Moreover, although Perl likes
|
||||||
# to a different libc ABI than core Postgres uses. The available information
|
# to put stuff like -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 here, it
|
||||||
# says that all the symbols that affect Perl's own ABI begin with letters,
|
# would be fatal to try to compile PL/Perl to a different libc ABI than core
|
||||||
# so it should be sufficient to adopt -D switches for symbols not beginning
|
# Postgres uses. The available information says that most symbols that affect
|
||||||
# with underscore. An exception is that we need to let through
|
# Perl's own ABI begin with letters, so it's almost sufficient to adopt -D
|
||||||
# -D_USE_32BIT_TIME_T if it's present. (We probably could restrict that to
|
# switches for symbols not beginning with underscore. Some exceptions are the
|
||||||
# only get through on Windows, but for the moment we let it through always.)
|
# Windows-specific -D_USE_32BIT_TIME_T and -D__MINGW_USE_VC2005_COMPAT; see
|
||||||
# For debugging purposes, let's have the configure output report the raw
|
# Mkvcbuild.pm for details. We absorb the former when Perl reports it. Perl
|
||||||
# ccflags value as well as the set of flags we chose to adopt.
|
# never reports the latter, and we don't attempt to deduce when it's needed.
|
||||||
|
# Consequently, we don't support using MinGW to link to MSVC-built Perl. As
|
||||||
|
# of 2017, all supported ActivePerl and Strawberry Perl are MinGW-built. If
|
||||||
|
# that changes or an MSVC-built Perl distribution becomes prominent, we can
|
||||||
|
# revisit this limitation.
|
||||||
AC_DEFUN([PGAC_CHECK_PERL_EMBED_CCFLAGS],
|
AC_DEFUN([PGAC_CHECK_PERL_EMBED_CCFLAGS],
|
||||||
[AC_REQUIRE([PGAC_PATH_PERL])
|
[AC_REQUIRE([PGAC_PATH_PERL])
|
||||||
AC_MSG_CHECKING([for CFLAGS recommended by Perl])
|
AC_MSG_CHECKING([for CFLAGS recommended by Perl])
|
||||||
|
@ -27,6 +27,7 @@ my $libpgport;
|
|||||||
my $libpgcommon;
|
my $libpgcommon;
|
||||||
my $postgres;
|
my $postgres;
|
||||||
my $libpq;
|
my $libpq;
|
||||||
|
my @unlink_on_exit;
|
||||||
|
|
||||||
# Set of variables for modules in contrib/ and src/test/modules/
|
# Set of variables for modules in contrib/ and src/test/modules/
|
||||||
my $contrib_defines = { 'refint' => 'REFINT_VERBOSE' };
|
my $contrib_defines = { 'refint' => 'REFINT_VERBOSE' };
|
||||||
@ -508,34 +509,154 @@ sub mkvcbuild
|
|||||||
my $plperl =
|
my $plperl =
|
||||||
$solution->AddProject('plperl', 'dll', 'PLs', 'src/pl/plperl');
|
$solution->AddProject('plperl', 'dll', 'PLs', 'src/pl/plperl');
|
||||||
$plperl->AddIncludeDir($solution->{options}->{perl} . '/lib/CORE');
|
$plperl->AddIncludeDir($solution->{options}->{perl} . '/lib/CORE');
|
||||||
|
$plperl->AddReference($postgres);
|
||||||
|
|
||||||
|
my $perl_path = $solution->{options}->{perl} . '\lib\CORE\*perl*';
|
||||||
|
|
||||||
|
# ActivePerl 5.16 provided perl516.lib; 5.18 provided libperl518.a
|
||||||
|
my @perl_libs =
|
||||||
|
grep { /perl\d+\.lib$|libperl\d+\.a$/ } glob($perl_path);
|
||||||
|
if (@perl_libs == 1)
|
||||||
|
{
|
||||||
|
$plperl->AddLibrary($perl_libs[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
die
|
||||||
|
"could not identify perl library version matching pattern $perl_path\n";
|
||||||
|
}
|
||||||
|
|
||||||
# Add defines from Perl's ccflags; see PGAC_CHECK_PERL_EMBED_CCFLAGS
|
# Add defines from Perl's ccflags; see PGAC_CHECK_PERL_EMBED_CCFLAGS
|
||||||
my @perl_embed_ccflags;
|
my @perl_embed_ccflags;
|
||||||
foreach my $f (split(" ", $Config{ccflags}))
|
foreach my $f (split(" ", $Config{ccflags}))
|
||||||
{
|
{
|
||||||
if ( $f =~ /^-D[^_]/
|
if ($f =~ /^-D[^_]/)
|
||||||
|| $f =~ /^-D_USE_32BIT_TIME_T/)
|
|
||||||
{
|
{
|
||||||
$f =~ s/\-D//;
|
$f =~ s/\-D//;
|
||||||
push(@perl_embed_ccflags, $f);
|
push(@perl_embed_ccflags, $f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Perl versions before 5.13.4 don't provide -D_USE_32BIT_TIME_T
|
# hack to prevent duplicate definitions of uid_t/gid_t
|
||||||
# regardless of how they were built. On 32-bit Windows, assume
|
|
||||||
# such a version was built with a pre-MSVC-2005 compiler, and
|
|
||||||
# define the symbol anyway, so that we are compatible if we're
|
|
||||||
# being built with a later MSVC version.
|
|
||||||
push(@perl_embed_ccflags, '_USE_32BIT_TIME_T')
|
|
||||||
if $solution->{platform} eq 'Win32'
|
|
||||||
&& $Config{PERL_REVISION} == 5
|
|
||||||
&& ($Config{PERL_VERSION} < 13
|
|
||||||
|| ( $Config{PERL_VERSION} == 13
|
|
||||||
&& $Config{PERL_SUBVERSION} < 4));
|
|
||||||
|
|
||||||
# Also, a hack to prevent duplicate definitions of uid_t/gid_t
|
|
||||||
push(@perl_embed_ccflags, 'PLPERL_HAVE_UID_GID');
|
push(@perl_embed_ccflags, 'PLPERL_HAVE_UID_GID');
|
||||||
|
|
||||||
|
# Windows offers several 32-bit ABIs. Perl is sensitive to
|
||||||
|
# sizeof(time_t), one of the ABI dimensions. To get 32-bit time_t,
|
||||||
|
# use "cl -D_USE_32BIT_TIME_T" or plain "gcc". For 64-bit time_t, use
|
||||||
|
# "gcc -D__MINGW_USE_VC2005_COMPAT" or plain "cl". Before MSVC 2005,
|
||||||
|
# plain "cl" chose 32-bit time_t. PostgreSQL doesn't support building
|
||||||
|
# with pre-MSVC-2005 compilers, but it does support linking to Perl
|
||||||
|
# built with such a compiler. MSVC-built Perl 5.13.4 and later report
|
||||||
|
# -D_USE_32BIT_TIME_T in $Config{ccflags} if applicable, but
|
||||||
|
# MinGW-built Perl never reports -D_USE_32BIT_TIME_T despite typically
|
||||||
|
# needing it. Ignore the $Config{ccflags} opinion about
|
||||||
|
# -D_USE_32BIT_TIME_T, and use a runtime test to deduce the ABI Perl
|
||||||
|
# expects. Specifically, test use of PL_modglobal, which maps to a
|
||||||
|
# PerlInterpreter field whose position depends on sizeof(time_t).
|
||||||
|
if ($solution->{platform} eq 'Win32')
|
||||||
|
{
|
||||||
|
my $source_file = 'conftest.c';
|
||||||
|
my $obj = 'conftest.obj';
|
||||||
|
my $exe = 'conftest.exe';
|
||||||
|
my @conftest = ($source_file, $obj, $exe);
|
||||||
|
push @unlink_on_exit, @conftest;
|
||||||
|
unlink $source_file;
|
||||||
|
open my $o, '>', $source_file
|
||||||
|
|| croak "Could not write to $source_file";
|
||||||
|
print $o '
|
||||||
|
/* compare to plperl.h */
|
||||||
|
#define __inline__ __inline
|
||||||
|
#define PERL_NO_GET_CONTEXT
|
||||||
|
#include <EXTERN.h>
|
||||||
|
#include <perl.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int dummy_argc = 1;
|
||||||
|
char *dummy_argv[1] = {""};
|
||||||
|
char *dummy_env[1] = {NULL};
|
||||||
|
static PerlInterpreter *interp;
|
||||||
|
|
||||||
|
PERL_SYS_INIT3(&dummy_argc, (char ***) &dummy_argv,
|
||||||
|
(char ***) &dummy_env);
|
||||||
|
interp = perl_alloc();
|
||||||
|
perl_construct(interp);
|
||||||
|
{
|
||||||
|
dTHX;
|
||||||
|
const char key[] = "dummy";
|
||||||
|
|
||||||
|
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
|
||||||
|
hv_store(PL_modglobal, key, sizeof(key) - 1, newSViv(1), 0);
|
||||||
|
return hv_fetch(PL_modglobal, key, sizeof(key) - 1, 0) == NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
';
|
||||||
|
close $o;
|
||||||
|
|
||||||
|
# Build $source_file with a given #define, and return a true value
|
||||||
|
# if a run of the resulting binary exits successfully.
|
||||||
|
my $try_define = sub {
|
||||||
|
my $define = shift;
|
||||||
|
|
||||||
|
unlink $obj, $exe;
|
||||||
|
my @cmd = (
|
||||||
|
'cl',
|
||||||
|
'-I' . $solution->{options}->{perl} . '/lib/CORE',
|
||||||
|
(map { "-D$_" } @perl_embed_ccflags, $define || ()),
|
||||||
|
$source_file,
|
||||||
|
'/link',
|
||||||
|
$perl_libs[0]);
|
||||||
|
my $compile_output = `@cmd 2>&1`;
|
||||||
|
-f $exe || die "Failed to build Perl test:\n$compile_output";
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
# Some builds exhibit runtime failure through Perl warning
|
||||||
|
# 'Can't spawn "conftest.exe"'; supress that.
|
||||||
|
no warnings;
|
||||||
|
|
||||||
|
# Disable error dialog boxes like we do in the postmaster.
|
||||||
|
# Here, we run code that triggers relevant errors.
|
||||||
|
use Win32API::File qw(SetErrorMode :SEM_);
|
||||||
|
my $oldmode = SetErrorMode(
|
||||||
|
SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
|
||||||
|
system(".\\$exe");
|
||||||
|
SetErrorMode($oldmode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !($? >> 8);
|
||||||
|
};
|
||||||
|
|
||||||
|
my $define_32bit_time = '_USE_32BIT_TIME_T';
|
||||||
|
my $ok_now = $try_define->(undef);
|
||||||
|
my $ok_32bit = $try_define->($define_32bit_time);
|
||||||
|
unlink @conftest;
|
||||||
|
if (!$ok_now && !$ok_32bit)
|
||||||
|
{
|
||||||
|
|
||||||
|
# Unsupported configuration. Since we used %Config from the
|
||||||
|
# Perl running the build scripts, this is expected if
|
||||||
|
# attempting to link with some other Perl.
|
||||||
|
die "Perl test fails with or without -D$define_32bit_time";
|
||||||
|
}
|
||||||
|
elsif ($ok_now && $ok_32bit)
|
||||||
|
{
|
||||||
|
|
||||||
|
# Resulting build may work, but it's especially important to
|
||||||
|
# verify with "vcregress plcheck". A refined test may avoid
|
||||||
|
# this outcome.
|
||||||
|
warn "Perl test passes with or without -D$define_32bit_time";
|
||||||
|
}
|
||||||
|
elsif ($ok_32bit)
|
||||||
|
{
|
||||||
|
push(@perl_embed_ccflags, $define_32bit_time);
|
||||||
|
} # else $ok_now, hence no flag required
|
||||||
|
}
|
||||||
|
|
||||||
|
print "CFLAGS recommended by Perl: $Config{ccflags}\n";
|
||||||
|
print "CFLAGS to compile embedded Perl: ",
|
||||||
|
(join ' ', map { "-D$_" } @perl_embed_ccflags), "\n";
|
||||||
foreach my $f (@perl_embed_ccflags)
|
foreach my $f (@perl_embed_ccflags)
|
||||||
{
|
{
|
||||||
$plperl->AddDefine($f);
|
$plperl->AddDefine($f);
|
||||||
@ -605,20 +726,6 @@ sub mkvcbuild
|
|||||||
die 'Failed to create plperl_opmask.h' . "\n";
|
die 'Failed to create plperl_opmask.h' . "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$plperl->AddReference($postgres);
|
|
||||||
my $perl_path = $solution->{options}->{perl} . '\lib\CORE\*perl*';
|
|
||||||
# ActivePerl 5.16 provided perl516.lib; 5.18 provided libperl518.a
|
|
||||||
my @perl_libs =
|
|
||||||
grep { /perl\d+\.lib$|libperl\d+\.a$/ } glob($perl_path);
|
|
||||||
if (@perl_libs == 1)
|
|
||||||
{
|
|
||||||
$plperl->AddLibrary($perl_libs[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
die
|
|
||||||
"could not identify perl library version matching pattern $perl_path\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add transform module dependent on plperl
|
# Add transform module dependent on plperl
|
||||||
my $hstore_plperl = AddTransformModule(
|
my $hstore_plperl = AddTransformModule(
|
||||||
@ -965,4 +1072,9 @@ sub AdjustModule
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
END
|
||||||
|
{
|
||||||
|
unlink @unlink_on_exit;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
Loading…
Reference in New Issue
Block a user