More MSVC build support from Magnus.
authorTom Lane
Wed, 29 Nov 2006 19:49:31 +0000 (19:49 +0000)
committerTom Lane
Wed, 29 Nov 2006 19:49:31 +0000 (19:49 +0000)
src/tools/msvc/Solution.pm
src/tools/msvc/clean.bat [new file with mode: 0755]
src/tools/msvc/genbki.pl [new file with mode: 0755]
src/tools/msvc/install.pl [new file with mode: 0755]

index 104edfd2d9db9580863f2cbd67a5e9d937a67912..e60525656d21660a72115d0c7837a8ea75128881 100644 (file)
@@ -55,6 +55,7 @@ sub GenerateFiles {
                confess "Bad format of version: $self->{strver}\n"
            }
            $self->{numver} = sprintf("%d%02d%02d", $1, $2, $3?$3:0);
+           $self->{majorver} = sprintf("%d.%d", $1, $2);
        }
    }
    close(C);
@@ -206,6 +207,19 @@ EOF
 EOF
        close(O);
    }
+
+   my $mf = Project::read_file('src\backend\catalog\Makefile');
+   $mf =~ s{\\s*[\r\n]+}{}mg;
+   $mf =~ /^POSTGRES_BKI_SRCS\s*:=[^,]+,(.*)\)$/gm || croak "Could not find POSTGRES_BKI_SRCS in Makefile\n";
+   my @allbki = split /\s+/, $1;
+    foreach my $bki (@allbki) {
+       next if $bki eq "";
+       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));
+          last;
+        }
+   }
 }
 
 sub AddProject {
diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat
new file mode 100755 (executable)
index 0000000..a1dd09a
--- /dev/null
@@ -0,0 +1,55 @@
+@echo off
+
+set D=%CD%
+if exist ..\msvc if exist ..\..\..\src cd ..\..\..
+
+if exist debug rd /s /q debug
+if exist release rd /s /q release
+call :del *.vcproj
+call :del pgsql.sln
+del /s /q src\bin\win32ver.rc 2> NUL
+del /s /q src\interfaces\win32ver.rc 2> NUL
+call :del src\backend\win32ver.rc
+
+
+REM Delete files created with GenerateFiles() in Solution.pm
+call :del src\include\pg_config.h
+call :del src\include\pg_config_os.h
+call :del src\include\parser\parse.h
+call :del src\include\utils\fmgroids.h
+
+call :del src\backend\utils\fmgrtab.c
+call :del src\backend\catalog\postgres.bki
+call :del src\backend\catalog\postgres.description
+call :del src\backend\catalog\postgres.shdescription
+call :del src\backend\parser\gram.c
+call :del src\backend\bootstrap\bootparse.c
+call :del src\backend\bootstrap\bootstrap_tokens.h
+
+call :del src\bin\psql\sql_help.h
+
+call :del src\interfaces\libpq\libpq.rc
+call :del src\interfaces\libpq\libpqdll.def
+call :del src\interfaces\ecpg\include\ecpg_config.h
+call :del src\interfaces\ecpg\preproc\preproc.c
+call :del src\interfaces\ecpg\preproc\preproc.h
+
+call :del src\port\pg_config_paths.h
+
+call :del src\pl\plperl\spi.c
+call :del src\pl\plpgsql\src\pl_gram.c
+call :del src\pl\plpgsql\src\pl.tab.h
+
+call :del contrib\cube\cubeparse.c
+call :del contrib\cube\cubeparse.h
+call :del contrib\seg\segparse.c
+call :del contrib\seg\segparse.h
+
+
+cd %D%
+goto :eof
+
+
+:del
+if exist %1 del /q %1
+goto :eof
\ No newline at end of file
diff --git a/src/tools/msvc/genbki.pl b/src/tools/msvc/genbki.pl
new file mode 100755 (executable)
index 0000000..f18033c
--- /dev/null
@@ -0,0 +1,210 @@
+#!/usr/bin/perl
+#-------------------------------------------------------------------------
+#
+# genbki.pl--
+#    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-2006, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+#
+# IDENTIFICATION
+#    $PostgreSQL: pgsql/src/tools/msvc/genbki.pl,v 1.1 2006/11/29 19:49:31 tgl Exp $
+#
+#-------------------------------------------------------------------------
+
+use strict;
+use warnings;
+
+my $version = shift || Usage();
+my $prefix = shift || Usage();
+
+$version =~ /^(\d+\.\d+)/ || die "Bad format verison $version\n";
+my $majorversion = $1;
+
+my $pgext = read_file("src/include/postgres_ext.h");
+$pgext =~ /^#define\s+NAMEDATALEN\s+(\d+)$/mg || die "Could not read NAMEDATALEN from postgres_ext.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) {
+   $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];
+      }
+      $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;
+}
+
diff --git a/src/tools/msvc/install.pl b/src/tools/msvc/install.pl
new file mode 100755 (executable)
index 0000000..c00b730
--- /dev/null
@@ -0,0 +1,132 @@
+use strict;
+use warnings;
+use Carp;
+use File::Basename;
+use File::Copy;
+
+$| = 1;
+
+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');
+
+CopySetOfFiles('programs', "$conf\\*.exe", $target . '/bin/');
+CopySetOfFiles('libraries', "$conf\\*.dll", $target . '/lib/');
+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();
+
+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;
+       my $tgt = $target . basename($_);
+       print ".";
+       copy($_, $tgt) || croak "Could not copy $_\n";
+   }
+   close($D);
+   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;
+}
+