vcbuild - conditional regeneration - Mailing list pgsql-patches

From Magnus Hagander
Subject vcbuild - conditional regeneration
Date
Msg-id 45A6ADCB.2090207@hagander.net
Whole thread Raw
Responses Re: vcbuild - conditional regeneration  (Magnus Hagander <magnus@hagander.net>)
List pgsql-patches
The attached patch changes vcbuild so the project and solution files are
only regenerated if they are actually changed. This helps when you're
developing in the Visual Studio GUI, because updating the files (even to
the same contents) will cause a reload and re-parse of all the projects
in the solution.

As a bonus, it doesn't trash the project file if it for some reason
aborts half-way through.

The patch includes part of the previously sent patch about pthreads
requirements, because they change the same area. Should be workable
without the other one as well, so it's no problem applying just one of
them if the other one is troublesome.

//Magnus
Index: src/tools/msvc/Project.pm
===================================================================
RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/Project.pm,v
retrieving revision 1.5
diff -c -r1.5 Project.pm
*** src/tools/msvc/Project.pm    4 Jan 2007 17:58:19 -0000    1.5
--- src/tools/msvc/Project.pm    11 Jan 2007 21:24:38 -0000
***************
*** 252,261 ****
      }

  # Dump the project
!     open(F, ">$self->{name}.vcproj") || croak("Could not write to $self->{name}.vcproj\n");
!     $self->WriteHeader(*F);
!     $self->WriteReferences(*F);
!     print F <<EOF;
   <Files>
  EOF
      my @dirstack = ();
--- 252,261 ----
      }

  # Dump the project
!    my $dump = '';
!     $dump .= $self->WriteHeader();
!     $dump .= $self->WriteReferences();
!     $dump .= <<EOF;
   <Files>
  EOF
      my @dirstack = ();
***************
*** 271,277 ****
                  last if (length($dir) == length(join('\\',@dirstack)));
                  last if (substr($dir, length(join('\\',@dirstack)),1) eq '\\');
              }
!             print F ' ' x $#dirstack . "  </Filter>\n";
              pop @dirstack;
          }
  # Now walk forwards and create whatever directories are needed
--- 271,277 ----
                  last if (length($dir) == length(join('\\',@dirstack)));
                  last if (substr($dir, length(join('\\',@dirstack)),1) eq '\\');
              }
!             $dump .= ' ' x $#dirstack . "  </Filter>\n";
              pop @dirstack;
          }
  # Now walk forwards and create whatever directories are needed
***************
*** 280,317 ****
              $left =~ s/^\\//;
              my @pieces = split /\\/, $left;
              push @dirstack, $pieces[0];
!             print F ' ' x $#dirstack . "  <Filter Name=\"$pieces[0]\" Filter=\"\">\n";
          }

!         print F ' ' x $#dirstack . "   <File RelativePath=\"$f\"";
          if ($f =~ /\.y$/) {
              my $of = $f;
              $of =~ s/\.y$/.c/;
              $of =~ s{^src\\pl\\plpgsql\\src\\gram.c$}{src\\pl\\plpgsql\\src\\pl_gram.c};
!             print F '>' . GenerateCustomTool('Running bison on ' . $f, 'cmd /V:ON /c src/tools/msvc\pgbison.bat ' .
$f,$of) . '</File>' . "\n"; 
          }
          elsif ($f =~ /\.l$/) {
              my $of = $f;
              $of =~ s/\.l$/.c/;
              $of =~ s{^src\\pl\\plpgsql\\src\\scan.c$}{src\\pl\\plpgsql\\src\\pl_scan.c};
!             print F '>' . GenerateCustomTool('Running flex on ' . $f, 'src/tools/msvc\pgflex.bat ' . $f,$of) .
'</File>'. "\n"; 
          }
          elsif (defined($uniquefiles{$file})) {
  # File already exists, so fake a new name
              my $obj = $dir;
              $obj =~ s/\\/_/g;
!             print F "><FileConfiguration Name=\"Debug|Win32\"><Tool Name=\"VCCLCompilerTool\"
ObjectFile=\".\\debug\\$self->{name}\\$obj". "_$file.obj\" /></FileConfiguration><FileConfiguration
Name=\"Release|Win32\"><ToolName=\"VCCLCompilerTool\" ObjectFile=\".\\release\\$self->{name}\\$obj" . "_$file.obj\"
/></FileConfiguration></File>\n";
          }
          else {
              $uniquefiles{$file} = 1;
!             print F " />\n";
          }
      }
      while ($#dirstack >= 0) {
!         print F ' ' x $#dirstack . "  </Filter>\n";
          pop @dirstack;
      }
!     $self->Footer(*F);
      close(F);
  }

--- 280,331 ----
              $left =~ s/^\\//;
              my @pieces = split /\\/, $left;
              push @dirstack, $pieces[0];
!             $dump .= ' ' x $#dirstack . "  <Filter Name=\"$pieces[0]\" Filter=\"\">\n";
          }

!         $dump .= ' ' x $#dirstack . "   <File RelativePath=\"$f\"";
          if ($f =~ /\.y$/) {
              my $of = $f;
              $of =~ s/\.y$/.c/;
              $of =~ s{^src\\pl\\plpgsql\\src\\gram.c$}{src\\pl\\plpgsql\\src\\pl_gram.c};
!             $dump .= '>' . GenerateCustomTool('Running bison on ' . $f, 'cmd /V:ON /c src/tools/msvc\pgbison.bat ' .
$f,$of) . '</File>' . "\n"; 
          }
          elsif ($f =~ /\.l$/) {
              my $of = $f;
              $of =~ s/\.l$/.c/;
              $of =~ s{^src\\pl\\plpgsql\\src\\scan.c$}{src\\pl\\plpgsql\\src\\pl_scan.c};
!             $dump .= '>' . GenerateCustomTool('Running flex on ' . $f, 'src/tools/msvc\pgflex.bat ' . $f,$of) .
'</File>'. "\n"; 
          }
          elsif (defined($uniquefiles{$file})) {
  # File already exists, so fake a new name
              my $obj = $dir;
              $obj =~ s/\\/_/g;
!             $dump .= "><FileConfiguration Name=\"Debug|Win32\"><Tool Name=\"VCCLCompilerTool\"
ObjectFile=\".\\debug\\$self->{name}\\$obj". "_$file.obj\" /></FileConfiguration><FileConfiguration
Name=\"Release|Win32\"><ToolName=\"VCCLCompilerTool\" ObjectFile=\".\\release\\$self->{name}\\$obj" . "_$file.obj\"
/></FileConfiguration></File>\n";
          }
          else {
              $uniquefiles{$file} = 1;
!             $dump .= " />\n";
          }
      }
      while ($#dirstack >= 0) {
!         $dump .= ' ' x $#dirstack . "  </Filter>\n";
          pop @dirstack;
      }
!     $dump .= $self->Footer();
!     my $oldcont = read_file("$self->{name}.vcproj",1);
!     if ($oldcont) {
!       my $dump2 = $dump;
!       $dump2 =~ s/ProjectGUID="[^"]+"//gs;
!       $dump2 =~ s/ReferencedProjectIdentifier="[^"]+"//gs;
!       $oldcont =~ s/ProjectGUID="[^"]+"//gs;
!       $oldcont =~ s/ReferencedProjectIdentifier="[^"]+"//gs;
!       if ($dump2 eq $oldcont) {
!          #print "Not rewriting $self->{name}\n";
!          return;
!       }
!    }
!     open(F, ">$self->{name}.vcproj") || croak("Could not write to $self->{name}.vcproj\n");
!     print F $dump;
      close(F);
  }

***************
*** 325,357 ****
  }

  sub WriteReferences {
!     my ($self, $f) = @_;
!     print $f " <References>\n";
      foreach my $ref (@{$self->{references}}) {
!         print $f "  <ProjectReference ReferencedProjectIdentifier=\"$ref->{guid}\" Name=\"$ref->{name}\" />\n";
      }
!     print $f " </References>\n";
  }

  sub WriteHeader {
!     my ($self, $f) = @_;
!
!     print $f <<EOF;
  <?xml version="1.0" encoding="Windows-1252"?>
  <VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="$self->{name}" ProjectGUID="$self->{guid}">
   <Platforms><Platform Name="Win32"/></Platforms>
   <Configurations>
  EOF
!     $self->WriteConfiguration($f, 'Debug', { defs=>'_DEBUG;DEBUG=1;', wholeopt=>0 , opt=>0, strpool=>'false',
runtime=>3}); 
!     $self->WriteConfiguration($f, 'Release', { defs=>'', wholeopt=>0, opt=>3, strpool=>'true', runtime=>2 });
! print $f <<EOF;
   </Configurations>
  EOF
  }

  sub WriteConfiguration
  {
!     my ($self, $f, $cfgname, $p) = @_;
      my $cfgtype = ($self->{type} eq "exe")?1:($self->{type} eq "dll"?2:4);
      my $libcfg = (uc $cfgname eq "RELEASE")?"MD":"MDd";
      my $libs = '';
--- 339,373 ----
  }

  sub WriteReferences {
!     my ($self) = @_;
!     my $t = " <References>\n";
      foreach my $ref (@{$self->{references}}) {
!         $t .= "  <ProjectReference ReferencedProjectIdentifier=\"$ref->{guid}\" Name=\"$ref->{name}\" />\n";
      }
!     $t .= " </References>\n";
!     return $t;
  }

  sub WriteHeader {
!     my ($self) = @_;
!    my $t = <<EOF;
  <?xml version="1.0" encoding="Windows-1252"?>
  <VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="$self->{name}" ProjectGUID="$self->{guid}">
   <Platforms><Platform Name="Win32"/></Platforms>
   <Configurations>
  EOF
!     $t .= $self->WriteConfiguration('Debug', { defs=>'_DEBUG;DEBUG=1;', wholeopt=>0 , opt=>0, strpool=>'false',
runtime=>3}); 
!     $t .= $self->WriteConfiguration('Release', { defs=>'', wholeopt=>0, opt=>3, strpool=>'true', runtime=>2 });
! $t .= <<EOF;
   </Configurations>
  EOF
+    return $t;
  }

  sub WriteConfiguration
  {
!     my ($self, $cfgname, $p) = @_;
!     my $t = '';
      my $cfgtype = ($self->{type} eq "exe")?1:($self->{type} eq "dll"?2:4);
      my $libcfg = (uc $cfgname eq "RELEASE")?"MD":"MDd";
      my $libs = '';
***************
*** 367,382 ****
      }
      $libs =~ s/ $//;
      $libs =~ s/__CFGNAME__/$cfgname/g;
!     print $f <<EOF;
    <Configuration Name="$cfgname|Win32" OutputDirectory=".\\$cfgname\\$self->{name}"
IntermediateDirectory=".\\$cfgname\\$self->{name}"
      ConfigurationType="$cfgtype" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="FALSE" CharacterSet="2"
WholeProgramOptimization="$p->{wholeopt}">
      <Tool Name="VCCLCompilerTool" Optimization="$p->{opt}"
!
AdditionalIncludeDirectories="src/include;src/include/port/win32;src/include/port/win32_msvc;$self->{solution}->{options}->{pthread};$self->{includes}"

PreprocessorDefinitions="WIN32;_WINDOWS;__WINDOWS__;__WIN32__;EXEC_BACKEND;WIN32_STACK_RLIMIT=4194304;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE$self->{defines}$p->{defs}"
          StringPooling="$p->{strpool}"
          RuntimeLibrary="$p->{runtime}" DisableSpecificWarnings="$self->{disablewarnings}"
  EOF
!     print $f <<EOF;
          AssemblerOutput="0" AssemblerListingLocation=".\\$cfgname\\$self->{name}\\"
ObjectFile=".\\$cfgname\\$self->{name}\\"
          ProgramDataBaseFileName=".\\$cfgname\\$self->{name}\\" BrowseInformation="0"
          WarningLevel="3" SuppressStartupBanner="TRUE" DebugInformationFormat="3" CompileAs="0"/>
--- 383,400 ----
      }
      $libs =~ s/ $//;
      $libs =~ s/__CFGNAME__/$cfgname/g;
!     my $pth = $self->{solution}->{options}->{pthread};
!     $pth = '' unless $pth;
!     $t .= <<EOF;
    <Configuration Name="$cfgname|Win32" OutputDirectory=".\\$cfgname\\$self->{name}"
IntermediateDirectory=".\\$cfgname\\$self->{name}"
      ConfigurationType="$cfgtype" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="FALSE" CharacterSet="2"
WholeProgramOptimization="$p->{wholeopt}">
      <Tool Name="VCCLCompilerTool" Optimization="$p->{opt}"
!
AdditionalIncludeDirectories="src/include;src/include/port/win32;src/include/port/win32_msvc;$pth;$self->{includes}"

PreprocessorDefinitions="WIN32;_WINDOWS;__WINDOWS__;__WIN32__;EXEC_BACKEND;WIN32_STACK_RLIMIT=4194304;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE$self->{defines}$p->{defs}"
          StringPooling="$p->{strpool}"
          RuntimeLibrary="$p->{runtime}" DisableSpecificWarnings="$self->{disablewarnings}"
  EOF
!     $t .= <<EOF;
          AssemblerOutput="0" AssemblerListingLocation=".\\$cfgname\\$self->{name}\\"
ObjectFile=".\\$cfgname\\$self->{name}\\"
          ProgramDataBaseFileName=".\\$cfgname\\$self->{name}\\" BrowseInformation="0"
          WarningLevel="3" SuppressStartupBanner="TRUE" DebugInformationFormat="3" CompileAs="0"/>
***************
*** 391,419 ****
      if ($self->{implib}) {
          my $l = $self->{implib};
          $l =~ s/__CFGNAME__/$cfgname/g;
!         print $f "\t\tImportLibrary=\"$l\"\n";
      }
      if ($self->{def}) {
          my $d = $self->{def};
          $d =~ s/__CFGNAME__/$cfgname/g;
!         print $f "\t\tModuleDefinitionFile=\"$d\"\n";
      }

!     print $f "\t/>\n";
!     print $f "\t<Tool Name=\"VCLibrarianTool\" OutputFile=\".\\$cfgname\\$self->{name}\\$self->{name}.lib\"
IgnoreDefaultLibraryNames=\"libc\"/>\n"; 
!     print $f "\t<Tool Name=\"VCResourceCompilerTool\" AdditionalIncludeDirectories=\"src\\include\" />\n";
      if ($self->{builddef}) {
!         print $f "\t<Tool Name=\"VCPreLinkEventTool\" Description=\"Generate DEF file\" CommandLine=\"perl
src\\tools\\msvc\\gendef.pl$cfgname\\$self->{name}\" />\n"; 
      }
!     print $f <<EOF;
    </Configuration>
  EOF
  }

  sub Footer {
!     my ($self, $f) = @_;

!     print $f <<EOF;
   </Files>
   <Globals/>
  </VisualStudioProject>
--- 409,438 ----
      if ($self->{implib}) {
          my $l = $self->{implib};
          $l =~ s/__CFGNAME__/$cfgname/g;
!         $t .= "\t\tImportLibrary=\"$l\"\n";
      }
      if ($self->{def}) {
          my $d = $self->{def};
          $d =~ s/__CFGNAME__/$cfgname/g;
!         $t .= "\t\tModuleDefinitionFile=\"$d\"\n";
      }

!     $t .= "\t/>\n";
!     $t .= "\t<Tool Name=\"VCLibrarianTool\" OutputFile=\".\\$cfgname\\$self->{name}\\$self->{name}.lib\"
IgnoreDefaultLibraryNames=\"libc\"/>\n"; 
!     $t .= "\t<Tool Name=\"VCResourceCompilerTool\" AdditionalIncludeDirectories=\"src\\include\" />\n";
      if ($self->{builddef}) {
!         $t .= "\t<Tool Name=\"VCPreLinkEventTool\" Description=\"Generate DEF file\" CommandLine=\"perl
src\\tools\\msvc\\gendef.pl$cfgname\\$self->{name}\" />\n"; 
      }
!     $t .= <<EOF;
    </Configuration>
  EOF
+    return $t;
  }

  sub Footer {
!     my ($self) = @_;

!     return <<EOF;
   </Files>
   <Globals/>
  </VisualStudioProject>
***************
*** 424,433 ****
--- 443,456 ----
  # Utility function that loads a complete file
  sub read_file {
      my $filename = shift;
+     my $ignorenoexist = shift;
      my $F;
      my $t = $/;

      undef $/;
+     if ($ignorenoexist) {
+       open($F, $filename) || return '';
+    }
      open($F, $filename) || croak "Could not open file $filename\n";
      my $txt = <$F>;
      close($F);
Index: src/tools/msvc/Solution.pm
===================================================================
RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/Solution.pm,v
retrieving revision 1.5
diff -c -r1.5 Solution.pm
*** src/tools/msvc/Solution.pm    29 Dec 2006 16:49:02 -0000    1.5
--- src/tools/msvc/Solution.pm    11 Jan 2007 21:21:21 -0000
***************
*** 269,297 ****
          }
      }

!     open(SLN,">pgsql.sln") || croak "Could not write to pgsql.sln\n";
!     print SLN <<EOF;
  Microsoft Visual Studio Solution File, Format Version 9.00
  # Visual Studio 2005
  EOF

      foreach my $fld (keys %{$self->{projects}}) {
          foreach my $proj (@{$self->{projects}->{$fld}}) {
!             print SLN <<EOF;
  Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "$proj->{name}", "$proj->{name}.vcproj", "$proj->{guid}"
  EndProject
  EOF
          }
          if ($fld ne "") {
              $flduid{$fld} = Win32::GuidGen();
!             print SLN <<EOF;
  Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "$fld", "$fld", "$flduid{$fld}"
  EndProject
  EOF
          }
      }

!     print SLN <<EOF;
  Global
      GlobalSection(SolutionConfigurationPlatforms) = preSolution
          Debug|Win32 = Debug|Win32
--- 268,295 ----
          }
      }

!     my $dump = <<EOF;
  Microsoft Visual Studio Solution File, Format Version 9.00
  # Visual Studio 2005
  EOF

      foreach my $fld (keys %{$self->{projects}}) {
          foreach my $proj (@{$self->{projects}->{$fld}}) {
!             $dump .= <<EOF;
  Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "$proj->{name}", "$proj->{name}.vcproj", "$proj->{guid}"
  EndProject
  EOF
          }
          if ($fld ne "") {
              $flduid{$fld} = Win32::GuidGen();
!             $dump .= <<EOF;
  Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "$fld", "$fld", "$flduid{$fld}"
  EndProject
  EOF
          }
      }

!     $dump .= <<EOF;
  Global
      GlobalSection(SolutionConfigurationPlatforms) = preSolution
          Debug|Win32 = Debug|Win32
***************
*** 302,317 ****

      foreach my $fld (keys %{$self->{projects}}) {
          foreach my $proj (@{$self->{projects}->{$fld}}) {
!         print SLN <<EOF;
          $proj->{guid}.Debug|Win32.ActiveCfg = Debug|Win32
!         $proj->{guid}.Debug|Win32.Build.0  = Debug|Win32
          $proj->{guid}.Release|Win32.ActiveCfg = Release|Win32
          $proj->{guid}.Release|Win32.Build.0 = Release|Win32
  EOF
          }
      }

!     print SLN <<EOF;
      EndGlobalSection
      GlobalSection(SolutionProperties) = preSolution
          HideSolutionNode = FALSE
--- 300,315 ----

      foreach my $fld (keys %{$self->{projects}}) {
          foreach my $proj (@{$self->{projects}->{$fld}}) {
!         $dump .= <<EOF;
          $proj->{guid}.Debug|Win32.ActiveCfg = Debug|Win32
!         $proj->{guid}.Debug|Win32.Build.0  = Debug|Win32
          $proj->{guid}.Release|Win32.ActiveCfg = Release|Win32
          $proj->{guid}.Release|Win32.Build.0 = Release|Win32
  EOF
          }
      }

!     $dump .= <<EOF;
      EndGlobalSection
      GlobalSection(SolutionProperties) = preSolution
          HideSolutionNode = FALSE
***************
*** 322,335 ****
      foreach my $fld (keys %{$self->{projects}}) {
          next if ($fld eq "");
          foreach my $proj (@{$self->{projects}->{$fld}}) {
!             print SLN "\t\t$proj->{guid} = $flduid{$fld}\n";
          }
      }

!     print SLN <<EOF;
      EndGlobalSection
  EndGlobal
  EOF
      close(SLN);
  }

--- 320,346 ----
      foreach my $fld (keys %{$self->{projects}}) {
          next if ($fld eq "");
          foreach my $proj (@{$self->{projects}->{$fld}}) {
!             $dump .= "\t\t$proj->{guid} = $flduid{$fld}\n";
          }
      }

!     $dump .= <<EOF;
      EndGlobalSection
  EndGlobal
  EOF
+     my $oldcont = Project::read_file("pgsql.sln",1);
+     if ($oldcont) {
+       my $dump2 = $dump;
+       $dump2 =~ s/{[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}}//gs;
+       $oldcont =~ s/{[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}}//gs;
+       if ($dump2 eq $oldcont) {
+          #print "Not rewriting pgsql.sln\n";
+          return;
+       }
+    }
+     open(SLN,">pgsql.sln") || croak "Could not write to pgsql.sln\n";
+
+     print SLN $dump;
      close(SLN);
  }

pgsql-patches by date:

Previous
From: "Jim C. Nasby"
Date:
Subject: Re: [HACKERS] [PATCHES] Patch to log usage of temporary files
Next
From: "Simon Riggs"
Date:
Subject: Re: [HACKERS] [PATCHES] Patch to log usage of temporary files