From 08bb6185615483a6c3afc13230c62f38c5f2f0fc Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Sat, 17 Mar 2007 13:50:42 +0000 Subject: [PATCH] Turn most vc build scripts into modules instead of scripts, and just have skeleton scripts calling them. To make it easier for the buildfarm (or other "outside callers") to use these modules directly. Per suggestion from Andrew Dunstan. --- src/tools/msvc/Genbki.pm | 264 ++++++++++++++++++++ src/tools/msvc/Install.pm | 208 ++++++++++++++++ src/tools/msvc/Mkvcbuild.pm | 455 +++++++++++++++++++++++++++++++++++ src/tools/msvc/README | 2 +- src/tools/msvc/Solution.pm | 9 +- src/tools/msvc/install.pl | 193 +-------------- src/tools/msvc/mkvcbuild.pl | 432 +-------------------------------- src/tools/msvc/vcregress.bat | 2 + 8 files changed, 943 insertions(+), 622 deletions(-) create mode 100644 src/tools/msvc/Genbki.pm create mode 100644 src/tools/msvc/Install.pm create mode 100644 src/tools/msvc/Mkvcbuild.pm diff --git a/src/tools/msvc/Genbki.pm b/src/tools/msvc/Genbki.pm new file mode 100644 index 0000000000..20a9881078 --- /dev/null +++ b/src/tools/msvc/Genbki.pm @@ -0,0 +1,264 @@ +#!/usr/bin/perl +#------------------------------------------------------------------------- +# +# Genbki.pm -- +# perl script which generates .bki files from specially formatted .h +# files. These .bki files are used to initialize the postgres template +# database. +# +# Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group +# Portions Copyright (c) 1994, Regents of the University of California +# +# +# IDENTIFICATION +# $PostgreSQL: pgsql/src/tools/msvc/Genbki.pm,v 1.1 2007/03/17 13:50:42 mha Exp $ +# +#------------------------------------------------------------------------- + +package Genbki; + +use strict; +use warnings; + +use Exporter; +our (@ISA, @EXPORT_OK); +@ISA = qw(Exporter); +@EXPORT_OK = qw(genbki); + +sub genbki +{ + my $version = shift; + my $prefix = shift; + + $version =~ /^(\d+\.\d+)/ || die "Bad format verison $version\n"; + my $majorversion = $1; + + my $pgext = read_file("src/include/pg_config_manual.h"); + $pgext =~ /^#define\s+NAMEDATALEN\s+(\d+)$/mg + || die "Could not read NAMEDATALEN from pg_config_manual.h\n"; + my $namedatalen = $1; + + my $pgauthid = read_file("src/include/catalog/pg_authid.h"); + $pgauthid =~ /^#define\s+BOOTSTRAP_SUPERUSERID\s+(\d+)$/mg + || die "Could not read BOOTSTRAUP_SUPERUSERID from pg_authid.h\n"; + my $bootstrapsuperuserid = $1; + + my $pgnamespace = read_file("src/include/catalog/pg_namespace.h"); + $pgnamespace =~ /^#define\s+PG_CATALOG_NAMESPACE\s+(\d+)$/mg + || die "Could not read PG_CATALOG_NAMESPACE from pg_namespace.h\n"; + my $pgcatalognamespace = $1; + + my $indata = ""; + + while (@_) + { + my $f = shift; + next unless $f; + $indata .= read_file($f); + $indata .= "\n"; + } + + # Strip C comments, from perl FAQ 4.27 + $indata =~ s{/\*.*?\*/}{}gs; + + $indata =~ s{;\s*$}{}gm; + $indata =~ s{^\s+}{}gm; + $indata =~ s{^Oid}{oid}gm; + $indata =~ s{\(Oid}{(oid}gm; + $indata =~ s{^NameData}{name}gm; + $indata =~ s{\(NameData}{(name}g; + $indata =~ s{^TransactionId}{xid}gm; + $indata =~ s{\(TransactionId}{(xid}g; + $indata =~ s{PGUID}{$bootstrapsuperuserid}g; + $indata =~ s{NAMEDATALEN}{$namedatalen}g; + $indata =~ s{PGNSP}{$pgcatalognamespace}g; + + #print $indata; + + my $bki = ""; + my $desc = ""; + my $shdesc = ""; + + my $oid = 0; + my $catalog = 0; + my $reln_open = 0; + my $bootstrap = ""; + my $shared_relation = ""; + my $without_oids = ""; + my $nc = 0; + my $inside = 0; + my @attr; + my @types; + + foreach my $line (split /\n/, $indata) + { + if ($line =~ /^DATA\((.*)\)$/m) + { + my $data = $1; + my @fields = split /\s+/,$data; + if ($#fields >=4 && $fields[0] eq "insert" && $fields[1] eq "OID" && $fields[2] eq "=") + { + $oid = $fields[3]; + } + else + { + $oid = 0; + } + $data =~ s/\s{2,}/ /g; + $bki .= $data . "\n"; + } + elsif ($line =~ /^DESCR\("(.*)"\)$/m) + { + if ($oid != 0) + { + $desc .= sprintf("%d\t%s\t0\t%s\n", $oid, $catalog, $1); + } + } + elsif ($line =~ /^SHDESCR\("(.*)"\)$/m) + { + if ($oid != 0) + { + $shdesc .= sprintf("%d\t%s\t%s\n", $oid, $catalog, $1); + } + } + elsif ($line =~ /^DECLARE_(UNIQUE_)?INDEX\((.*)\)$/m) + { + if ($reln_open) + { + $bki .= "close $catalog\n"; + $reln_open = 0; + } + my $u = $1?" unique":""; + my @fields = split /,/,$2,3; + $fields[2] =~ s/\s{2,}/ /g; + $bki .= "declare$u index $fields[0] $fields[1] $fields[2]\n"; + } + elsif ($line =~ /^DECLARE_TOAST\((.*)\)$/m) + { + if ($reln_open) + { + $bki .= "close $catalog\n"; + $reln_open = 0; + } + my @fields = split /,/,$1; + $bki .= "declare toast $fields[1] $fields[2] on $fields[0]\n"; + } + elsif ($line =~ /^BUILD_INDICES/) + { + $bki .= "build indices\n"; + } + elsif ($line =~ /^CATALOG\((.*)\)(.*)$/m) + { + if ($reln_open) + { + $bki .= "close $catalog\n"; + $reln_open = 0; + } + my $rest = $2; + my @fields = split /,/,$1; + $catalog = $fields[0]; + $oid = $fields[1]; + $bootstrap=$shared_relation=$without_oids=""; + if ($rest =~ /BKI_BOOTSTRAP/) + { + $bootstrap = "bootstrap "; + } + if ($rest =~ /BKI_SHARED_RELATION/) + { + $shared_relation = "shared_relation "; + } + if ($rest =~ /BKI_WITHOUT_OIDS/) + { + $without_oids = "without_oids "; + } + $nc++; + $inside = 1; + next; + } + if ($inside==1) + { + next if ($line =~ /{/); + if ($line =~ /}/) + { + + # Last line + $bki .= "create $bootstrap$shared_relation$without_oids$catalog $oid\n (\n"; + my $first = 1; + for (my $i = 0; $i <= $#attr; $i++) + { + if ($first == 1) + { + $first = 0; + } + else + { + $bki .= ",\n"; + } + $bki .= " " . $attr[$i] . " = " . $types[$i]; + } + $bki .= "\n )\n"; + undef(@attr); + undef(@types); + $reln_open = 1; + $inside = 0; + if ($bootstrap eq "") + { + $bki .= "open $catalog\n"; + } + next; + } + + # inside catalog definition, so keep sucking up attributes + my @fields = split /\s+/,$line; + if ($fields[1] =~ /(.*)\[.*\]/) + { #Array attribute + push @attr, $1; + push @types, $fields[0] . '[]'; + } + else + { + push @attr, $fields[1]; + push @types, $fields[0]; + } + next; + } + } + if ($reln_open == 1) + { + $bki .= "close $catalog\n"; + } + + open(O,">$prefix.bki") || die "Could not write $prefix.bki\n"; + print O "# PostgreSQL $majorversion\n"; + print O $bki; + close(O); + open(O,">$prefix.description") || die "Could not write $prefix.description\n"; + print O $desc; + close(O); + open(O,">$prefix.shdescription") || die "Could not write $prefix.shdescription\n"; + print O $shdesc; + close(O); +} + +sub Usage +{ + print "Usage: genbki.pl [ ...]\n"; + exit(1); +} + +sub read_file +{ + my $filename = shift; + my $F; + my $t = $/; + + undef $/; + open($F, $filename) || die "Could not open file $filename\n"; + my $txt = <$F>; + close($F); + $/ = $t; + + return $txt; +} + +1; diff --git a/src/tools/msvc/Install.pm b/src/tools/msvc/Install.pm new file mode 100644 index 0000000000..0b7a9b1983 --- /dev/null +++ b/src/tools/msvc/Install.pm @@ -0,0 +1,208 @@ +package Install; + +use strict; +use warnings; +use Carp; +use File::Basename; +use File::Copy; + +use Exporter; +our (@ISA,@EXPORT_OK); +@ISA = qw(Exporter); +@EXPORT_OK = qw(Install); + +sub Install +{ + $| = 1; + + my $target = shift; + + chdir("../../..") if (-f "../../../configure"); + my $conf = ""; + if (-d "debug") + { + $conf = "debug"; + } + if (-d "release") + { + $conf = "release"; + } + die "Could not find debug or release binaries" if ($conf eq ""); + print "Installing for $conf\n"; + + EnsureDirectories($target, 'bin','lib','share','share/timezonesets'); + + CopySolutionOutput($conf, $target); + copy($target . '/lib/libpq.dll', $target . '/bin/libpq.dll'); + CopySetOfFiles('config files', "*.sample", $target . '/share/'); + CopySetOfFiles('timezone names', 'src\timezone\tznames\*.txt',$target . '/share/timezonesets/'); + CopyFiles( + 'timezone sets', + $target . '/share/timezonesets/', + 'src/timezone/tznames/', 'Default','Australia','India' + ); + CopySetOfFiles('BKI files', "src\\backend\\catalog\\postgres.*", $target .'/share/'); + CopySetOfFiles('SQL files', "src\\backend\\catalog\\*.sql", $target . '/share/'); + CopyFiles( + 'Information schema data', + $target . '/share/', + 'src/backend/catalog/', 'sql_features.txt' + ); + GenerateConversionScript($target); + GenerateTimezoneFiles($target,$conf); +} + +sub EnsureDirectories +{ + my $target = shift; + mkdir $target unless -d ($target); + while (my $d = shift) + { + mkdir $target . '/' . $d unless -d ($target . '/' . $d); + } +} + +sub CopyFiles +{ + my $what = shift; + my $target = shift; + my $basedir = shift; + + print "Copying $what"; + while (my $f = shift) + { + print "."; + $f = $basedir . $f; + die "No file $f\n" if (!-f $f); + copy($f, $target . basename($f)) + || croak "Could not copy $f to $target". basename($f). " to $target". basename($f) . "\n"; + } + print "\n"; +} + +sub CopySetOfFiles +{ + my $what = shift; + my $spec = shift; + my $target = shift; + my $D; + + print "Copying $what"; + open($D, "dir /b /s $spec |") || croak "Could not list $spec\n"; + while (<$D>) + { + chomp; + next if /regress/; # Skip temporary install in regression subdir + my $tgt = $target . basename($_); + print "."; + copy($_, $tgt) || croak "Could not copy $_: $!\n"; + } + close($D); + print "\n"; +} + +sub CopySolutionOutput +{ + my $conf = shift; + my $target = shift; + my $rem = qr{Project\("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"\) = "([^"]+)"}; + + my $sln = read_file("pgsql.sln") || croak "Could not open pgsql.sln\n"; + print "Copying build output files..."; + while ($sln =~ $rem) + { + my $pf = $1; + my $dir; + my $ext; + + $sln =~ s/$rem//; + + my $proj = read_file("$pf.vcproj") || croak "Could not open $pf.vcproj\n"; + if ($proj !~ qr{ConfigurationType="([^"]+)"}) + { + croak "Could not parse $pf.vcproj\n"; + } + if ($1 == 1) + { + $dir = "bin"; + $ext = "exe"; + } + elsif ($1 == 2) + { + $dir = "lib"; + $ext = "dll"; + } + else + { + + # Static lib, such as libpgport, only used internally during build, don't install + next; + } + copy("$conf\\$pf\\$pf.$ext","$target\\$dir\\$pf.$ext") || croak "Could not copy $pf.$ext\n"; + print "."; + } + print "\n"; +} + +sub GenerateConversionScript +{ + my $target = shift; + my $sql = ""; + my $F; + + print "Generating conversion proc script..."; + my $mf = read_file('src/backend/utils/mb/conversion_procs/Makefile'); + $mf =~ s{\\\s*[\r\n]+}{}mg; + $mf =~ /^CONVERSIONS\s*=\s*(.*)$/m + || die "Could not find CONVERSIONS line in conversions Makefile\n"; + my @pieces = split /\s+/,$1; + while ($#pieces > 0) + { + my $name = shift @pieces; + my $se = shift @pieces; + my $de = shift @pieces; + my $func = shift @pieces; + my $obj = shift @pieces; + $sql .= "-- $se --> $de\n"; + $sql .= +"CREATE OR REPLACE FUNCTION $func (INTEGER, INTEGER, CSTRING, INTERNAL, INTEGER) RETURNS VOID AS '\$libdir/$obj', '$func' LANGUAGE C STRICT;\n"; + $sql .= "DROP CONVERSION pg_catalog.$name;\n"; + $sql .= "CREATE DEFAULT CONVERSION pg_catalog.$name FOR '$se' TO '$de' FROM $func;\n"; + } + open($F,">$target/share/conversion_create.sql") + || die "Could not write to conversion_create.sql\n"; + print $F $sql; + close($F); + print "\n"; +} + +sub GenerateTimezoneFiles +{ + my $target = shift; + my $conf = shift; + my $mf = read_file("src/timezone/Makefile"); + $mf =~ s{\\\s*[\r\n]+}{}mg; + $mf =~ /^TZDATA\s*:?=\s*(.*)$/m || die "Could not find TZDATA row in timezone makefile\n"; + my @tzfiles = split /\s+/,$1; + unshift @tzfiles,''; + print "Generating timezone files..."; + system("$conf\\zic\\zic -d $target/share/timezone " . join(" src/timezone/data/", @tzfiles)); + print "\n"; +} + +sub read_file +{ + my $filename = shift; + my $F; + my $t = $/; + + undef $/; + open($F, $filename) || die "Could not open file $filename\n"; + my $txt = <$F>; + close($F); + $/ = $t; + + return $txt; +} + +1; diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm new file mode 100644 index 0000000000..84d5889ddd --- /dev/null +++ b/src/tools/msvc/Mkvcbuild.pm @@ -0,0 +1,455 @@ +package Mkvcbuild; + +use Carp; +use Win32; +use strict; +use warnings; +use Project; +use Solution; + +use Exporter; +our (@ISA, @EXPORT_OK); +@ISA = qw(Exporter); +@EXPORT_OK = qw(Mkvcbuild); + +my $solution; +my $libpgport; +my $postgres; +my $libpq; + +my $contrib_defines = {'refint' => 'REFINT_VERBOSE'}; +my @contrib_uselibpq = ('dblink', 'oid2name', 'pgbench', 'vacuumlo'); +my @contrib_uselibpgport = ('oid2name', 'pgbench', 'pg_standby', 'vacuumlo'); +my $contrib_extralibs = {'pgbench' => ['wsock32.lib']}; +my $contrib_extraincludes = {'tsearch2' => ['contrib/tsearch2']}; +my $contrib_extrasource = { + 'cube' => ['cubescan.l','cubeparse.y'], + 'seg' => ['segscan.l','segparse.y'] +}; +my @contrib_excludes = ('pgcrypto'); + +sub mkvcbuild +{ + our $config = shift; + + chdir('..\..\..') if (-d '..\msvc' && -d '..\..\..\src'); + die 'Must run from root or msvc directory' unless (-d 'src\tools\msvc' && -d 'src'); + + $solution = new Solution($config); + + our @pgportfiles = qw( + crypt.c fseeko.c getrusage.c inet_aton.c random.c srandom.c + unsetenv.c getaddrinfo.c gettimeofday.c kill.c open.c rand.c + snprintf.c strlcat.c strlcpy.c copydir.c dirmod.c exec.c noblock.c path.c pipe.c + pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c sprompt.c thread.c + getopt.c getopt_long.c dirent.c rint.c win32error.c); + + $libpgport = $solution->AddProject('libpgport','lib','misc'); + $libpgport->AddDefine('FRONTEND'); + $libpgport->AddFiles('src\port',@pgportfiles); + + $postgres = $solution->AddProject('postgres','exe','','src\backend'); + $postgres->AddIncludeDir('src\backend'); + $postgres->AddDir('src\backend\port\win32'); + $postgres->AddFile('src\backend\utils\fmgrtab.c'); + $postgres->ReplaceFile('src\backend\port\dynloader.c','src\backend\port\dynloader\win32.c'); + $postgres->ReplaceFile('src\backend\port\pg_sema.c','src\backend\port\win32_sema.c'); + $postgres->ReplaceFile('src\backend\port\pg_shmem.c','src\backend\port\sysv_shmem.c'); + $postgres->AddFiles('src\port',@pgportfiles); + $postgres->AddDir('src\timezone'); + $postgres->AddFiles('src\backend\parser','scan.l','gram.y'); + $postgres->AddFiles('src\backend\bootstrap','bootscanner.l','bootparse.y'); + $postgres->AddFiles('src\backend\utils\misc','guc-file.l'); + $postgres->AddDefine('BUILDING_DLL'); + $postgres->AddLibrary('wsock32.lib ws2_32.lib'); + $postgres->AddLibrary('wldap32.lib') if ($solution->{options}->{ldap}); + $postgres->FullExportDLL('postgres.lib'); + + my $plpgsql = $solution->AddProject('plpgsql','dll','PLs','src\pl\plpgsql\src'); + $plpgsql->AddFiles('src\pl\plpgsql\src','scan.l','gram.y'); + $plpgsql->AddReference($postgres); + + if ($solution->{options}->{perl}) + { + my $plperl = $solution->AddProject('plperl','dll','PLs','src\pl\plperl'); + $plperl->AddIncludeDir($solution->{options}->{perl} . '/lib/CORE'); + $plperl->AddDefine('PLPERL_HAVE_UID_GID'); + if (Solution::IsNewer('src\pl\plperl\SPI.c','src\pl\plperl\SPI.xs')) + { + print 'Building src\pl\plperl\SPI.c...' . "\n"; + system( $solution->{options}->{perl} + . '/bin/perl ' + . $solution->{options}->{perl} + . '/lib/ExtUtils/xsubpp -typemap ' + . $solution->{options}->{perl} + . '/lib/ExtUtils/typemap src\pl\plperl\SPI.xs >src\pl\plperl\SPI.c'); + if ((!(-f 'src\pl\plperl\SPI.c')) || -z 'src\pl\plperl\SPI.c') + { + unlink('src\pl\plperl\SPI.c'); # if zero size + die 'Failed to create SPI.c' . "\n"; + } + } + $plperl->AddReference($postgres); + $plperl->AddLibrary($solution->{options}->{perl} . '\lib\CORE\perl58.lib'); + } + + if ($solution->{options}->{python}) + { + my $plpython = $solution->AddProject('plpython','dll','PLs','src\pl\plpython'); + $plpython->AddIncludeDir($solution->{options}->{python} . '\include'); + $solution->{options}->{python} =~ /\\Python(\d{2})/i + || croak "Could not determine python version from path"; + $plpython->AddLibrary($solution->{options}->{python} . "\\Libs\\python$1.lib"); + $plpython->AddReference($postgres); + } + + if ($solution->{options}->{tcl}) + { + my $pltcl = $solution->AddProject('pltcl','dll','PLs','src\pl\tcl'); + $pltcl->AddIncludeDir($solution->{options}->{tcl} . '\include'); + $pltcl->AddReference($postgres); + $pltcl->AddLibrary($solution->{options}->{tcl} . '\lib\tcl84.lib'); + } + + $libpq = $solution->AddProject('libpq','dll','interfaces','src\interfaces\libpq'); + $libpq->AddDefine('FRONTEND'); + $libpq->AddIncludeDir('src\port'); + $libpq->AddLibrary('wsock32.lib'); + $libpq->AddLibrary('wldap32.lib') if ($solution->{options}->{ldap}); + $libpq->UseDef('src\interfaces\libpq\libpqdll.def'); + $libpq->ReplaceFile('src\interfaces\libpq\libpqrc.c','src\interfaces\libpq\libpq.rc'); + $libpq->AddReference($libpgport); + + my $pgtypes = + $solution->AddProject('libpgtypes','dll','interfaces','src\interfaces\ecpg\pgtypeslib'); + $pgtypes->AddDefine('FRONTEND'); + $pgtypes->AddReference($postgres,$libpgport); + $pgtypes->AddIncludeDir('src\interfaces\ecpg\include'); + + if ($config->{pthread}) + { + my $libecpg = + $solution->AddProject('libecpg','dll','interfaces','src\interfaces\ecpg\ecpglib'); + $libecpg->AddDefine('FRONTEND'); + $libecpg->AddIncludeDir('src\interfaces\ecpg\include'); + $libecpg->AddIncludeDir('src\interfaces\libpq'); + $libecpg->AddIncludeDir('src\port'); + $libecpg->AddLibrary('wsock32.lib'); + $libecpg->AddLibrary($config->{'pthread'} . '\pthreadVC2.lib'); + $libecpg->AddReference($libpq,$pgtypes); + + my $libecpgcompat = + $solution->AddProject('libecpg_compat','dll','interfaces', + 'src\interfaces\ecpg\compatlib'); + $libecpgcompat->AddIncludeDir('src\interfaces\ecpg\include'); + $libecpgcompat->AddIncludeDir('src\interfaces\libpq'); + $libecpgcompat->AddReference($pgtypes,$libecpg); + + my $ecpg = $solution->AddProject('ecpg','exe','interfaces','src\interfaces\ecpg\preproc'); + $ecpg->AddIncludeDir('src\interfaces\ecpg\include'); + $ecpg->AddIncludeDir('src\interfaces\libpq'); + $ecpg->AddFiles('src\interfaces\ecpg\preproc','pgc.l','preproc.y'); + $ecpg->AddDefine('MAJOR_VERSION=4'); + $ecpg->AddDefine('MINOR_VERSION=2'); + $ecpg->AddDefine('PATCHLEVEL=1'); + $ecpg->AddReference($libpgport); + } + else + { + print "Not building ecpg due to lack of pthreads.\n"; + } + + # src/bin + my $initdb = AddSimpleFrontend('initdb', 1); + + my $pgconfig = AddSimpleFrontend('pg_config'); + + my $pgcontrol = AddSimpleFrontend('pg_controldata'); + + my $pgctl = AddSimpleFrontend('pg_ctl', 1); + + my $pgreset = AddSimpleFrontend('pg_resetxlog'); + + my $pgevent = $solution->AddProject('pgevent','dll','bin'); + $pgevent->AddFiles('src\bin\pgevent','pgevent.c','pgmsgevent.rc'); + $pgevent->AddResourceFile('src\bin\pgevent','Eventlog message formatter'); + $pgevent->RemoveFile('src\bin\pgevent\win32ver.rc'); + $pgevent->UseDef('src\bin\pgevent\pgevent.def'); + $pgevent->DisableLinkerWarnings('4104'); + + my $psql = AddSimpleFrontend('psql', 1); + $psql->AddIncludeDir('src\bin\pg_dump'); + $psql->AddFile('src\bin\psql\psqlscan.l'); + + my $pgdump = AddSimpleFrontend('pg_dump', 1); + $pgdump->AddFile('src\bin\pg_dump\pg_dump.c'); + $pgdump->AddFile('src\bin\pg_dump\common.c'); + $pgdump->AddFile('src\bin\pg_dump\pg_dump_sort.c'); + + my $pgdumpall = AddSimpleFrontend('pg_dump', 1); + $pgdumpall->{name} = 'pg_dumpall'; + $pgdumpall->AddFile('src\bin\pg_dump\pg_dumpall.c'); + + my $pgrestore = AddSimpleFrontend('pg_dump', 1); + $pgrestore->{name} = 'pg_restore'; + $pgrestore->AddFile('src\bin\pg_dump\pg_restore.c'); + + my $zic = $solution->AddProject('zic','exe','utils'); + $zic->AddFiles('src\timezone','zic.c','ialloc.c','scheck.c','localtime.c'); + $zic->AddReference($libpgport); + + if ($solution->{options}->{xml}) + { + $contrib_extraincludes->{'xml2'} = [ + $solution->{options}->{xml} . '\include', + $solution->{options}->{xslt} . '\include', + $solution->{options}->{iconv} . '\include' + ]; + + $contrib_extralibs->{'xml2'} = [ + $solution->{options}->{xml} . '\lib\libxml2.lib', + $solution->{options}->{xslt} . '\lib\libxslt.lib' + ]; + } + else + { + push @contrib_excludes,'xml2'; + } + + if (!$solution->{options}->{openssl}) + { + push @contrib_excludes,'sslinfo'; + } + + # Pgcrypto makefile too complex to parse.... + my $pgcrypto = $solution->AddProject('pgcrypto','dll','crypto'); + $pgcrypto->AddFiles( + 'contrib\pgcrypto','pgcrypto.c','px.c','px-hmac.c', + 'px-crypt.c','crypt-gensalt.c','crypt-blowfish.c','crypt-des.c', + 'crypt-md5.c','mbuf.c','pgp.c','pgp-armor.c', + 'pgp-cfb.c','pgp-compress.c','pgp-decrypt.c','pgp-encrypt.c', + 'pgp-info.c','pgp-mpi.c','pgp-pubdec.c','pgp-pubenc.c', + 'pgp-pubkey.c','pgp-s2k.c','pgp-pgsql.c' + ); + if ($solution->{options}->{openssl}) + { + $pgcrypto->AddFiles('contrib\pgcrypto', 'openssl.c','pgp-mpi-openssl.c'); + } + else + { + $pgcrypto->AddFiles( + 'contrib\pgcrypto', 'md5.c','sha1.c','sha2.c', + 'internal.c','internal-sha2.c','blf.c','rijndael.c', + 'fortuna.c','random.c','pgp-mpi-internal.c','imath.c' + ); + } + $pgcrypto->AddReference($postgres); + $pgcrypto->AddLibrary('wsock32.lib'); + + my $D; + opendir($D, 'contrib') || croak "Could not opendir on contrib!\n"; + while (my $d = readdir($D)) + { + next if ($d =~ /^\./); + next unless (-f "contrib/$d/Makefile"); + next if (grep {/^$d$/} @contrib_excludes); + AddContrib($d); + } + closedir($D); + + my $mf = Project::read_file('src\backend\utils\mb\conversion_procs\Makefile'); + $mf =~ s{\\s*[\r\n]+}{}mg; + $mf =~ m{DIRS\s*=\s*(.*)$}m || die 'Could not match in conversion makefile' . "\n"; + foreach my $sub (split /\s+/,$1) + { + my $mf = Project::read_file('src\backend\utils\mb\conversion_procs\\' . $sub . '\Makefile'); + my $p = $solution->AddProject($sub, 'dll', 'conversion procs'); + $p->AddFile('src\backend\utils\mb\conversion_procs\\' . $sub . '\\' . $sub . '.c'); + if ($mf =~ m{^SRCS\s*\+=\s*(.*)$}m) + { + $p->AddFile('src\backend\utils\mb\conversion_procs\\' . $sub . '\\' . $1); + } + $p->AddReference($postgres); + } + + $mf = Project::read_file('src\bin\scripts\Makefile'); + $mf =~ s{\\s*[\r\n]+}{}mg; + $mf =~ m{PROGRAMS\s*=\s*(.*)$}m || die 'Could not match in bin\scripts\Makefile' . "\n"; + foreach my $prg (split /\s+/,$1) + { + my $proj = $solution->AddProject($prg,'exe','bin'); + $mf =~ m{$prg\s*:\s*(.*)$}m || die 'Could not find script define for $prg' . "\n"; + my @files = split /\s+/,$1; + foreach my $f (@files) + { + if ($f =~ /\/keywords\.o$/) + { + $proj->AddFile('src\backend\parser\keywords.c'); + } + else + { + $f =~ s/\.o$/\.c/; + if ($f eq 'dumputils.c') + { + $proj->AddFile('src\bin\pg_dump\dumputils.c'); + } + elsif ($f =~ /print\.c$/) + { # Also catches mbprint.c + $proj->AddFile('src\bin\psql\\' . $f); + } + else + { + $proj->AddFile('src\bin\scripts\\' . $f); + } + } + } + $proj->AddIncludeDir('src\interfaces\libpq'); + $proj->AddIncludeDir('src\bin\pg_dump'); + $proj->AddIncludeDir('src\bin\psql'); + $proj->AddReference($libpq,$libpgport); + $proj->AddResourceFile('src\bin\scripts','PostgreSQL Utility'); + } + + # Regression DLL and EXE + my $regress = $solution->AddProject('regress','dll','misc'); + $regress->AddFile('src\test\regress\regress.c'); + $regress->AddReference($postgres); + + my $pgregress = $solution->AddProject('pg_regress','exe','misc'); + $pgregress->AddFile('src\test\regress\pg_regress.c'); + $pgregress->AddIncludeDir('src\port'); + $pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"'); + $pgregress->AddDefine('FRONTEND'); + $pgregress->AddReference($libpgport); + + $solution->Save(); +} + +##################### +# Utility functions # +##################### + +# Add a simple frontend project (exe) +sub AddSimpleFrontend +{ + my $n = shift; + my $uselibpq= shift; + + my $p = $solution->AddProject($n,'exe','bin'); + $p->AddDir('src\bin\\' . $n); + $p->AddDefine('FRONTEND'); + $p->AddReference($libpgport); + if ($uselibpq) + { + $p->AddIncludeDir('src\interfaces\libpq'); + $p->AddReference($libpq); + } + return $p; +} + +# Add a simple contrib project +sub AddContrib +{ + my $n = shift; + my $mf = Project::read_file('contrib\\' . $n . '\Makefile'); + + if ($mf =~ /^MODULE_big/mg) + { + $mf =~ s{\\\s*[\r\n]+}{}mg; + my $proj = $solution->AddProject($n, 'dll', 'contrib'); + $mf =~ /^OBJS\s*=\s*(.*)$/gm || croak "Could not find objects in MODULE_big for $n\n"; + foreach my $o (split /\s+/, $1) + { + $o =~ s/\.o$/.c/; + $proj->AddFile('contrib\\' . $n . '\\' . $o); + } + $proj->AddReference($postgres); + if ($mf =~ /^SUBDIRS\s*:?=\s*(.*)$/mg) + { + foreach my $d (split /\s+/, $1) + { + my $mf2 = Project::read_file('contrib\\' . $n . '\\' . $d . '\Makefile'); + $mf2 =~ s{\\\s*[\r\n]+}{}mg; + $mf2 =~ /^SUBOBJS\s*=\s*(.*)$/gm + || croak "Could not find objects in MODULE_big for $n, subdir $d\n"; + foreach my $o (split /\s+/, $1) + { + $o =~ s/\.o$/.c/; + $proj->AddFile('contrib\\' . $n . '\\' . $d . '\\' . $o); + } + } + } + AdjustContribProj($proj); + return $proj; + } + elsif ($mf =~ /^MODULES\s*=\s*(.*)$/mg) + { + foreach my $mod (split /\s+/, $1) + { + my $proj = $solution->AddProject($mod, 'dll', 'contrib'); + $proj->AddFile('contrib\\' . $n . '\\' . $mod . '.c'); + $proj->AddReference($postgres); + AdjustContribProj($proj); + } + return undef; + } + elsif ($mf =~ /^PROGRAM\s*=\s*(.*)$/mg) + { + my $proj = $solution->AddProject($1, 'exe', 'contrib'); + $mf =~ /^OBJS\s*=\s*(.*)$/gm || croak "Could not find objects in MODULE_big for $n\n"; + foreach my $o (split /\s+/, $1) + { + $o =~ s/\.o$/.c/; + $proj->AddFile('contrib\\' . $n . '\\' . $o); + } + AdjustContribProj($proj); + return $proj; + } + else + { + croak "Could not determine contrib module type for $n\n"; + } +} + +sub AdjustContribProj +{ + my $proj = shift; + my $n = $proj->{name}; + + if ($contrib_defines->{$n}) + { + foreach my $d ($contrib_defines->{$n}) + { + $proj->AddDefine($d); + } + } + if (grep {/^$n$/} @contrib_uselibpq) + { + $proj->AddIncludeDir('src\interfaces\libpq'); + $proj->AddReference($libpq); + } + if (grep {/^$n$/} @contrib_uselibpgport) + { + $proj->AddReference($libpgport); + } + if ($contrib_extralibs->{$n}) + { + foreach my $l (@{$contrib_extralibs->{$n}}) + { + $proj->AddLibrary($l); + } + } + if ($contrib_extraincludes->{$n}) + { + foreach my $i (@{$contrib_extraincludes->{$n}}) + { + $proj->AddIncludeDir($i); + } + } + if ($contrib_extrasource->{$n}) + { + $proj->AddFiles('contrib\\' . $n, @{$contrib_extrasource->{$n}}); + } +} + +1; diff --git a/src/tools/msvc/README b/src/tools/msvc/README index e0123a953f..71d6f7d1d6 100644 --- a/src/tools/msvc/README +++ b/src/tools/msvc/README @@ -8,5 +8,5 @@ Notes about code indention -------------------------- If the perl code is modified, use perltidy on it since pgindent won't touch perl code. Use the following commandline: -perltidy -b -bl -nsfs -naws -l=100 *.pl *.pm +perltidy -b -bl -nsfs -naws -l=100 -ole=unix *.pl *.pm diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 37c098b4fb..f6699c857f 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -3,6 +3,8 @@ use Carp; use strict; use warnings; +use Genbki; + sub new { my $junk = shift; @@ -266,8 +268,11 @@ EOF if (IsNewer('src/backend/catalog/postgres.bki', "src/include/catalog/$bki")) { print "Generating postgres.bki...\n"; - system("perl src/tools/msvc/genbki.pl $self->{majorver} src/backend/catalog/postgres " - . join(' src/include/catalog/',@allbki)); + Genbki::genbki( + $self->{majorver}, + "src/backend/catalog/postgres", + split(/ /,join(' src/include/catalog/',@allbki)) + ); last; } } diff --git a/src/tools/msvc/install.pl b/src/tools/msvc/install.pl index 00271e50a4..4d7053f52d 100755 --- a/src/tools/msvc/install.pl +++ b/src/tools/msvc/install.pl @@ -1,202 +1,13 @@ use strict; use warnings; -use Carp; -use File::Basename; -use File::Copy; -$| = 1; +use Install qw(Install); my $target = shift || Usage(); - -chdir("../../..") if (-f "../../../configure"); -my $conf = ""; -if (-d "debug") -{ - $conf = "debug"; -} -if (-d "release") -{ - $conf = "release"; -} -die "Could not find debug or release binaries" if ($conf eq ""); -print "Installing for $conf\n"; - -EnsureDirectories('bin','lib','share','share/timezonesets'); - -CopySolutionOutput($conf, $target); -copy($target . '/lib/libpq.dll', $target . '/bin/libpq.dll'); -CopySetOfFiles('config files', "*.sample", $target . '/share/'); -CopySetOfFiles('timezone names', 'src\timezone\tznames\*.txt', $target . '/share/timezonesets/'); -CopyFiles( - 'timezone sets', - $target . '/share/timezonesets/', - 'src/timezone/tznames/', 'Default','Australia','India' -); -CopySetOfFiles('BKI files', "src\\backend\\catalog\\postgres.*", $target .'/share/'); -CopySetOfFiles('SQL files', "src\\backend\\catalog\\*.sql", $target . '/share/'); -CopyFiles( - 'Information schema data', - $target . '/share/', - 'src/backend/catalog/', 'sql_features.txt' -); -GenerateConversionScript(); -GenerateTimezoneFiles(); +Install($target); sub Usage { print "Usage: install.pl \n"; exit(1); } - -sub EnsureDirectories -{ - mkdir $target unless -d ($target); - while (my $d = shift) - { - mkdir $target . '/' . $d unless -d ($target . '/' . $d); - } -} - -sub CopyFiles -{ - my $what = shift; - my $target = shift; - my $basedir = shift; - - print "Copying $what"; - while (my $f = shift) - { - print "."; - $f = $basedir . $f; - die "No file $f\n" if (!-f $f); - copy($f, $target . basename($f)) - || croak "Could not copy $f to $target" - . basename($f) - . " to $target" - . basename($f) . "\n"; - } - print "\n"; -} - -sub CopySetOfFiles -{ - my $what = shift; - my $spec = shift; - my $target = shift; - my $D; - - print "Copying $what"; - open($D, "dir /b /s $spec |") || croak "Could not list $spec\n"; - while (<$D>) - { - chomp; - next if /regress/; # Skip temporary install in regression subdir - my $tgt = $target . basename($_); - print "."; - copy($_, $tgt) || croak "Could not copy $_: $!\n"; - } - close($D); - print "\n"; -} - -sub CopySolutionOutput -{ - my $conf = shift; - my $target = shift; - my $rem = qr{Project\("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"\) = "([^"]+)"}; - - my $sln = read_file("pgsql.sln") || croak "Could not open pgsql.sln\n"; - print "Copying build output files..."; - while ($sln =~ $rem) - { - my $pf = $1; - my $dir; - my $ext; - - $sln =~ s/$rem//; - - my $proj = read_file("$pf.vcproj") || croak "Could not open $pf.vcproj\n"; - if ($proj !~ qr{ConfigurationType="([^"]+)"}) - { - croak "Could not parse $pf.vcproj\n"; - } - if ($1 == 1) - { - $dir = "bin"; - $ext = "exe"; - } - elsif ($1 == 2) - { - $dir = "lib"; - $ext = "dll"; - } - else - { - - # Static lib, such as libpgport, only used internally during build, don't install - next; - } - copy("$conf\\$pf\\$pf.$ext","$target\\$dir\\$pf.$ext") || croak "Could not copy $pf.$ext\n"; - print "."; - } - print "\n"; -} - -sub GenerateConversionScript -{ - my $sql = ""; - my $F; - - print "Generating conversion proc script..."; - my $mf = read_file('src/backend/utils/mb/conversion_procs/Makefile'); - $mf =~ s{\\\s*[\r\n]+}{}mg; - $mf =~ /^CONVERSIONS\s*=\s*(.*)$/m - || die "Could not find CONVERSIONS line in conversions Makefile\n"; - my @pieces = split /\s+/,$1; - while ($#pieces > 0) - { - my $name = shift @pieces; - my $se = shift @pieces; - my $de = shift @pieces; - my $func = shift @pieces; - my $obj = shift @pieces; - $sql .= "-- $se --> $de\n"; - $sql .= -"CREATE OR REPLACE FUNCTION $func (INTEGER, INTEGER, CSTRING, INTERNAL, INTEGER) RETURNS VOID AS '\$libdir/$obj', '$func' LANGUAGE C STRICT;\n"; - $sql .= "DROP CONVERSION pg_catalog.$name;\n"; - $sql .= "CREATE DEFAULT CONVERSION pg_catalog.$name FOR '$se' TO '$de' FROM $func;\n"; - } - open($F,">$target/share/conversion_create.sql") - || die "Could not write to conversion_create.sql\n"; - print $F $sql; - close($F); - print "\n"; -} - -sub GenerateTimezoneFiles -{ - my $mf = read_file("src/timezone/Makefile"); - $mf =~ s{\\\s*[\r\n]+}{}mg; - $mf =~ /^TZDATA\s*:?=\s*(.*)$/m || die "Could not find TZDATA row in timezone makefile\n"; - my @tzfiles = split /\s+/,$1; - unshift @tzfiles,''; - print "Generating timezone files..."; - system("$conf\\zic\\zic -d $target/share/timezone " . join(" src/timezone/data/", @tzfiles)); - print "\n"; -} - -sub read_file -{ - my $filename = shift; - my $F; - my $t = $/; - - undef $/; - open($F, $filename) || die "Could not open file $filename\n"; - my $txt = <$F>; - close($F); - $/ = $t; - - return $txt; -} - diff --git a/src/tools/msvc/mkvcbuild.pl b/src/tools/msvc/mkvcbuild.pl index a09838df65..e8d9922f30 100644 --- a/src/tools/msvc/mkvcbuild.pl +++ b/src/tools/msvc/mkvcbuild.pl @@ -1,438 +1,14 @@ -use Carp; -use Win32; use strict; use warnings; -use Project; -use Solution; + +use Mkvcbuild; chdir('..\..\..') if (-d '..\msvc' && -d '..\..\..\src'); die 'Must run from root or msvc directory' unless (-d 'src\tools\msvc' && -d 'src'); + die 'Could not find config.pl' unless (-f 'src/tools/msvc/config.pl'); our $config; require 'src/tools/msvc/config.pl'; -my $solution = new Solution($config); - -our @pgportfiles = qw( - crypt.c fseeko.c getrusage.c inet_aton.c random.c srandom.c - unsetenv.c getaddrinfo.c gettimeofday.c kill.c open.c rand.c - snprintf.c strlcat.c strlcpy.c copydir.c dirmod.c exec.c noblock.c path.c pipe.c - pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c sprompt.c thread.c - getopt.c getopt_long.c dirent.c rint.c win32error.c); - -my $libpgport = $solution->AddProject('libpgport','lib','misc'); -$libpgport->AddDefine('FRONTEND'); -$libpgport->AddFiles('src\port',@pgportfiles); - -my $postgres = $solution->AddProject('postgres','exe','','src\backend'); -$postgres->AddIncludeDir('src\backend'); -$postgres->AddDir('src\backend\port\win32'); -$postgres->AddFile('src\backend\utils\fmgrtab.c'); -$postgres->ReplaceFile('src\backend\port\dynloader.c','src\backend\port\dynloader\win32.c'); -$postgres->ReplaceFile('src\backend\port\pg_sema.c','src\backend\port\win32_sema.c'); -$postgres->ReplaceFile('src\backend\port\pg_shmem.c','src\backend\port\sysv_shmem.c'); -$postgres->AddFiles('src\port',@pgportfiles); -$postgres->AddDir('src\timezone'); -$postgres->AddFiles('src\backend\parser','scan.l','gram.y'); -$postgres->AddFiles('src\backend\bootstrap','bootscanner.l','bootparse.y'); -$postgres->AddFiles('src\backend\utils\misc','guc-file.l'); -$postgres->AddDefine('BUILDING_DLL'); -$postgres->AddLibrary('wsock32.lib ws2_32.lib'); -$postgres->AddLibrary('wldap32.lib') if ($solution->{options}->{ldap}); -$postgres->FullExportDLL('postgres.lib'); - -my $plpgsql = $solution->AddProject('plpgsql','dll','PLs','src\pl\plpgsql\src'); -$plpgsql->AddFiles('src\pl\plpgsql\src','scan.l','gram.y'); -$plpgsql->AddReference($postgres); - -if ($solution->{options}->{perl}) -{ - my $plperl = $solution->AddProject('plperl','dll','PLs','src\pl\plperl'); - $plperl->AddIncludeDir($solution->{options}->{perl} . '/lib/CORE'); - $plperl->AddDefine('PLPERL_HAVE_UID_GID'); - if (Solution::IsNewer('src\pl\plperl\SPI.c','src\pl\plperl\SPI.xs')) - { - print 'Building src\pl\plperl\SPI.c...' . "\n"; - system( $solution->{options}->{perl} - . '/bin/perl ' - . $solution->{options}->{perl} - . '/lib/ExtUtils/xsubpp -typemap ' - . $solution->{options}->{perl} - . '/lib/ExtUtils/typemap src\pl\plperl\SPI.xs >src\pl\plperl\SPI.c'); - if ((!(-f 'src\pl\plperl\SPI.c')) || -z 'src\pl\plperl\SPI.c') - { - unlink('src\pl\plperl\SPI.c'); # if zero size - die 'Failed to create SPI.c' . "\n"; - } - } - $plperl->AddReference($postgres); - $plperl->AddLibrary($solution->{options}->{perl} . '\lib\CORE\perl58.lib'); -} - -if ($solution->{options}->{python}) -{ - my $plpython = $solution->AddProject('plpython','dll','PLs','src\pl\plpython'); - $plpython->AddIncludeDir($solution->{options}->{python} . '\include'); - $solution->{options}->{python} =~ /\\Python(\d{2})/i - || croak "Could not determine python version from path"; - $plpython->AddLibrary($solution->{options}->{python} . "\\Libs\\python$1.lib"); - $plpython->AddReference($postgres); -} - -if ($solution->{options}->{tcl}) -{ - my $pltcl = $solution->AddProject('pltcl','dll','PLs','src\pl\tcl'); - $pltcl->AddIncludeDir($solution->{options}->{tcl} . '\include'); - $pltcl->AddReference($postgres); - $pltcl->AddLibrary($solution->{options}->{tcl} . '\lib\tcl84.lib'); -} - -my $libpq = $solution->AddProject('libpq','dll','interfaces','src\interfaces\libpq'); -$libpq->AddDefine('FRONTEND'); -$libpq->AddIncludeDir('src\port'); -$libpq->AddLibrary('wsock32.lib'); -$libpq->AddLibrary('wldap32.lib') if ($solution->{options}->{ldap}); -$libpq->UseDef('src\interfaces\libpq\libpqdll.def'); -$libpq->ReplaceFile('src\interfaces\libpq\libpqrc.c','src\interfaces\libpq\libpq.rc'); - -my $pgtypes = - $solution->AddProject('libpgtypes','dll','interfaces','src\interfaces\ecpg\pgtypeslib'); -$pgtypes->AddDefine('FRONTEND'); -$pgtypes->AddReference($postgres,$libpgport); -$pgtypes->AddIncludeDir('src\interfaces\ecpg\include'); - -if ($config->{pthread}) -{ - my $libecpg = $solution->AddProject('libecpg','dll','interfaces','src\interfaces\ecpg\ecpglib'); - $libecpg->AddDefine('FRONTEND'); - $libecpg->AddIncludeDir('src\interfaces\ecpg\include'); - $libecpg->AddIncludeDir('src\interfaces\libpq'); - $libecpg->AddIncludeDir('src\port'); - $libecpg->AddLibrary('wsock32.lib'); - $libecpg->AddLibrary($config->{'pthread'} . '\pthreadVC2.lib'); - $libecpg->AddReference($libpq,$pgtypes); - - my $libecpgcompat = - $solution->AddProject('libecpg_compat','dll','interfaces','src\interfaces\ecpg\compatlib'); - $libecpgcompat->AddIncludeDir('src\interfaces\ecpg\include'); - $libecpgcompat->AddIncludeDir('src\interfaces\libpq'); - $libecpgcompat->AddReference($pgtypes,$libecpg); - - my $ecpg = $solution->AddProject('ecpg','exe','interfaces','src\interfaces\ecpg\preproc'); - $ecpg->AddIncludeDir('src\interfaces\ecpg\include'); - $ecpg->AddIncludeDir('src\interfaces\libpq'); - $ecpg->AddFiles('src\interfaces\ecpg\preproc','pgc.l','preproc.y'); - $ecpg->AddDefine('MAJOR_VERSION=4'); - $ecpg->AddDefine('MINOR_VERSION=2'); - $ecpg->AddDefine('PATCHLEVEL=1'); - $ecpg->AddReference($libpgport); -} -else -{ - print "Not building ecpg due to lack of pthreads.\n"; -} - -# src/bin -my $initdb = AddSimpleFrontend('initdb', 1); - -my $pgconfig = AddSimpleFrontend('pg_config'); - -my $pgcontrol = AddSimpleFrontend('pg_controldata'); - -my $pgctl = AddSimpleFrontend('pg_ctl', 1); - -my $pgreset = AddSimpleFrontend('pg_resetxlog'); - -my $pgevent = $solution->AddProject('pgevent','dll','bin'); -$pgevent->AddFiles('src\bin\pgevent','pgevent.c','pgmsgevent.rc'); -$pgevent->AddResourceFile('src\bin\pgevent','Eventlog message formatter'); -$pgevent->RemoveFile('src\bin\pgevent\win32ver.rc'); -$pgevent->UseDef('src\bin\pgevent\pgevent.def'); -$pgevent->DisableLinkerWarnings('4104'); - -my $psql = AddSimpleFrontend('psql', 1); -$psql->AddIncludeDir('src\bin\pg_dump'); -$psql->AddFile('src\bin\psql\psqlscan.l'); - -my $pgdump = AddSimpleFrontend('pg_dump', 1); -$pgdump->AddFile('src\bin\pg_dump\pg_dump.c'); -$pgdump->AddFile('src\bin\pg_dump\common.c'); -$pgdump->AddFile('src\bin\pg_dump\pg_dump_sort.c'); - -my $pgdumpall = AddSimpleFrontend('pg_dump', 1); -$pgdumpall->{name} = 'pg_dumpall'; -$pgdumpall->AddFile('src\bin\pg_dump\pg_dumpall.c'); - -my $pgrestore = AddSimpleFrontend('pg_dump', 1); -$pgrestore->{name} = 'pg_restore'; -$pgrestore->AddFile('src\bin\pg_dump\pg_restore.c'); - -my $zic = $solution->AddProject('zic','exe','utils'); -$zic->AddFiles('src\timezone','zic.c','ialloc.c','scheck.c','localtime.c'); -$zic->AddReference($libpgport); - -my $contrib_defines = {'refint' => 'REFINT_VERBOSE'}; -my @contrib_uselibpq = ('dblink', 'oid2name', 'pgbench', 'vacuumlo'); -my @contrib_uselibpgport = ('oid2name', 'pgbench', 'pg_standby', 'vacuumlo'); -my $contrib_extralibs = {'pgbench' => ['wsock32.lib']}; -my $contrib_extraincludes = {'tsearch2' => ['contrib/tsearch2']}; -my $contrib_extrasource = { - 'cube' => ['cubescan.l','cubeparse.y'], - 'seg' => ['segscan.l','segparse.y'] -}; - -my @contrib_excludes = ('pgcrypto'); - -if ($solution->{options}->{xml}) -{ - $contrib_extraincludes->{'xml2'} = [ - $solution->{options}->{xml} . '\include', - $solution->{options}->{xslt} . '\include', - $solution->{options}->{iconv} . '\include' - ]; - - $contrib_extralibs->{'xml2'} = [ - $solution->{options}->{xml} . '\lib\libxml2.lib', - $solution->{options}->{xslt} . '\lib\libxslt.lib' - ]; -} -else -{ - push @contrib_excludes,'xml2'; -} - -if (!$solution->{options}->{openssl}) -{ - push @contrib_excludes,'sslinfo'; -} - -# Pgcrypto makefile too complex to parse.... -my $pgcrypto = $solution->AddProject('pgcrypto','dll','crypto'); -$pgcrypto->AddFiles( - 'contrib\pgcrypto','pgcrypto.c','px.c','px-hmac.c', - 'px-crypt.c','crypt-gensalt.c','crypt-blowfish.c','crypt-des.c', - 'crypt-md5.c','mbuf.c','pgp.c','pgp-armor.c', - 'pgp-cfb.c','pgp-compress.c','pgp-decrypt.c','pgp-encrypt.c', - 'pgp-info.c','pgp-mpi.c','pgp-pubdec.c','pgp-pubenc.c', - 'pgp-pubkey.c','pgp-s2k.c','pgp-pgsql.c' -); -if ($solution->{options}->{openssl}) -{ - $pgcrypto->AddFiles('contrib\pgcrypto', 'openssl.c','pgp-mpi-openssl.c'); -} -else -{ - $pgcrypto->AddFiles( - 'contrib\pgcrypto', 'md5.c','sha1.c','sha2.c', - 'internal.c','internal-sha2.c','blf.c','rijndael.c', - 'fortuna.c','random.c','pgp-mpi-internal.c','imath.c' - ); -} -$pgcrypto->AddReference($postgres); -$pgcrypto->AddLibrary('wsock32.lib'); - -my $D; -opendir($D, 'contrib') || croak "Could not opendir on contrib!\n"; -while (my $d = readdir($D)) -{ - next if ($d =~ /^\./); - next unless (-f "contrib/$d/Makefile"); - next if (grep {/^$d$/} @contrib_excludes); - AddContrib($d); -} -closedir($D); - -my $mf = Project::read_file('src\backend\utils\mb\conversion_procs\Makefile'); -$mf =~ s{\\s*[\r\n]+}{}mg; -$mf =~ m{DIRS\s*=\s*(.*)$}m || die 'Could not match in conversion makefile' . "\n"; -foreach my $sub (split /\s+/,$1) -{ - my $mf = Project::read_file('src\backend\utils\mb\conversion_procs\\' . $sub . '\Makefile'); - my $p = $solution->AddProject($sub, 'dll', 'conversion procs'); - $p->AddFile('src\backend\utils\mb\conversion_procs\\' . $sub . '\\' . $sub . '.c'); - if ($mf =~ m{^SRCS\s*\+=\s*(.*)$}m) - { - $p->AddFile('src\backend\utils\mb\conversion_procs\\' . $sub . '\\' . $1); - } - $p->AddReference($postgres); -} - -$mf = Project::read_file('src\bin\scripts\Makefile'); -$mf =~ s{\\s*[\r\n]+}{}mg; -$mf =~ m{PROGRAMS\s*=\s*(.*)$}m || die 'Could not match in bin\scripts\Makefile' . "\n"; -foreach my $prg (split /\s+/,$1) -{ - my $proj = $solution->AddProject($prg,'exe','bin'); - $mf =~ m{$prg\s*:\s*(.*)$}m || die 'Could not find script define for $prg' . "\n"; - my @files = split /\s+/,$1; - foreach my $f (@files) - { - if ($f =~ /\/keywords\.o$/) - { - $proj->AddFile('src\backend\parser\keywords.c'); - } - else - { - $f =~ s/\.o$/\.c/; - if ($f eq 'dumputils.c') - { - $proj->AddFile('src\bin\pg_dump\dumputils.c'); - } - elsif ($f =~ /print\.c$/) - { # Also catches mbprint.c - $proj->AddFile('src\bin\psql\\' . $f); - } - else - { - $proj->AddFile('src\bin\scripts\\' . $f); - } - } - } - $proj->AddIncludeDir('src\interfaces\libpq'); - $proj->AddIncludeDir('src\bin\pg_dump'); - $proj->AddIncludeDir('src\bin\psql'); - $proj->AddReference($libpq,$libpgport); - $proj->AddResourceFile('src\bin\scripts','PostgreSQL Utility'); -} - -# Regression DLL and EXE -my $regress = $solution->AddProject('regress','dll','misc'); -$regress->AddFile('src\test\regress\regress.c'); -$regress->AddReference($postgres); - -my $pgregress = $solution->AddProject('pg_regress','exe','misc'); -$pgregress->AddFile('src\test\regress\pg_regress.c'); -$pgregress->AddIncludeDir('src\port'); -$pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"'); -$pgregress->AddDefine('FRONTEND'); -$pgregress->AddReference($libpgport); - -$solution->Save(); - -##################### -# Utility functions # -##################### - -# Add a simple frontend project (exe) -sub AddSimpleFrontend -{ - my $n = shift; - my $uselibpq= shift; - - my $p = $solution->AddProject($n,'exe','bin'); - $p->AddDir('src\bin\\' . $n); - $p->AddDefine('FRONTEND'); - $p->AddReference($libpgport); - if ($uselibpq) - { - $p->AddIncludeDir('src\interfaces\libpq'); - $p->AddReference($libpq); - } - return $p; -} - -# Add a simple contrib project -sub AddContrib -{ - my $n = shift; - my $mf = Project::read_file('contrib\\' . $n . '\Makefile'); - - if ($mf =~ /^MODULE_big/mg) - { - $mf =~ s{\\\s*[\r\n]+}{}mg; - my $proj = $solution->AddProject($n, 'dll', 'contrib'); - $mf =~ /^OBJS\s*=\s*(.*)$/gm || croak "Could not find objects in MODULE_big for $n\n"; - foreach my $o (split /\s+/, $1) - { - $o =~ s/\.o$/.c/; - $proj->AddFile('contrib\\' . $n . '\\' . $o); - } - $proj->AddReference($postgres); - if ($mf =~ /^SUBDIRS\s*:?=\s*(.*)$/mg) - { - foreach my $d (split /\s+/, $1) - { - my $mf2 = Project::read_file('contrib\\' . $n . '\\' . $d . '\Makefile'); - $mf2 =~ s{\\\s*[\r\n]+}{}mg; - $mf2 =~ /^SUBOBJS\s*=\s*(.*)$/gm - || croak "Could not find objects in MODULE_big for $n, subdir $d\n"; - foreach my $o (split /\s+/, $1) - { - $o =~ s/\.o$/.c/; - $proj->AddFile('contrib\\' . $n . '\\' . $d . '\\' . $o); - } - } - } - AdjustContribProj($proj); - return $proj; - } - elsif ($mf =~ /^MODULES\s*=\s*(.*)$/mg) - { - foreach my $mod (split /\s+/, $1) - { - my $proj = $solution->AddProject($mod, 'dll', 'contrib'); - $proj->AddFile('contrib\\' . $n . '\\' . $mod . '.c'); - $proj->AddReference($postgres); - AdjustContribProj($proj); - } - return undef; - } - elsif ($mf =~ /^PROGRAM\s*=\s*(.*)$/mg) - { - my $proj = $solution->AddProject($1, 'exe', 'contrib'); - $mf =~ /^OBJS\s*=\s*(.*)$/gm || croak "Could not find objects in MODULE_big for $n\n"; - foreach my $o (split /\s+/, $1) - { - $o =~ s/\.o$/.c/; - $proj->AddFile('contrib\\' . $n . '\\' . $o); - } - AdjustContribProj($proj); - return $proj; - } - else - { - croak "Could not determine contrib module type for $n\n"; - } -} - -sub AdjustContribProj -{ - my $proj = shift; - my $n = $proj->{name}; - - if ($contrib_defines->{$n}) - { - foreach my $d ($contrib_defines->{$n}) - { - $proj->AddDefine($d); - } - } - if (grep {/^$n$/} @contrib_uselibpq) - { - $proj->AddIncludeDir('src\interfaces\libpq'); - $proj->AddReference($libpq); - } - if (grep {/^$n$/} @contrib_uselibpgport) - { - $proj->AddReference($libpgport); - } - if ($contrib_extralibs->{$n}) - { - foreach my $l (@{$contrib_extralibs->{$n}}) - { - $proj->AddLibrary($l); - } - } - if ($contrib_extraincludes->{$n}) - { - foreach my $i (@{$contrib_extraincludes->{$n}}) - { - $proj->AddIncludeDir($i); - } - } - if ($contrib_extrasource->{$n}) - { - $proj->AddFiles('contrib\\' . $n, @{$contrib_extrasource->{$n}}); - } -} +Mkvcbuild::mkvcbuild($config); diff --git a/src/tools/msvc/vcregress.bat b/src/tools/msvc/vcregress.bat index c895449943..af71483566 100644 --- a/src/tools/msvc/vcregress.bat +++ b/src/tools/msvc/vcregress.bat @@ -24,6 +24,8 @@ SET SCHEDULE=parallel SET TEMPPORT=54321 IF NOT "%2"=="" SET SCHEDULE=%2 +SET PERL5LIB=..\..\tools\msvc + if "%what%"=="INSTALLCHECK" ..\..\..\%CONFIG%\pg_regress\pg_regress --psqldir=..\..\..\%CONFIG%\psql --schedule=%SCHEDULE%_schedule --multibyte=SQL_ASCII --load-language=plpgsql --no-locale if "%what%"=="CHECK" ..\..\..\%CONFIG%\pg_regress\pg_regress --psqldir=..\..\..\%CONFIG%\psql --schedule=%SCHEDULE%_schedule --multibyte=SQL_ASCII --load-language=plpgsql --no-locale --temp-install=./tmp_check --top-builddir=%TOPDIR% --temp-port=%TEMPPORT% -- GitLab