@@ -27,6 +27,7 @@ my $libpgport;
27
27
my $libpgcommon ;
28
28
my $postgres ;
29
29
my $libpq ;
30
+ my @unlink_on_exit ;
30
31
31
32
# Set of variables for modules in contrib/ and src/test/modules/
32
33
my $contrib_defines = { ' refint' => ' REFINT_VERBOSE' };
@@ -508,34 +509,154 @@ sub mkvcbuild
508
509
my $plperl =
509
510
$solution -> AddProject(' plperl' , ' dll' , ' PLs' , ' src/pl/plperl' );
510
511
$plperl -> AddIncludeDir($solution -> {options }-> {perl } . ' /lib/CORE' );
512
+ $plperl -> AddReference($postgres );
513
+
514
+ my $perl_path = $solution -> {options }-> {perl } . ' \lib\CORE\*perl*' ;
515
+
516
+ # ActivePerl 5.16 provided perl516.lib; 5.18 provided libperl518.a
517
+ my @perl_libs =
518
+ grep { / perl\d +\. lib$|libperl\d +\. a$ / } glob ($perl_path );
519
+ if (@perl_libs == 1)
520
+ {
521
+ $plperl -> AddLibrary($perl_libs [0]);
522
+ }
523
+ else
524
+ {
525
+ die
526
+ " could not identify perl library version matching pattern $perl_path \n " ;
527
+ }
511
528
512
529
# Add defines from Perl's ccflags; see PGAC_CHECK_PERL_EMBED_CCFLAGS
513
530
my @perl_embed_ccflags ;
514
531
foreach my $f (split (" " , $Config {ccflags }))
515
532
{
516
- if ( $f =~ / ^-D[^_]/
517
- || $f =~ / ^-D_USE_32BIT_TIME_T/ )
533
+ if ($f =~ / ^-D[^_]/ )
518
534
{
519
535
$f =~ s /\- D// ;
520
536
push (@perl_embed_ccflags , $f );
521
537
}
522
538
}
523
539
524
- # Perl versions before 5.13.4 don't provide -D_USE_32BIT_TIME_T
525
- # regardless of how they were built. On 32-bit Windows, assume
526
- # such a version was built with a pre-MSVC-2005 compiler, and
527
- # define the symbol anyway, so that we are compatible if we're
528
- # being built with a later MSVC version.
529
- push (@perl_embed_ccflags , ' _USE_32BIT_TIME_T' )
530
- if $solution -> {platform } eq ' Win32'
531
- && $Config {PERL_REVISION } == 5
532
- && ($Config {PERL_VERSION } < 13
533
- || ( $Config {PERL_VERSION } == 13
534
- && $Config {PERL_SUBVERSION } < 4));
535
-
536
- # Also, a hack to prevent duplicate definitions of uid_t/gid_t
540
+ # hack to prevent duplicate definitions of uid_t/gid_t
537
541
push (@perl_embed_ccflags , ' PLPERL_HAVE_UID_GID' );
538
542
543
+ # Windows offers several 32-bit ABIs. Perl is sensitive to
544
+ # sizeof(time_t), one of the ABI dimensions. To get 32-bit time_t,
545
+ # use "cl -D_USE_32BIT_TIME_T" or plain "gcc". For 64-bit time_t, use
546
+ # "gcc -D__MINGW_USE_VC2005_COMPAT" or plain "cl". Before MSVC 2005,
547
+ # plain "cl" chose 32-bit time_t. PostgreSQL doesn't support building
548
+ # with pre-MSVC-2005 compilers, but it does support linking to Perl
549
+ # built with such a compiler. MSVC-built Perl 5.13.4 and later report
550
+ # -D_USE_32BIT_TIME_T in $Config{ccflags} if applicable, but
551
+ # MinGW-built Perl never reports -D_USE_32BIT_TIME_T despite typically
552
+ # needing it. Ignore the $Config{ccflags} opinion about
553
+ # -D_USE_32BIT_TIME_T, and use a runtime test to deduce the ABI Perl
554
+ # expects. Specifically, test use of PL_modglobal, which maps to a
555
+ # PerlInterpreter field whose position depends on sizeof(time_t).
556
+ if ($solution -> {platform } eq ' Win32' )
557
+ {
558
+ my $source_file = ' conftest.c' ;
559
+ my $obj = ' conftest.obj' ;
560
+ my $exe = ' conftest.exe' ;
561
+ my @conftest = ($source_file , $obj , $exe );
562
+ push @unlink_on_exit , @conftest ;
563
+ unlink $source_file ;
564
+ open my $o , ' >' , $source_file
565
+ || croak " Could not write to $source_file " ;
566
+ print $o '
567
+ /* compare to plperl.h */
568
+ #define __inline__ __inline
569
+ #define PERL_NO_GET_CONTEXT
570
+ #include <EXTERN.h>
571
+ #include <perl.h>
572
+
573
+ int
574
+ main(int argc, char **argv)
575
+ {
576
+ int dummy_argc = 1;
577
+ char *dummy_argv[1] = {""};
578
+ char *dummy_env[1] = {NULL};
579
+ static PerlInterpreter *interp;
580
+
581
+ PERL_SYS_INIT3(&dummy_argc, (char ***) &dummy_argv,
582
+ (char ***) &dummy_env);
583
+ interp = perl_alloc();
584
+ perl_construct(interp);
585
+ {
586
+ dTHX;
587
+ const char key[] = "dummy";
588
+
589
+ PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
590
+ hv_store(PL_modglobal, key, sizeof(key) - 1, newSViv(1), 0);
591
+ return hv_fetch(PL_modglobal, key, sizeof(key) - 1, 0) == NULL;
592
+ }
593
+ }
594
+ ' ;
595
+ close $o ;
596
+
597
+ # Build $source_file with a given #define, and return a true value
598
+ # if a run of the resulting binary exits successfully.
599
+ my $try_define = sub {
600
+ my $define = shift ;
601
+
602
+ unlink $obj , $exe ;
603
+ my @cmd = (
604
+ ' cl' ,
605
+ ' -I' . $solution -> {options }-> {perl } . ' /lib/CORE' ,
606
+ (map { " -D$_ " } @perl_embed_ccflags , $define || ()),
607
+ $source_file ,
608
+ ' /link' ,
609
+ $perl_libs [0]);
610
+ my $compile_output = ` @cmd 2>&1` ;
611
+ -f $exe || die " Failed to build Perl test:\n $compile_output " ;
612
+
613
+ {
614
+
615
+ # Some builds exhibit runtime failure through Perl warning
616
+ # 'Can't spawn "conftest.exe"'; supress that.
617
+ no warnings;
618
+
619
+ # Disable error dialog boxes like we do in the postmaster.
620
+ # Here, we run code that triggers relevant errors.
621
+ use Win32API::File qw( SetErrorMode :SEM_) ;
622
+ my $oldmode = SetErrorMode(
623
+ SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
624
+ system (" .\\ $exe " );
625
+ SetErrorMode($oldmode );
626
+ }
627
+
628
+ return !($? >> 8);
629
+ };
630
+
631
+ my $define_32bit_time = ' _USE_32BIT_TIME_T' ;
632
+ my $ok_now = $try_define -> (undef );
633
+ my $ok_32bit = $try_define -> ($define_32bit_time );
634
+ unlink @conftest ;
635
+ if (!$ok_now && !$ok_32bit )
636
+ {
637
+
638
+ # Unsupported configuration. Since we used %Config from the
639
+ # Perl running the build scripts, this is expected if
640
+ # attempting to link with some other Perl.
641
+ die " Perl test fails with or without -D$define_32bit_time " ;
642
+ }
643
+ elsif ($ok_now && $ok_32bit )
644
+ {
645
+
646
+ # Resulting build may work, but it's especially important to
647
+ # verify with "vcregress plcheck". A refined test may avoid
648
+ # this outcome.
649
+ warn " Perl test passes with or without -D$define_32bit_time " ;
650
+ }
651
+ elsif ($ok_32bit )
652
+ {
653
+ push (@perl_embed_ccflags , $define_32bit_time );
654
+ } # else $ok_now, hence no flag required
655
+ }
656
+
657
+ print " CFLAGS recommended by Perl: $Config {ccflags}\n " ;
658
+ print " CFLAGS to compile embedded Perl: " ,
659
+ (join ' ' , map { " -D$_ " } @perl_embed_ccflags ), " \n " ;
539
660
foreach my $f (@perl_embed_ccflags )
540
661
{
541
662
$plperl -> AddDefine($f );
@@ -605,20 +726,6 @@ sub mkvcbuild
605
726
die ' Failed to create plperl_opmask.h' . " \n " ;
606
727
}
607
728
}
608
- $plperl -> AddReference($postgres );
609
- my $perl_path = $solution -> {options }-> {perl } . ' \lib\CORE\*perl*' ;
610
- # ActivePerl 5.16 provided perl516.lib; 5.18 provided libperl518.a
611
- my @perl_libs =
612
- grep { / perl\d +\. lib$|libperl\d +\. a$ / } glob ($perl_path );
613
- if (@perl_libs == 1)
614
- {
615
- $plperl -> AddLibrary($perl_libs [0]);
616
- }
617
- else
618
- {
619
- die
620
- " could not identify perl library version matching pattern $perl_path \n " ;
621
- }
622
729
623
730
# Add transform module dependent on plperl
624
731
my $hstore_plperl = AddTransformModule(
@@ -965,4 +1072,9 @@ sub AdjustModule
965
1072
}
966
1073
}
967
1074
1075
+ END
1076
+ {
1077
+ unlink @unlink_on_exit ;
1078
+ }
1079
+
968
1080
1;
0 commit comments