2 # Copyright (c) 2021-2022, PostgreSQL Global Development Group
7 # Package that encapsulates a Visual C++ solution file generation
9 # src/tools/msvc/Solution.pm
16 no warnings
qw(redefine); ## no critic
20 my $classname = shift;
25 VisualStudioVersion
=> undef,
26 MinimumVisualStudioVersion
=> undef,
30 bless($self, $classname);
32 $self->DeterminePlatform();
34 if ($options->{xslt
} && !$options->{xml
})
36 die "XSLT requires XML\n";
38 $options->{blocksize
} = 8
39 unless $options->{blocksize
}; # undef or 0 means default
40 die "Bad blocksize $options->{blocksize}"
41 unless grep { $_ == $options->{blocksize
} } (1, 2, 4, 8, 16, 32);
42 $options->{segsize
} = 1
43 unless $options->{segsize
}; # undef or 0 means default
44 # only allow segsize 1 for now, as we can't do large files yet in windows
45 die "Bad segsize $options->{segsize}"
46 unless $options->{segsize
} == 1;
47 $options->{wal_blocksize
} = 8
48 unless $options->{wal_blocksize
}; # undef or 0 means default
49 die "Bad wal_blocksize $options->{wal_blocksize}"
50 unless grep { $_ == $options->{wal_blocksize
} }
51 (1, 2, 4, 8, 16, 32, 64);
56 sub GetAdditionalHeaders
67 # Examine CL help output to determine if we are in 32 or 64-bit mode.
68 my $output = `cl /help 2>&1`;
69 $?
>> 8 == 0 or die "cl command not found";
71 ($output =~ /^\/favor
:<.+AMD64
/m
) ?
'x64' : 'Win32';
75 $self->{platform
} = 'FAKE';
77 print "Detected hardware platform: $self->{platform}\n";
81 # Return 1 if $oldfile is newer than $newfile, or if $newfile doesn't exist.
82 # Special case - if config.pl has changed, always return 1
85 my ($newfile, $oldfile) = @_;
86 -e
$oldfile or warn "source file \"$oldfile\" does not exist";
87 if ( $oldfile ne 'src/tools/msvc/config.pl'
88 && $oldfile ne 'src/tools/msvc/config_default.pl')
91 if (-f
'src/tools/msvc/config.pl')
92 && IsNewer
($newfile, 'src/tools/msvc/config.pl');
94 if (-f
'src/tools/msvc/config_default.pl')
95 && IsNewer
($newfile, 'src/tools/msvc/config_default.pl');
97 return 1 if (!(-e
$newfile));
98 my @nstat = stat($newfile);
99 my @ostat = stat($oldfile);
100 return 1 if ($nstat[9] < $ostat[9]);
104 # Copy a file, *not* preserving date. Only works for text files.
107 my ($src, $dest) = @_;
108 open(my $i, '<', $src) || croak
"Could not open $src";
109 open(my $o, '>', $dest) || croak
"Could not open $dest";
119 # Fetch version of OpenSSL based on a parsing of the command shipped with
120 # the installer this build is linking to. This returns as result an array
121 # made of the three first digits of the OpenSSL version, which is enough
122 # to decide which options to apply depending on the version of OpenSSL
124 sub GetOpenSSLVersion
128 # Attempt to get OpenSSL version and location. This assumes that
129 # openssl.exe is in the specified directory.
130 # Quote the .exe name in case it has spaces
132 qq("$self->{options}->{openssl}\\bin\\openssl.exe" version
2>&1);
133 my $sslout = `$opensslcmd`;
137 "Unable to determine OpenSSL version: The openssl.exe command wasn't found.";
139 if ($sslout =~ /(\d+)\.(\d+)\.(\d+)(\D)/m)
145 "Unable to determine OpenSSL version: The openssl.exe version could not be determined.";
151 my $bits = $self->{platform
} eq 'Win32' ?
32 : 64;
152 my $ac_init_found = 0;
155 my $package_bugreport;
157 my ($majorver, $minorver);
158 my $ac_define_openssl_api_compat_found = 0;
159 my $openssl_api_compat;
161 # Parse configure.ac to get version numbers
162 open(my $c, '<', "configure.ac")
163 || confess
("Could not open configure.ac for reading\n");
166 if (/^AC_INIT\(\[([^\]]+)\], \[([^\]]+)\], \[([^\]]+)\], \[([^\]]*)\], \[([^\]]+)\]/
172 $package_version = $2;
173 $package_bugreport = $3;
174 #$package_tarname = $4;
177 if ($package_version !~ /^(\d+)(?:\.(\d+))?/)
179 confess
"Bad format of version: $package_version\n";
181 $majorver = sprintf("%d", $1);
182 $minorver = sprintf("%d", $2 ?
$2 : 0);
184 elsif (/\bAC_DEFINE\(OPENSSL_API_COMPAT, \[([0-9xL]+)\]/)
186 $ac_define_openssl_api_compat_found = 1;
187 $openssl_api_compat = $1;
191 confess
"Unable to parse configure.ac for all variables!"
192 unless $ac_init_found && $ac_define_openssl_api_compat_found;
194 if (IsNewer
("src/include/pg_config_os.h", "src/include/port/win32.h"))
196 print "Copying pg_config_os.h...\n";
197 copyFile
("src/include/port/win32.h", "src/include/pg_config_os.h");
200 print "Generating configuration headers...\n";
201 my $extraver = $self->{options
}->{extraver
};
202 $extraver = '' unless defined $extraver;
203 my $port = $self->{options
}->{"--with-pgport"} || 5432;
205 # Every symbol in pg_config.h.in must be accounted for here. Set
206 # to undef if the symbol should not be defined.
211 ALIGNOF_LONG_LONG_INT
=> 8,
212 ALIGNOF_PG_INT128_TYPE
=> undef,
214 AC_APPLE_UNIVERSAL_BUILD
=> undef,
215 BLCKSZ
=> 1024 * $self->{options
}->{blocksize
},
216 CONFIGURE_ARGS
=> '"' . $self->GetFakeConfigure() . '"',
218 DEF_PGPORT_STR
=> qq{"$port"},
219 DLSUFFIX
=> '".dll"',
220 ENABLE_GSS
=> $self->{options
}->{gss
} ?
1 : undef,
221 ENABLE_NLS
=> $self->{options
}->{nls
} ?
1 : undef,
222 ENABLE_THREAD_SAFETY
=> 1,
223 HAVE_APPEND_HISTORY
=> undef,
224 HAVE_ASN1_STRING_GET0_DATA
=> undef,
226 HAVE_ATOMIC_H
=> undef,
227 HAVE_BACKTRACE_SYMBOLS
=> undef,
228 HAVE_BIO_GET_DATA
=> undef,
229 HAVE_BIO_METH_NEW
=> undef,
230 HAVE_COMPUTED_GOTO
=> undef,
231 HAVE_COPYFILE
=> undef,
232 HAVE_COPYFILE_H
=> undef,
233 HAVE_CRTDEFS_H
=> undef,
234 HAVE_CRYPTO_LOCK
=> undef,
235 HAVE_DECL_FDATASYNC
=> 0,
236 HAVE_DECL_F_FULLFSYNC
=> 0,
237 HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER
=> 0,
238 HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER
=> 0,
239 HAVE_DECL_LLVMGETHOSTCPUNAME
=> 0,
240 HAVE_DECL_LLVMGETHOSTCPUFEATURES
=> 0,
241 HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN
=> 0,
242 HAVE_DECL_POSIX_FADVISE
=> 0,
243 HAVE_DECL_PREADV
=> 0,
244 HAVE_DECL_PWRITEV
=> 0,
245 HAVE_DECL_STRLCAT
=> 0,
246 HAVE_DECL_STRLCPY
=> 0,
247 HAVE_DECL_STRNLEN
=> 1,
248 HAVE_EDITLINE_HISTORY_H
=> undef,
249 HAVE_EDITLINE_READLINE_H
=> undef,
250 HAVE_EXECINFO_H
=> undef,
251 HAVE_EXPLICIT_BZERO
=> undef,
253 HAVE_GCC__ATOMIC_INT32_CAS
=> undef,
254 HAVE_GCC__ATOMIC_INT64_CAS
=> undef,
255 HAVE_GCC__SYNC_CHAR_TAS
=> undef,
256 HAVE_GCC__SYNC_INT32_CAS
=> undef,
257 HAVE_GCC__SYNC_INT32_TAS
=> undef,
258 HAVE_GCC__SYNC_INT64_CAS
=> undef,
259 HAVE_GETADDRINFO
=> undef,
260 HAVE_GETHOSTBYNAME_R
=> undef,
261 HAVE_GETIFADDRS
=> undef,
262 HAVE_GETOPT
=> undef,
263 HAVE_GETOPT_H
=> undef,
264 HAVE_GETOPT_LONG
=> undef,
265 HAVE_GETPEEREID
=> undef,
266 HAVE_GETPEERUCRED
=> undef,
267 HAVE_GSSAPI_GSSAPI_H
=> undef,
268 HAVE_GSSAPI_H
=> undef,
269 HAVE_HMAC_CTX_FREE
=> undef,
270 HAVE_HMAC_CTX_NEW
=> undef,
271 HAVE_HISTORY_H
=> undef,
272 HAVE_HISTORY_TRUNCATE_FILE
=> undef,
273 HAVE_IFADDRS_H
=> undef,
274 HAVE_INET_ATON
=> undef,
276 HAVE_INT_TIMEZONE
=> 1,
279 HAVE_INTTYPES_H
=> undef,
280 HAVE_INT_OPTERR
=> undef,
281 HAVE_INT_OPTRESET
=> undef,
283 HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P
=> undef,
284 HAVE_KQUEUE
=> undef,
285 HAVE_LANGINFO_H
=> undef,
286 HAVE_LDAP_H
=> undef,
287 HAVE_LDAP_INITIALIZE
=> undef,
288 HAVE_LIBCRYPTO
=> undef,
289 HAVE_LIBLDAP
=> undef,
290 HAVE_LIBLZ4
=> undef,
292 HAVE_LIBPAM
=> undef,
293 HAVE_LIBREADLINE
=> undef,
294 HAVE_LIBSELINUX
=> undef,
295 HAVE_LIBSSL
=> undef,
296 HAVE_LIBWLDAP32
=> undef,
297 HAVE_LIBXML2
=> undef,
298 HAVE_LIBXSLT
=> undef,
299 HAVE_LIBZ
=> $self->{options
}->{zlib
} ?
1 : undef,
300 HAVE_LIBZSTD
=> undef,
302 HAVE_LONG_INT_64
=> undef,
303 HAVE_LONG_LONG_INT_64
=> 1,
304 HAVE_MBARRIER_H
=> undef,
305 HAVE_MBSTOWCS_L
=> 1,
307 HAVE_MEMSET_S
=> undef,
308 HAVE_MKDTEMP
=> undef,
309 HAVE_NETINET_TCP_H
=> undef,
310 HAVE_NET_IF_H
=> undef,
311 HAVE_OPENSSL_INIT_SSL
=> undef,
312 HAVE_OSSP_UUID_H
=> undef,
313 HAVE_PAM_PAM_APPL_H
=> undef,
314 HAVE_POSIX_FADVISE
=> undef,
315 HAVE_POSIX_FALLOCATE
=> undef,
316 HAVE_PPC_LWARX_MUTEX_HINT
=> undef,
318 HAVE_PS_STRINGS
=> undef,
319 HAVE_PTHREAD
=> undef,
320 HAVE_PTHREAD_BARRIER_WAIT
=> undef,
321 HAVE_PTHREAD_IS_THREADED_NP
=> undef,
322 HAVE_PTHREAD_PRIO_INHERIT
=> undef,
323 HAVE_READLINE_H
=> undef,
324 HAVE_READLINE_HISTORY_H
=> undef,
325 HAVE_READLINE_READLINE_H
=> undef,
326 HAVE_RL_COMPLETION_MATCHES
=> undef,
327 HAVE_RL_COMPLETION_SUPPRESS_QUOTE
=> undef,
328 HAVE_RL_FILENAME_COMPLETION_FUNCTION
=> undef,
329 HAVE_RL_FILENAME_QUOTE_CHARACTERS
=> undef,
330 HAVE_RL_FILENAME_QUOTING_FUNCTION
=> undef,
331 HAVE_RL_RESET_SCREEN_SIZE
=> undef,
332 HAVE_RL_VARIABLE_BIND
=> undef,
333 HAVE_SECURITY_PAM_APPL_H
=> undef,
334 HAVE_SETPROCTITLE
=> undef,
335 HAVE_SETPROCTITLE_FAST
=> undef,
341 HAVE_STRCHRNUL
=> undef,
342 HAVE_STRERROR_R
=> undef,
343 HAVE_STRINGS_H
=> undef,
345 HAVE_STRLCAT
=> undef,
346 HAVE_STRLCPY
=> undef,
348 HAVE_STRSIGNAL
=> undef,
349 HAVE_STRUCT_ADDRINFO
=> 1,
350 HAVE_STRUCT_CMSGCRED
=> undef,
351 HAVE_STRUCT_OPTION
=> undef,
352 HAVE_STRUCT_SOCKADDR_SA_LEN
=> undef,
353 HAVE_STRUCT_SOCKADDR_STORAGE
=> 1,
354 HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
=> 1,
355 HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
=> undef,
356 HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
=> undef,
357 HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
=> undef,
358 HAVE_STRUCT_SOCKADDR_UN
=> undef,
359 HAVE_STRUCT_TM_TM_ZONE
=> undef,
360 HAVE_SYNC_FILE_RANGE
=> undef,
361 HAVE_SYNCFS
=> undef,
362 HAVE_SYSLOG
=> undef,
363 HAVE_SYS_EPOLL_H
=> undef,
364 HAVE_SYS_EVENT_H
=> undef,
365 HAVE_SYS_IPC_H
=> undef,
366 HAVE_SYS_PERSONALITY_H
=> undef,
367 HAVE_SYS_PRCTL_H
=> undef,
368 HAVE_SYS_PROCCTL_H
=> undef,
369 HAVE_SYS_RESOURCE_H
=> undef,
370 HAVE_SYS_SELECT_H
=> undef,
371 HAVE_SYS_SEM_H
=> undef,
372 HAVE_SYS_SHM_H
=> undef,
373 HAVE_SYS_SIGNALFD_H
=> undef,
374 HAVE_SYS_SOCKIO_H
=> undef,
375 HAVE_SYS_STAT_H
=> 1,
376 HAVE_SYS_TYPES_H
=> 1,
377 HAVE_SYS_UCRED_H
=> undef,
378 HAVE_SYS_UIO_H
=> undef,
379 HAVE_SYS_UN_H
=> undef,
380 HAVE_TERMIOS_H
=> undef,
381 HAVE_TYPEOF
=> undef,
382 HAVE_UCRED_H
=> undef,
383 HAVE_UINT64
=> undef,
385 HAVE_UNION_SEMUN
=> undef,
387 HAVE_USELOCALE
=> undef,
388 HAVE_UUID_BSD
=> undef,
389 HAVE_UUID_E2FS
=> undef,
390 HAVE_UUID_OSSP
=> undef,
391 HAVE_UUID_H
=> undef,
392 HAVE_UUID_UUID_H
=> undef,
393 HAVE_WINLDAP_H
=> undef,
394 HAVE_WCSTOMBS_L
=> 1,
395 HAVE_VISIBILITY_ATTRIBUTE
=> undef,
396 HAVE_X509_GET_SIGNATURE_NID
=> 1,
397 HAVE_X86_64_POPCNTQ
=> undef,
399 HAVE__BUILTIN_BSWAP16
=> undef,
400 HAVE__BUILTIN_BSWAP32
=> undef,
401 HAVE__BUILTIN_BSWAP64
=> undef,
402 HAVE__BUILTIN_CLZ
=> undef,
403 HAVE__BUILTIN_CONSTANT_P
=> undef,
404 HAVE__BUILTIN_CTZ
=> undef,
405 HAVE__BUILTIN_FRAME_ADDRESS
=> undef,
406 HAVE__BUILTIN_OP_OVERFLOW
=> undef,
407 HAVE__BUILTIN_POPCOUNT
=> undef,
408 HAVE__BUILTIN_TYPES_COMPATIBLE_P
=> undef,
409 HAVE__BUILTIN_UNREACHABLE
=> undef,
410 HAVE__CONFIGTHREADLOCALE
=> 1,
412 HAVE__GET_CPUID
=> undef,
413 HAVE__STATIC_ASSERT
=> undef,
414 INT64_MODIFIER
=> qq{"ll"},
415 LOCALE_T_IN_XLOCALE
=> undef,
416 MAXIMUM_ALIGNOF
=> 8,
417 MEMSET_LOOP_LIMIT
=> 1024,
418 OPENSSL_API_COMPAT
=> $openssl_api_compat,
419 PACKAGE_BUGREPORT
=> qq{"$package_bugreport"},
420 PACKAGE_NAME
=> qq{"$package_name"},
421 PACKAGE_STRING
=> qq{"$package_name $package_version"},
422 PACKAGE_TARNAME
=> lc qq{"$package_name"},
423 PACKAGE_URL
=> qq{"$package_url"},
424 PACKAGE_VERSION
=> qq{"$package_version"},
425 PG_INT128_TYPE
=> undef,
426 PG_INT64_TYPE
=> 'long long int',
427 PG_KRB_SRVNAM
=> qq{"postgres"},
428 PG_MAJORVERSION
=> qq{"$majorver"},
429 PG_MAJORVERSION_NUM
=> $majorver,
430 PG_MINORVERSION_NUM
=> $minorver,
431 PG_PRINTF_ATTRIBUTE
=> undef,
433 PG_VERSION
=> qq{"$package_version$extraver"},
434 PG_VERSION_NUM
=> sprintf("%d%04d", $majorver, $minorver),
436 qq{"PostgreSQL $package_version$extraver, compiled by Visual C++ build " CppAsString2
(_MSC_VER
) ", $bits-bit"},
437 PROFILE_PID_DIR
=> undef,
438 PTHREAD_CREATE_JOINABLE
=> undef,
439 RELSEG_SIZE
=> (1024 / $self->{options
}->{blocksize
}) *
440 $self->{options
}->{segsize
} * 1024,
443 SIZEOF_OFF_T
=> undef,
444 SIZEOF_SIZE_T
=> $bits / 8,
445 SIZEOF_VOID_P
=> $bits / 8,
447 STRERROR_R_INT
=> undef,
448 USE_ARMV8_CRC32C
=> undef,
449 USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK
=> undef,
450 USE_ASSERT_CHECKING
=> $self->{options
}->{asserts
} ?
1 : undef,
451 USE_BONJOUR
=> undef,
452 USE_BSD_AUTH
=> undef,
453 USE_ICU
=> $self->{options
}->{icu
} ?
1 : undef,
455 USE_LIBXSLT
=> undef,
457 USE_LDAP
=> $self->{options
}->{ldap
} ?
1 : undef,
459 USE_NAMED_POSIX_SEMAPHORES
=> undef,
460 USE_OPENSSL
=> undef,
462 USE_SLICING_BY_8_CRC32C
=> undef,
463 USE_SSE42_CRC32C
=> undef,
464 USE_SSE42_CRC32C_WITH_RUNTIME_CHECK
=> 1,
465 USE_SYSTEMD
=> undef,
466 USE_SYSV_SEMAPHORES
=> undef,
467 USE_SYSV_SHARED_MEMORY
=> undef,
468 USE_UNNAMED_POSIX_SEMAPHORES
=> undef,
469 USE_WIN32_SEMAPHORES
=> 1,
470 USE_WIN32_SHARED_MEMORY
=> 1,
472 WCSTOMBS_L_IN_XLOCALE
=> undef,
473 WORDS_BIGENDIAN
=> undef,
474 XLOG_BLCKSZ
=> 1024 * $self->{options
}->{wal_blocksize
},
475 _FILE_OFFSET_BITS
=> undef,
476 _LARGEFILE_SOURCE
=> undef,
477 _LARGE_FILES
=> undef,
478 inline
=> '__inline',
479 pg_restrict
=> '__restrict',
480 # not defined, because it'd conflict with __declspec(restrict)
484 if ($self->{options
}->{uuid
})
486 $define{HAVE_UUID_OSSP
} = 1;
487 $define{HAVE_UUID_H
} = 1;
489 if ($self->{options
}->{xml
})
491 $define{HAVE_LIBXML2
} = 1;
492 $define{USE_LIBXML
} = 1;
494 if ($self->{options
}->{xslt
})
496 $define{HAVE_LIBXSLT
} = 1;
497 $define{USE_LIBXSLT
} = 1;
499 if ($self->{options
}->{lz4
})
501 $define{HAVE_LIBLZ4
} = 1;
502 $define{USE_LZ4
} = 1;
504 if ($self->{options
}->{zstd
})
506 $define{HAVE_LIBZSTD
} = 1;
507 $define{USE_ZSTD
} = 1;
509 if ($self->{options
}->{openssl
})
511 $define{USE_OPENSSL
} = 1;
513 my ($digit1, $digit2, $digit3) = $self->GetOpenSSLVersion();
515 # More symbols are needed with OpenSSL 1.1.0 and above.
516 if ( ($digit1 >= '3' && $digit2 >= '0' && $digit3 >= '0')
517 || ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0'))
519 $define{HAVE_ASN1_STRING_GET0_DATA
} = 1;
520 $define{HAVE_BIO_GET_DATA
} = 1;
521 $define{HAVE_BIO_METH_NEW
} = 1;
522 $define{HAVE_HMAC_CTX_FREE
} = 1;
523 $define{HAVE_HMAC_CTX_NEW
} = 1;
524 $define{HAVE_OPENSSL_INIT_SSL
} = 1;
528 $self->GenerateConfigHeader('src/include/pg_config.h', \
%define, 1);
529 $self->GenerateConfigHeader('src/include/pg_config_ext.h', \
%define, 0);
530 $self->GenerateConfigHeader('src/interfaces/ecpg/include/ecpg_config.h',
533 $self->GenerateDefFile(
534 "src/interfaces/libpq/libpqdll.def",
535 "src/interfaces/libpq/exports.txt",
537 $self->GenerateDefFile(
538 "src/interfaces/ecpg/ecpglib/ecpglib.def",
539 "src/interfaces/ecpg/ecpglib/exports.txt",
541 $self->GenerateDefFile(
542 "src/interfaces/ecpg/compatlib/compatlib.def",
543 "src/interfaces/ecpg/compatlib/exports.txt",
545 $self->GenerateDefFile(
546 "src/interfaces/ecpg/pgtypeslib/pgtypeslib.def",
547 "src/interfaces/ecpg/pgtypeslib/exports.txt",
550 chdir('src/backend/utils');
551 my $pg_proc_dat = '../../../src/include/catalog/pg_proc.dat';
552 if ( IsNewer
('fmgr-stamp', 'Gen_fmgrtab.pl')
553 || IsNewer
('fmgr-stamp', '../catalog/Catalog.pm')
554 || IsNewer
('fmgr-stamp', $pg_proc_dat)
555 || IsNewer
('fmgr-stamp', '../../../src/include/access/transam.h'))
558 "perl -I ../catalog Gen_fmgrtab.pl --include-path ../../../src/include/ $pg_proc_dat"
560 open(my $f, '>', 'fmgr-stamp')
561 || confess
"Could not touch fmgr-stamp";
567 'src/include/utils/fmgroids.h',
568 'src/backend/utils/fmgroids.h'))
570 copyFile
('src/backend/utils/fmgroids.h',
571 'src/include/utils/fmgroids.h');
575 'src/include/utils/fmgrprotos.h',
576 'src/backend/utils/fmgrprotos.h'))
579 'src/backend/utils/fmgrprotos.h',
580 'src/include/utils/fmgrprotos.h');
584 'src/include/storage/lwlocknames.h',
585 'src/backend/storage/lmgr/lwlocknames.txt'))
587 print "Generating lwlocknames.c and lwlocknames.h...\n";
588 my $lmgr = 'src/backend/storage/lmgr';
589 system("perl $lmgr/generate-lwlocknames.pl --outdir $lmgr $lmgr/lwlocknames.txt");
592 'src/include/storage/lwlocknames.h',
593 'src/backend/storage/lmgr/lwlocknames.h'))
596 'src/backend/storage/lmgr/lwlocknames.h',
597 'src/include/storage/lwlocknames.h');
600 if (IsNewer
('src/include/utils/probes.h', 'src/backend/utils/probes.d'))
602 print "Generating probes.h...\n";
604 'perl src/backend/utils/Gen_dummy_probes.pl src/backend/utils/probes.d > src/include/utils/probes.h'
608 if ($self->{options
}->{python
}
610 'src/pl/plpython/spiexceptions.h',
611 'src/backend/utils/errcodes.txt'))
613 print "Generating spiexceptions.h...\n";
615 'perl src/pl/plpython/generate-spiexceptions.pl src/backend/utils/errcodes.txt > src/pl/plpython/spiexceptions.h'
620 'src/include/utils/errcodes.h',
621 'src/backend/utils/errcodes.txt'))
623 print "Generating errcodes.h...\n";
625 'perl src/backend/utils/generate-errcodes.pl --outfile src/backend/utils/errcodes.h src/backend/utils/errcodes.txt'
627 copyFile
('src/backend/utils/errcodes.h',
628 'src/include/utils/errcodes.h');
632 'src/pl/plpgsql/src/plerrcodes.h',
633 'src/backend/utils/errcodes.txt'))
635 print "Generating plerrcodes.h...\n";
637 'perl src/pl/plpgsql/src/generate-plerrcodes.pl src/backend/utils/errcodes.txt > src/pl/plpgsql/src/plerrcodes.h'
641 if ($self->{options
}->{tcl
}
643 'src/pl/tcl/pltclerrcodes.h', 'src/backend/utils/errcodes.txt'))
645 print "Generating pltclerrcodes.h...\n";
647 'perl src/pl/tcl/generate-pltclerrcodes.pl src/backend/utils/errcodes.txt > src/pl/tcl/pltclerrcodes.h'
651 if (IsNewer
('src/bin/psql/sql_help.h', 'src/bin/psql/create_help.pl'))
653 print "Generating sql_help.h...\n";
654 my $psql = 'src/bin/psql';
655 system("perl $psql/create_help.pl --docdir doc/src/sgml/ref --outdir $psql --basename sql_help");
658 if (IsNewer
('src/common/kwlist_d.h', 'src/include/parser/kwlist.h'))
660 print "Generating kwlist_d.h...\n";
662 'perl -I src/tools src/tools/gen_keywordlist.pl --extern -o src/common src/include/parser/kwlist.h'
667 'src/pl/plpgsql/src/pl_reserved_kwlist_d.h',
668 'src/pl/plpgsql/src/pl_reserved_kwlist.h')
670 'src/pl/plpgsql/src/pl_unreserved_kwlist_d.h',
671 'src/pl/plpgsql/src/pl_unreserved_kwlist.h'))
674 "Generating pl_reserved_kwlist_d.h and pl_unreserved_kwlist_d.h...\n";
675 chdir('src/pl/plpgsql/src');
677 'perl -I ../../../tools ../../../tools/gen_keywordlist.pl --varname ReservedPLKeywords pl_reserved_kwlist.h'
680 'perl -I ../../../tools ../../../tools/gen_keywordlist.pl --varname UnreservedPLKeywords pl_unreserved_kwlist.h'
682 chdir('../../../..');
686 'src/interfaces/ecpg/preproc/c_kwlist_d.h',
687 'src/interfaces/ecpg/preproc/c_kwlist.h')
689 'src/interfaces/ecpg/preproc/ecpg_kwlist_d.h',
690 'src/interfaces/ecpg/preproc/ecpg_kwlist.h'))
692 print "Generating c_kwlist_d.h and ecpg_kwlist_d.h...\n";
693 chdir('src/interfaces/ecpg/preproc');
695 'perl -I ../../../tools ../../../tools/gen_keywordlist.pl --varname ScanCKeywords --no-case-fold c_kwlist.h'
698 'perl -I ../../../tools ../../../tools/gen_keywordlist.pl --varname ScanECPGKeywords ecpg_kwlist.h'
700 chdir('../../../..');
704 'src/interfaces/ecpg/preproc/preproc.y',
705 'src/backend/parser/gram.y'))
707 print "Generating preproc.y...\n";
708 my $ecpg = 'src/interfaces/ecpg';
709 system("perl $ecpg/preproc/parse.pl --srcdir $ecpg/preproc --parser src/backend/parser/gram.y --output $ecpg/preproc/preproc.y");
712 unless (-f
"src/port/pg_config_paths.h")
714 print "Generating pg_config_paths.h...\n";
715 open(my $o, '>', 'src/port/pg_config_paths.h')
716 || confess
"Could not open pg_config_paths.h";
718 #define PGBINDIR "/bin"
719 #define PGSHAREDIR "/share"
720 #define SYSCONFDIR "/etc"
721 #define INCLUDEDIR "/include"
722 #define PKGINCLUDEDIR "/include"
723 #define INCLUDEDIRSERVER "/include/server"
724 #define LIBDIR "/lib"
725 #define PKGLIBDIR "/lib"
726 #define LOCALEDIR "/share/locale"
727 #define DOCDIR "/doc"
728 #define HTMLDIR "/doc"
729 #define MANDIR "/man"
734 my $mf = Project
::read_file
('src/backend/catalog/Makefile');
735 $mf =~ s{\\\r?\n}{}g;
736 $mf =~ /^CATALOG_HEADERS\s*:?=(.*)$/gm
737 || croak
"Could not find CATALOG_HEADERS in Makefile\n";
738 my @bki_srcs = split /\s+/, $1;
739 $mf =~ /^POSTGRES_BKI_DATA\s*:?=[^,]+,(.*)\)$/gm
740 || croak
"Could not find POSTGRES_BKI_DATA in Makefile\n";
741 my @bki_data = split /\s+/, $1;
744 foreach my $bki (@bki_srcs, @bki_data)
748 'src/backend/catalog/bki-stamp',
749 "src/include/catalog/$bki"))
756 if IsNewer
('src/backend/catalog/bki-stamp',
757 'src/backend/catalog/genbki.pl');
759 if IsNewer
('src/backend/catalog/bki-stamp',
760 'src/backend/catalog/Catalog.pm');
763 chdir('src/backend/catalog');
764 my $bki_srcs = join(' ../../../src/include/catalog/', @bki_srcs);
766 "perl genbki.pl --include-path ../../../src/include/ --set-version=$majorver $bki_srcs"
768 open(my $f, '>', 'bki-stamp')
769 || confess
"Could not touch bki-stamp";
775 'src/include/catalog/header-stamp',
776 'src/backend/catalog/bki-stamp'))
778 # Copy generated headers to include directory.
779 opendir(my $dh, 'src/backend/catalog/')
780 || die "Can't opendir src/backend/catalog/ $!";
781 my @def_headers = grep { /pg_\w+_d\.h$/ } readdir($dh);
783 foreach my $def_header (@def_headers)
786 "src/backend/catalog/$def_header",
787 "src/include/catalog/$def_header");
790 'src/backend/catalog/schemapg.h',
791 'src/include/catalog/schemapg.h');
793 'src/backend/catalog/system_fk_info.h',
794 'src/include/catalog/system_fk_info.h');
795 open(my $chs, '>', 'src/include/catalog/header-stamp')
796 || confess
"Could not touch header-stamp";
800 my $nmf = Project
::read_file
('src/backend/nodes/Makefile');
801 $nmf =~ s{\\\r?\n}{}g;
802 $nmf =~ /^node_headers\s*:?=(.*)$/gm
803 || croak
"Could not find node_headers in Makefile\n";
804 my @node_headers = split /\s+/, $1;
805 @node_headers = grep { $_ ne '' } @node_headers;
806 my @node_files = map { "src/include/$_" } @node_headers;
808 my $need_node_support = 0;
809 foreach my $nodefile (@node_files)
811 if (IsNewer
('src/backend/nodes/node-support-stamp', $nodefile))
813 $need_node_support = 1;
817 $need_node_support = 1
819 'src/backend/nodes/node-support-stamp',
820 'src/backend/nodes/gen_node_support.pl');
822 if ($need_node_support)
824 system("perl src/backend/nodes/gen_node_support.pl --outdir src/backend/nodes @node_files");
825 open(my $f, '>', 'src/backend/nodes/node-support-stamp')
826 || confess
"Could not touch node-support-stamp";
831 'src/include/nodes/nodetags.h',
832 'src/backend/nodes/nodetags.h'))
834 copyFile
('src/backend/nodes/nodetags.h',
835 'src/include/nodes/nodetags.h');
838 open(my $o, '>', "doc/src/sgml/version.sgml")
839 || croak
"Could not write to version.sgml\n";
841 <!ENTITY version "$package_version">
842 <!ENTITY majorversion "$majorver">
848 # Read lines from input file and substitute symbols using the same
849 # logic that config.status uses. There should be one call of this for
850 # each AC_CONFIG_HEADERS call in configure.ac.
852 # If the "required" argument is true, we also keep track which of our
853 # defines have been found and error out if any are left unused at the
854 # end. That way we avoid accumulating defines in this file that are
855 # no longer used by configure.
856 sub GenerateConfigHeader
858 my ($self, $config_header, $defines, $required) = @_;
860 my $config_header_in = $config_header . '.in';
862 if ( IsNewer
($config_header, $config_header_in)
863 || IsNewer
($config_header, __FILE__
))
865 my %defines_copy = %$defines;
867 open(my $i, '<', $config_header_in)
868 || confess
"Could not open $config_header_in\n";
869 open(my $o, '>', $config_header)
870 || confess
"Could not write to $config_header\n";
873 "/* $config_header. Generated from $config_header_in by src/tools/msvc/Solution.pm. */\n";
877 if (m/^#(\s*)undef\s+(\w+)/)
881 if (exists $defines->{$macro})
883 if (defined $defines->{$macro})
885 print $o "#${ws}define $macro ", $defines->{$macro},
890 print $o "/* #${ws}undef $macro */\n";
892 delete $defines_copy{$macro};
897 "undefined symbol: $macro at $config_header line $.";
908 if ($required && scalar(keys %defines_copy) > 0)
910 croak
"unused defines: " . join(' ', keys %defines_copy);
917 my ($self, $deffile, $txtfile, $libname) = @_;
919 if (IsNewer
($deffile, $txtfile))
921 print "Generating $deffile...\n";
922 open(my $if, '<', $txtfile) || confess
("Could not open $txtfile\n");
923 open(my $of, '>', $deffile) || confess
("Could not open $deffile\n");
924 print $of "LIBRARY $libname\nEXPORTS\n";
930 print $of " $f @ $o\n";
940 my ($self, $name, $type, $folder, $initialdir) = @_;
943 VSObjectFactory
::CreateProject
($self->{vcver
}, $name, $type, $self);
944 push @
{ $self->{projects
}->{$folder} }, $proj;
945 $proj->AddDir($initialdir) if ($initialdir);
946 if ($self->{options
}->{zlib
})
948 $proj->AddIncludeDir($self->{options
}->{zlib
} . '\include');
949 $proj->AddLibrary($self->{options
}->{zlib
} . '\lib\zdll.lib');
951 if ($self->{options
}->{openssl
})
953 $proj->AddIncludeDir($self->{options
}->{openssl
} . '\include');
954 my ($digit1, $digit2, $digit3) = $self->GetOpenSSLVersion();
956 # Starting at version 1.1.0 the OpenSSL installers have
957 # changed their library names from:
958 # - libeay to libcrypto
960 if ( ($digit1 >= '3' && $digit2 >= '0' && $digit3 >= '0')
961 || ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0'))
967 # The format name of the libraries is slightly
968 # different between the Win32 and Win64 platform, so
970 if (-e
"$self->{options}->{openssl}/lib/VC/sslcrypto32MD.lib")
972 # Win32 here, with a debugging library set.
974 $libsslpath = '\lib\VC\libssl32.lib';
975 $libcryptopath = '\lib\VC\libcrypto32.lib';
977 elsif (-e
"$self->{options}->{openssl}/lib/VC/sslcrypto64MD.lib")
979 # Win64 here, with a debugging library set.
981 $libsslpath = '\lib\VC\libssl64.lib';
982 $libcryptopath = '\lib\VC\libcrypto64.lib';
986 # On both Win32 and Win64 the same library
987 # names are used without a debugging context.
989 $libsslpath = '\lib\libssl.lib';
990 $libcryptopath = '\lib\libcrypto.lib';
993 $proj->AddLibrary($self->{options
}->{openssl
} . $libsslpath,
995 $proj->AddLibrary($self->{options
}->{openssl
} . $libcryptopath,
1000 # Choose which set of libraries to use depending on if
1001 # debugging libraries are in place in the installer.
1002 if (-e
"$self->{options}->{openssl}/lib/VC/ssleay32MD.lib")
1005 $self->{options
}->{openssl
} . '\lib\VC\ssleay32.lib', 1);
1007 $self->{options
}->{openssl
} . '\lib\VC\libeay32.lib', 1);
1011 # We don't expect the config-specific library
1012 # to be here, so don't ask for it in last
1015 $self->{options
}->{openssl
} . '\lib\ssleay32.lib', 0);
1017 $self->{options
}->{openssl
} . '\lib\libeay32.lib', 0);
1021 if ($self->{options
}->{nls
})
1023 $proj->AddIncludeDir($self->{options
}->{nls
} . '\include');
1024 $proj->AddLibrary($self->{options
}->{nls
} . '\lib\libintl.lib');
1026 if ($self->{options
}->{gss
})
1028 $proj->AddIncludeDir($self->{options
}->{gss
} . '\include');
1029 $proj->AddIncludeDir($self->{options
}->{gss
} . '\include\krb5');
1030 if ($self->{platform
} eq 'Win32')
1033 $self->{options
}->{gss
} . '\lib\i386\krb5_32.lib');
1035 $self->{options
}->{gss
} . '\lib\i386\comerr32.lib');
1037 $self->{options
}->{gss
} . '\lib\i386\gssapi32.lib');
1042 $self->{options
}->{gss
} . '\lib\amd64\krb5_64.lib');
1044 $self->{options
}->{gss
} . '\lib\amd64\comerr64.lib');
1046 $self->{options
}->{gss
} . '\lib\amd64\gssapi64.lib');
1049 if ($self->{options
}->{iconv
})
1051 $proj->AddIncludeDir($self->{options
}->{iconv
} . '\include');
1052 $proj->AddLibrary($self->{options
}->{iconv
} . '\lib\iconv.lib');
1054 if ($self->{options
}->{icu
})
1056 $proj->AddIncludeDir($self->{options
}->{icu
} . '\include');
1057 if ($self->{platform
} eq 'Win32')
1059 $proj->AddLibrary($self->{options
}->{icu
} . '\lib\icuin.lib');
1060 $proj->AddLibrary($self->{options
}->{icu
} . '\lib\icuuc.lib');
1061 $proj->AddLibrary($self->{options
}->{icu
} . '\lib\icudt.lib');
1065 $proj->AddLibrary($self->{options
}->{icu
} . '\lib64\icuin.lib');
1066 $proj->AddLibrary($self->{options
}->{icu
} . '\lib64\icuuc.lib');
1067 $proj->AddLibrary($self->{options
}->{icu
} . '\lib64\icudt.lib');
1070 if ($self->{options
}->{xml
})
1072 $proj->AddIncludeDir($self->{options
}->{xml
} . '\include');
1073 $proj->AddIncludeDir($self->{options
}->{xml
} . '\include\libxml2');
1074 $proj->AddLibrary($self->{options
}->{xml
} . '\lib\libxml2.lib');
1076 if ($self->{options
}->{xslt
})
1078 $proj->AddIncludeDir($self->{options
}->{xslt
} . '\include');
1079 $proj->AddLibrary($self->{options
}->{xslt
} . '\lib\libxslt.lib');
1081 if ($self->{options
}->{lz4
})
1083 $proj->AddIncludeDir($self->{options
}->{lz4
} . '\include');
1084 $proj->AddLibrary($self->{options
}->{lz4
} . '\lib\liblz4.lib');
1086 if ($self->{options
}->{zstd
})
1088 $proj->AddIncludeDir($self->{options
}->{zstd
} . '\include');
1089 $proj->AddLibrary($self->{options
}->{zstd
} . '\lib\libzstd.lib');
1091 if ($self->{options
}->{uuid
})
1093 $proj->AddIncludeDir($self->{options
}->{uuid
} . '\include');
1094 $proj->AddLibrary($self->{options
}->{uuid
} . '\lib\uuid.lib');
1104 $self->GenerateFiles();
1105 foreach my $fld (keys %{ $self->{projects
} })
1107 foreach my $proj (@
{ $self->{projects
}->{$fld} })
1113 open(my $sln, '>', "pgsql.sln") || croak
"Could not write to pgsql.sln\n";
1115 Microsoft Visual Studio Solution File, Format Version $self->{solutionFileVersion}
1116 # $self->{visualStudioName}
1119 print $sln $self->GetAdditionalHeaders();
1121 foreach my $fld (keys %{ $self->{projects
} })
1123 foreach my $proj (@
{ $self->{projects
}->{$fld} })
1126 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "$proj->{name}", "$proj->{name}$proj->{filenameExtension}", "$proj->{guid}"
1132 $flduid{$fld} = $^O
eq "MSWin32" ? Win32
::GuidGen
() : 'FAKE';
1134 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "$fld", "$fld", "$flduid{$fld}"
1142 GlobalSection(SolutionConfigurationPlatforms) = preSolution
1143 Debug|$self->{platform}= Debug|$self->{platform}
1144 Release|$self->{platform} = Release|$self->{platform}
1146 GlobalSection(ProjectConfigurationPlatforms) = postSolution
1149 foreach my $fld (keys %{ $self->{projects
} })
1151 foreach my $proj (@
{ $self->{projects
}->{$fld} })
1154 $proj->{guid}.Debug|$self->{platform}.ActiveCfg = Debug|$self->{platform}
1155 $proj->{guid}.Debug|$self->{platform}.Build.0 = Debug|$self->{platform}
1156 $proj->{guid}.Release|$self->{platform}.ActiveCfg = Release|$self->{platform}
1157 $proj->{guid}.Release|$self->{platform}.Build.0 = Release|$self->{platform}
1164 GlobalSection(SolutionProperties) = preSolution
1165 HideSolutionNode = FALSE
1167 GlobalSection(NestedProjects) = preSolution
1170 foreach my $fld (keys %{ $self->{projects
} })
1172 next if ($fld eq "");
1173 foreach my $proj (@
{ $self->{projects
}->{$fld} })
1175 print $sln "\t\t$proj->{guid} = $flduid{$fld}\n";
1187 sub GetFakeConfigure
1191 my $cfg = '--enable-thread-safety';
1192 $cfg .= ' --enable-cassert' if ($self->{options
}->{asserts
});
1193 $cfg .= ' --enable-nls' if ($self->{options
}->{nls
});
1194 $cfg .= ' --enable-tap-tests' if ($self->{options
}->{tap_tests
});
1195 $cfg .= ' --with-ldap' if ($self->{options
}->{ldap
});
1196 $cfg .= ' --without-zlib' unless ($self->{options
}->{zlib
});
1197 $cfg .= ' --with-extra-version' if ($self->{options
}->{extraver
});
1198 $cfg .= ' --with-ssl=openssl' if ($self->{options
}->{openssl
});
1199 $cfg .= ' --with-uuid' if ($self->{options
}->{uuid
});
1200 $cfg .= ' --with-libxml' if ($self->{options
}->{xml
});
1201 $cfg .= ' --with-libxslt' if ($self->{options
}->{xslt
});
1202 $cfg .= ' --with-lz4' if ($self->{options
}->{lz4
});
1203 $cfg .= ' --with-zstd' if ($self->{options
}->{zstd
});
1204 $cfg .= ' --with-gssapi' if ($self->{options
}->{gss
});
1205 $cfg .= ' --with-icu' if ($self->{options
}->{icu
});
1206 $cfg .= ' --with-tcl' if ($self->{options
}->{tcl
});
1207 $cfg .= ' --with-perl' if ($self->{options
}->{perl
});
1208 $cfg .= ' --with-python' if ($self->{options
}->{python
});
1209 my $port = $self->{options
}->{'--with-pgport'};
1210 $cfg .= " --with-pgport=$port" if defined($port);
1215 package VS2015Solution
;
1218 # Package that encapsulates a Visual Studio 2015 solution file
1224 use base
qw(Solution);
1226 no warnings
qw(redefine); ## no critic
1230 my $classname = shift;
1231 my $self = $classname->SUPER::_new
(@_);
1232 bless($self, $classname);
1234 $self->{solutionFileVersion
} = '12.00';
1235 $self->{vcver
} = '14.00';
1236 $self->{visualStudioName
} = 'Visual Studio 2015';
1237 $self->{VisualStudioVersion
} = '14.0.24730.2';
1238 $self->{MinimumVisualStudioVersion
} = '10.0.40219.1';
1243 package VS2017Solution
;
1246 # Package that encapsulates a Visual Studio 2017 solution file
1252 use base
qw(Solution);
1254 no warnings
qw(redefine); ## no critic
1258 my $classname = shift;
1259 my $self = $classname->SUPER::_new
(@_);
1260 bless($self, $classname);
1262 $self->{solutionFileVersion
} = '12.00';
1263 $self->{vcver
} = '15.00';
1264 $self->{visualStudioName
} = 'Visual Studio 2017';
1265 $self->{VisualStudioVersion
} = '15.0.26730.3';
1266 $self->{MinimumVisualStudioVersion
} = '10.0.40219.1';
1271 package VS2019Solution
;
1274 # Package that encapsulates a Visual Studio 2019 solution file
1280 use base
qw(Solution);
1282 no warnings
qw(redefine); ## no critic
1286 my $classname = shift;
1287 my $self = $classname->SUPER::_new
(@_);
1288 bless($self, $classname);
1290 $self->{solutionFileVersion
} = '12.00';
1291 $self->{vcver
} = '16.00';
1292 $self->{visualStudioName
} = 'Visual Studio 2019';
1293 $self->{VisualStudioVersion
} = '16.0.28729.10';
1294 $self->{MinimumVisualStudioVersion
} = '10.0.40219.1';
1299 package VS2022Solution
;
1302 # Package that encapsulates a Visual Studio 2022 solution file
1308 use base
qw(Solution);
1310 no warnings
qw(redefine); ## no critic
1314 my $classname = shift;
1315 my $self = $classname->SUPER::_new
(@_);
1316 bless($self, $classname);
1318 $self->{solutionFileVersion
} = '12.00';
1319 $self->{vcver
} = '17.00';
1320 $self->{visualStudioName
} = 'Visual Studio 2022';
1321 $self->{VisualStudioVersion
} = '17.0.31903.59';
1322 $self->{MinimumVisualStudioVersion
} = '10.0.40219.1';
1327 sub GetAdditionalHeaders
1329 my ($self, $f) = @_;
1331 return qq|VisualStudioVersion
= $self->{VisualStudioVersion
}
1332 MinimumVisualStudioVersion
= $self->{MinimumVisualStudioVersion
}