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 =~ /^(.*)\\([^\\]+)\.[r]?[cyl]$/); 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"; } 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;