@@ -28,6 +28,7 @@ my $libpgport;
28
28
my $libpgcommon ;
29
29
my $postgres ;
30
30
my $libpq ;
31
+ my @unlink_on_exit ;
31
32
32
33
my $contrib_defines = {' refint' => ' REFINT_VERBOSE' };
33
34
my @contrib_uselibpq =
@@ -140,34 +141,154 @@ sub mkvcbuild
140
141
my $plperl =
141
142
$solution -> AddProject(' plperl' ,' dll' ,' PLs' ,' src\pl\plperl' );
142
143
$plperl -> AddIncludeDir($solution -> {options }-> {perl } .' /lib/CORE' );
144
+ $plperl -> AddReference($postgres );
145
+
146
+ my $perl_path =$solution -> {options }-> {perl } .' \lib\CORE\*perl*' ;
147
+
148
+ # ActivePerl 5.16 provided perl516.lib; 5.18 provided libperl518.a
149
+ my @perl_libs =
150
+ grep {/ perl\d +\. lib$|libperl\d +\. a$ / }glob ($perl_path );
151
+ if (@perl_libs == 1)
152
+ {
153
+ $plperl -> AddLibrary($perl_libs [0]);
154
+ }
155
+ else
156
+ {
157
+ die
158
+ " could not identify perl library version matching pattern$perl_path \n " ;
159
+ }
143
160
144
161
# Add defines from Perl's ccflags; see PGAC_CHECK_PERL_EMBED_CCFLAGS
145
162
my @perl_embed_ccflags ;
146
163
foreach my $f (split (" " ,$Config {ccflags }))
147
164
{
148
- if ($f =~/ ^-D[^_]/ ||
149
- $f =~/ ^-D_USE_32BIT_TIME_T/ )
165
+ if ($f =~/ ^-D[^_]/ )
150
166
{
151
167
$f =~s /\- D// ;
152
168
push (@perl_embed_ccflags ,$f );
153
169
}
154
170
}
155
171
156
- # Perl versions before 5.13.4 don't provide -D_USE_32BIT_TIME_T
157
- # regardless of how they were built. On 32-bit Windows, assume
158
- # such a version was built with a pre-MSVC-2005 compiler, and
159
- # define the symbol anyway, so that we are compatible if we're
160
- # being built with a later MSVC version.
161
- push (@perl_embed_ccflags ,' _USE_32BIT_TIME_T' )
162
- if $solution -> {platform }eq ' Win32'
163
- &&$Config {PERL_REVISION } == 5
164
- && ($Config {PERL_VERSION } < 13
165
- || ($Config {PERL_VERSION } == 13
166
- &&$Config {PERL_SUBVERSION } < 4));
167
-
168
- # Also, a hack to prevent duplicate definitions of uid_t/gid_t
172
+ # hack to prevent duplicate definitions of uid_t/gid_t
169
173
push (@perl_embed_ccflags ,' PLPERL_HAVE_UID_GID' );
170
174
175
+ # Windows offers several 32-bit ABIs. Perl is sensitive to
176
+ # sizeof(time_t), one of the ABI dimensions. To get 32-bit time_t,
177
+ # use "cl -D_USE_32BIT_TIME_T" or plain "gcc". For 64-bit time_t, use
178
+ # "gcc -D__MINGW_USE_VC2005_COMPAT" or plain "cl". Before MSVC 2005,
179
+ # plain "cl" chose 32-bit time_t. PostgreSQL doesn't support building
180
+ # with pre-MSVC-2005 compilers, but it does support linking to Perl
181
+ # built with such a compiler. MSVC-built Perl 5.13.4 and later report
182
+ # -D_USE_32BIT_TIME_T in $Config{ccflags} if applicable, but
183
+ # MinGW-built Perl never reports -D_USE_32BIT_TIME_T despite typically
184
+ # needing it. Ignore the $Config{ccflags} opinion about
185
+ # -D_USE_32BIT_TIME_T, and use a runtime test to deduce the ABI Perl
186
+ # expects. Specifically, test use of PL_modglobal, which maps to a
187
+ # PerlInterpreter field whose position depends on sizeof(time_t).
188
+ if ($solution -> {platform }eq ' Win32' )
189
+ {
190
+ my $source_file =' conftest.c' ;
191
+ my $obj =' conftest.obj' ;
192
+ my $exe =' conftest.exe' ;
193
+ my @conftest = ($source_file ,$obj ,$exe );
194
+ push @unlink_on_exit ,@conftest ;
195
+ unlink $source_file ;
196
+ open my $o ,' >' ,$source_file
197
+ || croak" Could not write to$source_file " ;
198
+ print $o '
199
+ /* compare to plperl.h */
200
+ #define __inline__ __inline
201
+ #define PERL_NO_GET_CONTEXT
202
+ #include <EXTERN.h>
203
+ #include <perl.h>
204
+
205
+ int
206
+ main(int argc, char **argv)
207
+ {
208
+ intdummy_argc = 1;
209
+ char *dummy_argv[1] = {""};
210
+ char *dummy_env[1] = {NULL};
211
+ static PerlInterpreter *interp;
212
+
213
+ PERL_SYS_INIT3(&dummy_argc, (char ***) &dummy_argv,
214
+ (char ***) &dummy_env);
215
+ interp = perl_alloc();
216
+ perl_construct(interp);
217
+ {
218
+ dTHX;
219
+ const charkey[] = "dummy";
220
+
221
+ PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
222
+ hv_store(PL_modglobal, key, sizeof(key) - 1, newSViv(1), 0);
223
+ return hv_fetch(PL_modglobal, key, sizeof(key) - 1, 0) == NULL;
224
+ }
225
+ }
226
+ ' ;
227
+ close $o ;
228
+
229
+ # Build $source_file with a given #define, and return a true value
230
+ # if a run of the resulting binary exits successfully.
231
+ my $try_define =sub {
232
+ my $define =shift ;
233
+
234
+ unlink $obj ,$exe ;
235
+ my @cmd = (
236
+ ' cl' ,
237
+ ' -I' .$solution -> {options }-> {perl } .' /lib/CORE' ,
238
+ (map {" -D$_ " }@perl_embed_ccflags ,$define || ()),
239
+ $source_file ,
240
+ ' /link' ,
241
+ $perl_libs [0]);
242
+ my $compile_output =` @cmd 2>&1` ;
243
+ -f $exe ||die " Failed to build Perl test:\n $compile_output " ;
244
+
245
+ {
246
+
247
+ # Some builds exhibit runtime failure through Perl warning
248
+ # 'Can't spawn "conftest.exe"'; supress that.
249
+ no warnings;
250
+
251
+ # Disable error dialog boxes like we do in the postmaster.
252
+ # Here, we run code that triggers relevant errors.
253
+ use Win32API::Fileqw( SetErrorMode :SEM_) ;
254
+ my $oldmode = SetErrorMode(
255
+ SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
256
+ system (" .\\ $exe " );
257
+ SetErrorMode($oldmode );
258
+ }
259
+
260
+ return !($? >> 8);
261
+ };
262
+
263
+ my $define_32bit_time =' _USE_32BIT_TIME_T' ;
264
+ my $ok_now =$try_define -> (undef );
265
+ my $ok_32bit =$try_define -> ($define_32bit_time );
266
+ unlink @conftest ;
267
+ if (!$ok_now && !$ok_32bit )
268
+ {
269
+
270
+ # Unsupported configuration. Since we used %Config from the
271
+ # Perl running the build scripts, this is expected if
272
+ # attempting to link with some other Perl.
273
+ die " Perl test fails with or without -D$define_32bit_time " ;
274
+ }
275
+ elsif ($ok_now &&$ok_32bit )
276
+ {
277
+
278
+ # Resulting build may work, but it's especially important to
279
+ # verify with "vcregress plcheck". A refined test may avoid
280
+ # this outcome.
281
+ warn " Perl test passes with or without -D$define_32bit_time " ;
282
+ }
283
+ elsif ($ok_32bit )
284
+ {
285
+ push (@perl_embed_ccflags ,$define_32bit_time );
286
+ }# else $ok_now, hence no flag required
287
+ }
288
+
289
+ print " CFLAGS recommended by Perl:$Config {ccflags}\n " ;
290
+ print " CFLAGS to compile embedded Perl:" ,
291
+ (join ' ' ,map {" -D$_ " }@perl_embed_ccflags )," \n " ;
171
292
foreach my $f (@perl_embed_ccflags )
172
293
{
173
294
$plperl -> AddDefine($f );
@@ -237,19 +358,6 @@ sub mkvcbuild
237
358
die ' Failed to create plperl_opmask.h' ." \n " ;
238
359
}
239
360
}
240
- $plperl -> AddReference($postgres );
241
- my $perl_path =$solution -> {options }-> {perl } .' \lib\CORE\*perl*' ;
242
- # ActivePerl 5.16 provided perl516.lib; 5.18 provided libperl518.a
243
- my @perl_libs =
244
- grep {/ perl\d +\. lib$|libperl\d +\. a$ / }glob ($perl_path );
245
- if (@perl_libs == 1)
246
- {
247
- $plperl -> AddLibrary($perl_libs [0]);
248
- }
249
- else
250
- {
251
- die " could not identify perl library version" ;
252
- }
253
361
}
254
362
255
363
if ($solution -> {options }-> {python })
@@ -839,4 +947,9 @@ sub AdjustContribProj
839
947
}
840
948
}
841
949
950
+ END
951
+ {
952
+ unlink @unlink_on_exit ;
953
+ }
954
+
842
955
1;