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