1package VCBuildProject; 2 3# 4# Package that encapsulates a VCBuild (Visual C++ 2005/2008) project file 5# 6# src/tools/msvc/VCBuildProject.pm 7# 8 9use Carp; 10use strict; 11use warnings; 12use base qw(Project); 13 14sub _new 15{ 16 my $classname = shift; 17 my $self = $classname->SUPER::_new(@_); 18 bless($self, $classname); 19 20 $self->{filenameExtension} = '.vcproj'; 21 22 return $self; 23} 24 25sub WriteHeader 26{ 27 my ($self, $f) = @_; 28 29 print $f <<EOF; 30<?xml version="1.0" encoding="Windows-1252"?> 31<VisualStudioProject ProjectType="Visual C++" Version="$self->{vcver}" Name="$self->{name}" ProjectGUID="$self->{guid}"> 32 <Platforms><Platform Name="$self->{platform}"/></Platforms> 33 <Configurations> 34EOF 35 36 $self->WriteConfiguration( 37 $f, 'Debug', 38 { defs => "_DEBUG;DEBUG=1", 39 wholeopt => 0, 40 opt => 0, 41 strpool => 'false', 42 runtime => 3 }); 43 $self->WriteConfiguration( 44 $f, 45 'Release', 46 { defs => "", 47 wholeopt => 0, 48 opt => 3, 49 strpool => 'true', 50 runtime => 2 }); 51 print $f <<EOF; 52 </Configurations> 53EOF 54 $self->WriteReferences($f); 55} 56 57sub WriteFiles 58{ 59 my ($self, $f) = @_; 60 print $f <<EOF; 61 <Files> 62EOF 63 my @dirstack = (); 64 my %uniquefiles; 65 foreach my $fileNameWithPath (sort keys %{ $self->{files} }) 66 { 67 confess "Bad format filename '$fileNameWithPath'\n" 68 unless ($fileNameWithPath =~ m!^(.*)/([^/]+)\.(c|cpp|y|l|rc)$!); 69 my $dir = $1; 70 my $file = $2; 71 72 # Walk backwards down the directory stack and close any dirs 73 # we're done with. 74 while ($#dirstack >= 0) 75 { 76 if (join('/', @dirstack) eq 77 substr($dir, 0, length(join('/', @dirstack)))) 78 { 79 last if (length($dir) == length(join('/', @dirstack))); 80 last 81 if (substr($dir, length(join('/', @dirstack)), 1) eq '/'); 82 } 83 print $f ' ' x $#dirstack . " </Filter>\n"; 84 pop @dirstack; 85 } 86 87 # Now walk forwards and create whatever directories are needed 88 while (join('/', @dirstack) ne $dir) 89 { 90 my $left = substr($dir, length(join('/', @dirstack))); 91 $left =~ s/^\///; 92 my @pieces = split /\//, $left; 93 push @dirstack, $pieces[0]; 94 print $f ' ' x $#dirstack 95 . " <Filter Name=\"$pieces[0]\" Filter=\"\">\n"; 96 } 97 98 # VC builds do not like file paths with forward slashes. 99 my $fileNameWithPathFormatted = $fileNameWithPath; 100 $fileNameWithPathFormatted =~ s/\//\\/g; 101 102 print $f ' ' x $#dirstack 103 . " <File RelativePath=\"$fileNameWithPathFormatted\""; 104 if ($fileNameWithPath =~ /\.y$/) 105 { 106 my $of = $fileNameWithPath; 107 $of =~ s/\.y$/.c/; 108 $of =~ 109 s{^src/pl/plpgsql/src/gram.c$}{src/pl/plpgsql/src/pl_gram.c}; 110 print $f '>' 111 . $self->GenerateCustomTool( 112 'Running bison on ' . $fileNameWithPath, 113 "perl src/tools/msvc/pgbison.pl $fileNameWithPath", $of) 114 . '</File>' . "\n"; 115 } 116 elsif ($fileNameWithPath =~ /\.l$/) 117 { 118 my $of = $fileNameWithPath; 119 $of =~ s/\.l$/.c/; 120 print $f '>' 121 . $self->GenerateCustomTool( 122 'Running flex on ' . $fileNameWithPath, 123 "perl src/tools/msvc/pgflex.pl $fileNameWithPath", $of) 124 . '</File>' . "\n"; 125 } 126 elsif (defined($uniquefiles{$file})) 127 { 128 129 # File already exists, so fake a new name 130 my $obj = $dir; 131 $obj =~ s!/!_!g; 132 print $f 133"><FileConfiguration Name=\"Debug|$self->{platform}\"><Tool Name=\"VCCLCompilerTool\" ObjectFile=\".\\debug\\$self->{name}\\$obj" 134 . "_$file.obj\" /></FileConfiguration><FileConfiguration Name=\"Release|$self->{platform}\"><Tool Name=\"VCCLCompilerTool\" ObjectFile=\".\\release\\$self->{name}\\$obj" 135 . "_$file.obj\" /></FileConfiguration></File>\n"; 136 } 137 else 138 { 139 $uniquefiles{$file} = 1; 140 print $f " />\n"; 141 } 142 } 143 while ($#dirstack >= 0) 144 { 145 print $f ' ' x $#dirstack . " </Filter>\n"; 146 pop @dirstack; 147 } 148 print $f <<EOF; 149 </Files> 150EOF 151} 152 153sub Footer 154{ 155 my ($self, $f) = @_; 156 157 print $f <<EOF; 158 <Globals/> 159</VisualStudioProject> 160EOF 161} 162 163sub WriteConfiguration 164{ 165 my ($self, $f, $cfgname, $p) = @_; 166 my $cfgtype = 167 ($self->{type} eq "exe") ? 1 : ($self->{type} eq "dll" ? 2 : 4); 168 my $libs = $self->GetAdditionalLinkerDependencies($cfgname, ' '); 169 170 my $targetmachine = $self->{platform} eq 'Win32' ? 1 : 17; 171 172 print $f <<EOF; 173 <Configuration Name="$cfgname|$self->{platform}" OutputDirectory=".\\$cfgname\\$self->{name}" IntermediateDirectory=".\\$cfgname\\$self->{name}" 174 ConfigurationType="$cfgtype" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="FALSE" CharacterSet="2" WholeProgramOptimization="$p->{wholeopt}"> 175 <Tool Name="VCCLCompilerTool" Optimization="$p->{opt}" 176 AdditionalIncludeDirectories="$self->{prefixincludes}src/include;src/include/port/win32;src/include/port/win32_msvc;$self->{includes}" 177 PreprocessorDefinitions="WIN32;_WINDOWS;__WINDOWS__;__WIN32__;EXEC_BACKEND;WIN32_STACK_RLIMIT=4194304;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE$self->{defines}$p->{defs}" 178 StringPooling="$p->{strpool}" 179 RuntimeLibrary="$p->{runtime}" DisableSpecificWarnings="$self->{disablewarnings}" 180 AdditionalOptions="/MP" 181EOF 182 print $f <<EOF; 183 AssemblerOutput="0" AssemblerListingLocation=".\\$cfgname\\$self->{name}\\" ObjectFile=".\\$cfgname\\$self->{name}\\" 184 ProgramDataBaseFileName=".\\$cfgname\\$self->{name}\\" BrowseInformation="0" 185 WarningLevel="3" SuppressStartupBanner="TRUE" DebugInformationFormat="3" CompileAs="0"/> 186 <Tool Name="VCLinkerTool" OutputFile=".\\$cfgname\\$self->{name}\\$self->{name}.$self->{type}" 187 AdditionalDependencies="$libs" 188 LinkIncremental="0" SuppressStartupBanner="TRUE" AdditionalLibraryDirectories="" IgnoreDefaultLibraryNames="libc" 189 StackReserveSize="4194304" DisableSpecificWarnings="$self->{disablewarnings}" 190 GenerateDebugInformation="TRUE" ProgramDatabaseFile=".\\$cfgname\\$self->{name}\\$self->{name}.pdb" 191 GenerateMapFile="FALSE" MapFileName=".\\$cfgname\\$self->{name}\\$self->{name}.map" 192 RandomizedBaseAddress="FALSE" 193 SubSystem="1" TargetMachine="$targetmachine" 194EOF 195 if ($self->{disablelinkerwarnings}) 196 { 197 print $f 198"\t\tAdditionalOptions=\"/ignore:$self->{disablelinkerwarnings}\"\n"; 199 } 200 if ($self->{implib}) 201 { 202 my $l = $self->{implib}; 203 $l =~ s/__CFGNAME__/$cfgname/g; 204 print $f "\t\tImportLibrary=\"$l\"\n"; 205 } 206 if ($self->{def}) 207 { 208 my $d = $self->{def}; 209 $d =~ s/__CFGNAME__/$cfgname/g; 210 print $f "\t\tModuleDefinitionFile=\"$d\"\n"; 211 } 212 213 print $f "\t/>\n"; 214 print $f 215"\t<Tool Name=\"VCLibrarianTool\" OutputFile=\".\\$cfgname\\$self->{name}\\$self->{name}.lib\" IgnoreDefaultLibraryNames=\"libc\" />\n"; 216 print $f 217"\t<Tool Name=\"VCResourceCompilerTool\" AdditionalIncludeDirectories=\"src\\include\" />\n"; 218 if ($self->{builddef}) 219 { 220 print $f 221"\t<Tool Name=\"VCPreLinkEventTool\" Description=\"Generate DEF file\" CommandLine=\"perl src\\tools\\msvc\\gendef.pl $cfgname\\$self->{name} $self->{platform}\" />\n"; 222 } 223 print $f <<EOF; 224 </Configuration> 225EOF 226} 227 228sub WriteReferences 229{ 230 my ($self, $f) = @_; 231 print $f " <References>\n"; 232 foreach my $ref (@{ $self->{references} }) 233 { 234 print $f 235" <ProjectReference ReferencedProjectIdentifier=\"$ref->{guid}\" Name=\"$ref->{name}\" />\n"; 236 } 237 print $f " </References>\n"; 238} 239 240sub GenerateCustomTool 241{ 242 my ($self, $desc, $tool, $output, $cfg) = @_; 243 if (!defined($cfg)) 244 { 245 return $self->GenerateCustomTool($desc, $tool, $output, 'Debug') 246 . $self->GenerateCustomTool($desc, $tool, $output, 'Release'); 247 } 248 return 249"<FileConfiguration Name=\"$cfg|$self->{platform}\"><Tool Name=\"VCCustomBuildTool\" Description=\"$desc\" CommandLine=\"$tool\" AdditionalDependencies=\"\" Outputs=\"$output\" /></FileConfiguration>"; 250} 251 252package VC2005Project; 253 254# 255# Package that encapsulates a Visual C++ 2005 project file 256# 257 258use strict; 259use warnings; 260use base qw(VCBuildProject); 261 262sub new 263{ 264 my $classname = shift; 265 my $self = $classname->SUPER::_new(@_); 266 bless($self, $classname); 267 268 $self->{vcver} = '8.00'; 269 270 return $self; 271} 272 273package VC2008Project; 274 275# 276# Package that encapsulates a Visual C++ 2008 project file 277# 278 279use strict; 280use warnings; 281use base qw(VCBuildProject); 282 283sub new 284{ 285 my $classname = shift; 286 my $self = $classname->SUPER::_new(@_); 287 bless($self, $classname); 288 289 $self->{vcver} = '9.00'; 290 291 return $self; 292} 293 2941; 295