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