Wed Oct 20 09:18:05 UTC 2010 Johnny Willemsen <jwillemsen@remedy.nl>
[MPC.git] / modules / VC8WorkspaceCreator.pm
blob53b36a99cc0f882ffe0b66a4b435b5211d1f7b95
1 package VC8WorkspaceCreator;
3 # ************************************************************
4 # Description : A VC8 Workspace Creator
5 # Author : Johnny Willemsen
6 # Create Date : 4/21/2004
7 # ************************************************************
9 # ************************************************************
10 # Pragmas
11 # ************************************************************
13 use strict;
15 use VC8ProjectCreator;
16 use VC71WorkspaceCreator;
18 use vars qw(@ISA);
19 @ISA = qw(VC71WorkspaceCreator);
21 # ************************************************************
22 # Data Section
23 # ************************************************************
25 my %lang_map = (Creator::cplusplus => 'Visual C#',
26 Creator::csharp => 'Visual C#',
27 Creator::vb => 'Visual Basic',
28 Creator::java => 'Visual J#');
30 # ************************************************************
31 # Subroutine Section
32 # ************************************************************
34 sub pre_workspace {
35 my($self, $fh) = @_;
36 my $crlf = $self->crlf();
38 ## This identifies it as a Visual Studio 2005 file
39 print $fh '', $crlf,
40 'Microsoft Visual Studio Solution File, Format Version 9.00', $crlf;
42 ## Optionally print the workspace comment
43 $self->print_workspace_comment($fh,
44 '# Visual Studio 2005', $crlf,
45 '# $Id$', $crlf,
46 '#', $crlf,
47 '# This file was generated by MPC. Any changes made directly to', $crlf,
48 '# this file will be lost the next time it is generated.', $crlf,
49 '#', $crlf,
50 '# MPC Command:', $crlf,
51 '# ', $self->create_command_line_string($0, @ARGV), $crlf);
54 sub post_workspace {
55 my($self, $fh, $creator) = @_;
56 my $pjs = $self->get_project_info();
57 my @projects = $self->sort_dependencies($self->get_projects(), 0);
58 my %gmap;
60 ## Store a map of the project name to project guid and whether or not
61 ## it is suitable to be referenced. Adding a reference to a
62 ## non-managed c++ library or a "utility" project causes a warning in
63 ## Visual Studio 2008 and higher.
64 foreach my $project (@projects) {
65 my($name, $deps, $guid, $lang, $custom_only, $nocross, $managed) = @{$$pjs{$project}};
66 $gmap{$name} = [$guid, !$custom_only && ($managed ||
67 $lang ne Creator::cplusplus)];
70 ## Now go through the projects and check for the need to add external
71 ## references.
72 foreach my $project (@projects) {
73 my $ph = new FileHandle();
74 my $outdir = $self->get_outdir();
75 $outdir = $self->getcwd() if ($outdir eq '.');
76 if (open($ph, "$outdir/$project")) {
77 my $write;
78 my @read;
79 my $crlf = $self->crlf();
80 my $cwd = $self->getcwd();
81 my $lang = $$pjs{$project}->[3];
82 my $managed = $$pjs{$project}->[6];
84 while(<$ph>) {
85 ## This is a comment found in vc8.mpd if the project contains the
86 ## 'after' keyword setting and the 'add_references' template
87 ## variable setting.
88 if (/^(\s*)<!\-\-\s+MPC\s+ADD\s+DEPENDENCIES/) {
89 my $spc = $1;
90 my $deps = $self->get_validated_ordering($project);
91 foreach my $dep (@$deps) {
92 my $relative = $self->get_relative_dep_file($creator,
93 "$cwd/$project",
94 $dep);
95 if (defined $relative) {
96 $relative =~ s!/!\\!g;
98 if ($lang eq Creator::cplusplus) {
99 ## If the current project is not managed, then we will
100 ## add references (although I doubt that will be useful).
101 ## If the current project is managed, then the reference
102 ## project must be managed or a non-c++ project.
103 if (!$managed || ($managed && $gmap{$dep}->[1])) {
104 ## See if the dependency has an associated attribute.
105 ## If it does, split it into name value pairs for use in
106 ## the resulting generated XML.
107 my %attr;
108 my $attr = $creator->get_dependency_attribute($dep);
109 if (defined $attr) {
110 foreach my $a (split(',', $attr)) {
111 my @nvp = split('=', $a);
112 $attr{lc($nvp[0])} = $nvp[1] if (defined $nvp[0] &&
113 defined $nvp[1]);
117 push(@read, $self->cpp_proj_ref($spc, $gmap{$dep}->[0],
118 \%attr, $relative));
121 ## This is a non-c++ language. So, it should not reference
122 ## unmanaged c++ libraries. If it's a managed project or
123 ## it's not a c++ project, it's ok to add a reference.
124 elsif ($gmap{$dep}->[1]) {
125 push(@read, $spc . '<ProjectReference Include="' .
126 $relative . '">' . $crlf,
127 $spc . ' <Project>{' . $gmap{$dep}->[0] .
128 '}</Project>' . $crlf,
129 $spc . ' <Name>' . $dep . '</Name>' . $crlf,
130 $spc . '</ProjectReference>' . $crlf);
133 ## Indicate that we need to re-write the file
134 $write = 1;
137 last if (!$write);
139 else {
140 push(@read, $_);
143 close($ph);
145 ## If we need to re-write the file, then do so
146 if ($write && open($ph, ">$outdir/$project")) {
147 foreach my $line (@read) {
148 print $ph $line;
150 close($ph);
156 sub cpp_proj_ref {
157 my ($self, $spc, $refguid, $attr, $relative) = @_;
158 my $crlf = $self->crlf();
159 return $spc . '<ProjectReference' . $crlf .
160 $spc . "\tReferencedProjectIdentifier=\"\{$refguid\}\"$crlf" .
161 (defined $$attr{'copylocal'}
162 ? $spc . "\tCopyLocal=\"" . $$attr{'copylocal'} . "\"$crlf"
163 : ''
165 $spc . "\tRelativePathToProject=\"$relative\"$crlf" .
166 $spc . '/>' . $crlf;
169 sub adjust_names {
170 my($self, $name, $proj, $lang) = @_;
172 ## For websites, the project needs to be the directory of the actual
173 ## project file with a trailing slash. The name needs a trailing slash
174 ## too.
175 if ($lang eq Creator::website) {
176 $proj = $self->mpc_dirname($proj);
177 $proj .= '\\';
178 $name .= '\\' if $self->website_trailing_slash();
181 ## This always needs to be a path with the Windows style directory
182 ## separator.
183 $proj =~ s/\//\\/g;
184 return $name, $proj;
187 sub website_trailing_slash {
188 return 1;
191 sub website_extra_props {
194 sub get_short_config_name {
195 #my($self, $cfg) = @_;
196 return $_[1];
199 sub get_solution_config_section_name {
200 #my $self = shift;
201 return 'SolutionConfigurationPlatforms';
204 sub get_project_config_section_name {
205 #my $self = shift;
206 return 'ProjectConfigurationPlatforms';
209 sub print_additional_sections {
210 my($self, $fh) = @_;
211 my $crlf = $self->crlf();
213 print $fh "\tGlobalSection(SolutionProperties) = preSolution$crlf",
214 "\t\tHideSolutionNode = FALSE$crlf",
215 "\tEndGlobalSection$crlf";
218 sub allow_empty_dependencies {
219 #my $self = shift;
220 return 0;
223 sub print_inner_project {
224 my($self, $fh, $gen, $currguid, $deps, $name, $name_to_guid_map, $proj_language, $cfgs) = @_;
226 ## We need to perform a lot of work, but only for websites.
227 if ($proj_language eq Creator::website) {
228 my $crlf = $self->crlf();
229 my $directory = ($name eq '.\\' ?
230 $self->get_workspace_name() . '\\' : $name);
232 ## We need the directory name with no trailing back-slash for use
233 ## below.
234 my $notrail = $directory;
235 $notrail =~ s/\\$//;
237 # Print the website project.
238 print $fh "\tProjectSection(WebsiteProperties) = preProject", $crlf;
240 $self->website_extra_props($fh);
242 ## Print out the references
243 my $references;
244 foreach my $dep (@$deps) {
245 if (defined $$name_to_guid_map{$dep}) {
246 $references = "\t\t" .
247 'ProjectReferences = "' if (!defined $references);
248 $references .= "{$$name_to_guid_map{$dep}}|$dep;";
251 print $fh $references, '"', $crlf if (defined $references);
253 ## And now the configurations
254 my %cfg_seen;
255 foreach my $config (@$cfgs) {
256 $config =~ s/\|.*//;
257 if (!$cfg_seen{$config}) {
258 print $fh "\t\t$config.AspNetCompiler.VirtualPath = \"/$notrail\"", $crlf,
259 "\t\t$config.AspNetCompiler.PhysicalPath = \"$directory\"", $crlf,
260 "\t\t$config.AspNetCompiler.TargetPath = \"PrecompiledWeb\\$directory\"", $crlf,
261 "\t\t$config.AspNetCompiler.Updateable = \"true\"", $crlf,
262 "\t\t$config.AspNetCompiler.ForceOverwrite = \"true\"", $crlf,
263 "\t\t$config.AspNetCompiler.FixedNames = \"true\"", $crlf,
264 "\t\t$config.AspNetCompiler.Debug = \"",
265 ($config =~ /debug/i ? 'True' : 'False'), "\"", $crlf;
266 $cfg_seen{$config} = 1;
269 print $fh "\t\tVWDPort = \"1573\"", $crlf,
270 "\t\tDefaultWebSiteLanguage = \"",
271 $lang_map{$self->get_language()}, "\"", $crlf,
272 "\tEndProjectSection", $crlf;
274 else {
275 # We can ignore this project and pass it to the
276 # SUPER since it's not a website.
277 $self->SUPER::print_inner_project($fh, $gen, $currguid, $deps,
278 $name, $name_to_guid_map);