package VCBuildProject; # # Package that encapsulates a VCBuild (Visual C++ 2005/2008) project file # # src/tools/msvc/VCBuildProject.pm # use Carp; use strict; use warnings; use base qw(Project); sub _new { my $classname = shift; my $self = $classname->SUPER::_new(@_); bless($self, $classname); $self->{filenameExtension} = '.vcproj'; return $self; } sub WriteHeader { my ($self, $f) = @_; print $f < 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 $self->WriteReferences($f); } sub WriteFiles { my ($self, $f) = @_; print $f < EOF my @dirstack = (); my %uniquefiles; foreach my $fileNameWithPath (sort keys %{ $self->{files} }) { confess "Bad format filename '$fileNameWithPath'\n" unless ($fileNameWithPath =~ m!^(.*)/([^/]+)\.(c|cpp|y|l|rc)$!); my $dir = $1; my $file = $2; # Walk backwards down the directory stack and close any dirs # we're done with. while ($#dirstack >= 0) { if (join('/', @dirstack) eq substr($dir, 0, length(join('/', @dirstack)))) { last if (length($dir) == length(join('/', @dirstack))); last if (substr($dir, length(join('/', @dirstack)), 1) eq '/'); } print $f ' ' x $#dirstack . " \n"; pop @dirstack; } # Now walk forwards and create whatever directories are needed while (join('/', @dirstack) ne $dir) { my $left = substr($dir, length(join('/', @dirstack))); $left =~ s/^\///; my @pieces = split /\//, $left; push @dirstack, $pieces[0]; print $f ' ' x $#dirstack . " \n"; } # VC builds do not like file paths with forward slashes. my $fileNameWithPathFormatted = $fileNameWithPath; $fileNameWithPathFormatted =~ s/\//\\/g; print $f ' ' x $#dirstack . " ' . $self->GenerateCustomTool( 'Running bison on ' . $fileNameWithPath, "perl src/tools/msvc/pgbison.pl $fileNameWithPath", $of) . '' . "\n"; } elsif ($fileNameWithPath =~ /\.l$/) { my $of = $fileNameWithPath; $of =~ s/\.l$/.c/; print $f '>' . $self->GenerateCustomTool( 'Running flex on ' . $fileNameWithPath, "perl src/tools/msvc/pgflex.pl $fileNameWithPath", $of) . '' . "\n"; } elsif (defined($uniquefiles{$file})) { # File already exists, so fake a new name my $obj = $dir; $obj =~ s!/!_!g; print $f ">{platform}\">{name}\\$obj" . "_$file.obj\" />{platform}\">{name}\\$obj" . "_$file.obj\" />\n"; } else { $uniquefiles{$file} = 1; print $f " />\n"; } } while ($#dirstack >= 0) { print $f ' ' x $#dirstack . " \n"; pop @dirstack; } print $f < EOF } sub Footer { my ($self, $f) = @_; print $f < EOF } sub WriteConfiguration { my ($self, $f, $cfgname, $p) = @_; my $cfgtype = ($self->{type} eq "exe") ? 1 : ($self->{type} eq "dll" ? 2 : 4); my $libs = $self->GetAdditionalLinkerDependencies($cfgname, ' '); my $targetmachine = $self->{platform} eq 'Win32' ? 1 : 17; print $f < {disablelinkerwarnings}) { print $f "\t\tAdditionalOptions=\"/ignore:$self->{disablelinkerwarnings}\"\n"; } 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{name}\\$self->{name}.lib\" IgnoreDefaultLibraryNames=\"libc\" />\n"; print $f "\t\n"; if ($self->{builddef}) { print $f "\t{name} $self->{platform}\" />\n"; } print $f < EOF } sub WriteReferences { my ($self, $f) = @_; print $f " \n"; foreach my $ref (@{ $self->{references} }) { print $f " {guid}\" Name=\"$ref->{name}\" />\n"; } print $f " \n"; } sub GenerateCustomTool { my ($self, $desc, $tool, $output, $cfg) = @_; if (!defined($cfg)) { return $self->GenerateCustomTool($desc, $tool, $output, 'Debug') . $self->GenerateCustomTool($desc, $tool, $output, 'Release'); } return "{platform}\">"; } package VC2005Project; # # Package that encapsulates a Visual C++ 2005 project file # use strict; use warnings; use base qw(VCBuildProject); sub new { my $classname = shift; my $self = $classname->SUPER::_new(@_); bless($self, $classname); $self->{vcver} = '8.00'; return $self; } package VC2008Project; # # Package that encapsulates a Visual C++ 2008 project file # use strict; use warnings; use base qw(VCBuildProject); sub new { my $classname = shift; my $self = $classname->SUPER::_new(@_); bless($self, $classname); $self->{vcver} = '9.00'; return $self; } 1;