@@ -28,6 +28,7 @@ my $libpgcommon;
28
28
my $libpgfeutils ;
29
29
my $postgres ;
30
30
my $libpq ;
31
+ my @unlink_on_exit ;
31
32
32
33
# Set of variables for modules in contrib/ and src/test/modules/
33
34
my $contrib_defines = { ' refint' => ' REFINT_VERBOSE' };
@@ -547,34 +548,154 @@ sub mkvcbuild
547
548
my $plperl =
548
549
$solution -> AddProject(' plperl' , ' dll' , ' PLs' , ' src/pl/plperl' );
549
550
$plperl -> AddIncludeDir($solution -> {options }-> {perl } . ' /lib/CORE' );
551
+ $plperl -> AddReference($postgres );
552
+
553
+ my $perl_path = $solution -> {options }-> {perl } . ' \lib\CORE\*perl*' ;
554
+
555
+ # ActivePerl 5.16 provided perl516.lib; 5.18 provided libperl518.a
556
+ my @perl_libs =
557
+ grep { / perl\d +\. lib$|libperl\d +\. a$ / } glob ($perl_path );
558
+ if (@perl_libs == 1)
559
+ {
560
+ $plperl -> AddLibrary($perl_libs [0]);
561
+ }
562
+ else
563
+ {
564
+ die
565
+ " could not identify perl library version matching pattern $perl_path \n " ;
566
+ }
550
567
551
568
# Add defines from Perl's ccflags; see PGAC_CHECK_PERL_EMBED_CCFLAGS
552
569
my @perl_embed_ccflags ;
553
570
foreach my $f (split (" " , $Config {ccflags }))
554
571
{
555
- if ( $f =~ / ^-D[^_]/
556
- || $f =~ / ^-D_USE_32BIT_TIME_T/ )
572
+ if ($f =~ / ^-D[^_]/ )
557
573
{
558
574
$f =~ s /\- D// ;
559
575
push (@perl_embed_ccflags , $f );
560
576
}
561
577
}
562
578
563
- # Perl versions before 5.13.4 don't provide -D_USE_32BIT_TIME_T
564
- # regardless of how they were built. On 32-bit Windows, assume
565
- # such a version was built with a pre-MSVC-2005 compiler, and
566
- # define the symbol anyway, so that we are compatible if we're
567
- # being built with a later MSVC version.
568
- push (@perl_embed_ccflags , ' _USE_32BIT_TIME_T' )
569
- if $solution -> {platform } eq ' Win32'
570
- && $Config {PERL_REVISION } == 5
571
- && ($Config {PERL_VERSION } < 13
572
- || ( $Config {PERL_VERSION } == 13
573
- && $Config {PERL_SUBVERSION } < 4));
574
-
575
- # Also, a hack to prevent duplicate definitions of uid_t/gid_t
579
+ # hack to prevent duplicate definitions of uid_t/gid_t
576
580
push (@perl_embed_ccflags , ' PLPERL_HAVE_UID_GID' );
577
581
582
+ # Windows offers several 32-bit ABIs. Perl is sensitive to
583
+ # sizeof(time_t), one of the ABI dimensions. To get 32-bit time_t,
584
+ # use "cl -D_USE_32BIT_TIME_T" or plain "gcc". For 64-bit time_t, use
585
+ # "gcc -D__MINGW_USE_VC2005_COMPAT" or plain "cl". Before MSVC 2005,
586
+ # plain "cl" chose 32-bit time_t. PostgreSQL doesn't support building
587
+ # with pre-MSVC-2005 compilers, but it does support linking to Perl
588
+ # built with such a compiler. MSVC-built Perl 5.13.4 and later report
589
+ # -D_USE_32BIT_TIME_T in $Config{ccflags} if applicable, but
590
+ # MinGW-built Perl never reports -D_USE_32BIT_TIME_T despite typically
591
+ # needing it. Ignore the $Config{ccflags} opinion about
592
+ # -D_USE_32BIT_TIME_T, and use a runtime test to deduce the ABI Perl
593
+ # expects. Specifically, test use of PL_modglobal, which maps to a
594
+ # PerlInterpreter field whose position depends on sizeof(time_t).
595
+ if ($solution -> {platform } eq ' Win32' )
596
+ {
597
+ my $source_file = ' conftest.c' ;
598
+ my $obj = ' conftest.obj' ;
599
+ my $exe = ' conftest.exe' ;
600
+ my @conftest = ($source_file , $obj , $exe );
601
+ push @unlink_on_exit , @conftest ;
602
+ unlink $source_file ;
603
+ open my $o , ' >' , $source_file
604
+ || croak " Could not write to $source_file " ;
605
+ print $o '
606
+ /* compare to plperl.h */
607
+ #define __inline__ __inline
608
+ #define PERL_NO_GET_CONTEXT
609
+ #include <EXTERN.h>
610
+ #include <perl.h>
611
+
612
+ int
613
+ main(int argc, char **argv)
614
+ {
615
+ int dummy_argc = 1;
616
+ char *dummy_argv[1] = {""};
617
+ char *dummy_env[1] = {NULL};
618
+ static PerlInterpreter *interp;
619
+
620
+ PERL_SYS_INIT3(&dummy_argc, (char ***) &dummy_argv,
621
+ (char ***) &dummy_env);
622
+ interp = perl_alloc();
623
+ perl_construct(interp);
624
+ {
625
+ dTHX;
626
+ const char key[] = "dummy";
627
+
628
+ PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
629
+ hv_store(PL_modglobal, key, sizeof(key) - 1, newSViv(1), 0);
630
+ return hv_fetch(PL_modglobal, key, sizeof(key) - 1, 0) == NULL;
631
+ }
632
+ }
633
+ ' ;
634
+ close $o ;
635
+
636
+ # Build $source_file with a given #define, and return a true value
637
+ # if a run of the resulting binary exits successfully.
638
+ my $try_define = sub {
639
+ my $define = shift ;
640
+
641
+ unlink $obj , $exe ;
642
+ my @cmd = (
643
+ ' cl' ,
644
+ ' -I' . $solution -> {options }-> {perl } . ' /lib/CORE' ,
645
+ (map { " -D$_ " } @perl_embed_ccflags , $define || ()),
646
+ $source_file ,
647
+ ' /link' ,
648
+ $perl_libs [0]);
649
+ my $compile_output = ` @cmd 2>&1` ;
650
+ -f $exe || die " Failed to build Perl test:\n $compile_output " ;
651
+
652
+ {
653
+
654
+ # Some builds exhibit runtime failure through Perl warning
655
+ # 'Can't spawn "conftest.exe"'; supress that.
656
+ no warnings;
657
+
658
+ # Disable error dialog boxes like we do in the postmaster.
659
+ # Here, we run code that triggers relevant errors.
660
+ use Win32API::File qw( SetErrorMode :SEM_) ;
661
+ my $oldmode = SetErrorMode(
662
+ SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
663
+ system (" .\\ $exe " );
664
+ SetErrorMode($oldmode );
665
+ }
666
+
667
+ return !($? >> 8);
668
+ };
669
+
670
+ my $define_32bit_time = ' _USE_32BIT_TIME_T' ;
671
+ my $ok_now = $try_define -> (undef );
672
+ my $ok_32bit = $try_define -> ($define_32bit_time );
673
+ unlink @conftest ;
674
+ if (!$ok_now && !$ok_32bit )
675
+ {
676
+
677
+ # Unsupported configuration. Since we used %Config from the
678
+ # Perl running the build scripts, this is expected if
679
+ # attempting to link with some other Perl.
680
+ die " Perl test fails with or without -D$define_32bit_time " ;
681
+ }
682
+ elsif ($ok_now && $ok_32bit )
683
+ {
684
+
685
+ # Resulting build may work, but it's especially important to
686
+ # verify with "vcregress plcheck". A refined test may avoid
687
+ # this outcome.
688
+ warn " Perl test passes with or without -D$define_32bit_time " ;
689
+ }
690
+ elsif ($ok_32bit )
691
+ {
692
+ push (@perl_embed_ccflags , $define_32bit_time );
693
+ } # else $ok_now, hence no flag required
694
+ }
695
+
696
+ print " CFLAGS recommended by Perl: $Config {ccflags}\n " ;
697
+ print " CFLAGS to compile embedded Perl: " ,
698
+ (join ' ' , map { " -D$_ " } @perl_embed_ccflags ), " \n " ;
578
699
foreach my $f (@perl_embed_ccflags )
579
700
{
580
701
$plperl -> AddDefine($f );
@@ -644,6 +765,7 @@ sub mkvcbuild
644
765
die ' Failed to create plperl_opmask.h' . " \n " ;
645
766
}
646
767
}
768
+ <<<<<<< HEAD
647
769
$plperl ->AddReference($postgres );
648
770
my $perl_path = $solution ->{options}->{perl} . '\l ib\C ORE\* .*';
649
771
my @perl_libs =
@@ -658,6 +780,8 @@ sub mkvcbuild
658
780
die
659
781
"could not identify perl library version matching pattern $perl_path \n ";
660
782
}
783
+ =======
784
+ >>>>>>> 9b5c99790e... MSVC: Test whether 32-bit Perl needs -D_USE_32BIT_TIME_T.
661
785
662
786
# Add transform module dependent on plperl
663
787
my $hstore_plperl = AddTransformModule(
@@ -1032,4 +1156,9 @@ sub AdjustModule
1032
1156
}
1033
1157
}
1034
1158
1159
+ END
1160
+ {
1161
+ unlink @unlink_on_exit ;
1162
+ }
1163
+
1035
1164
1;
0 commit comments