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);
}