1 package VC8WorkspaceCreator
;
3 # ************************************************************
4 # Description : A VC8 Workspace Creator
5 # Author : Johnny Willemsen
6 # Create Date : 4/21/2004
7 # ************************************************************
9 # ************************************************************
11 # ************************************************************
15 use VC8ProjectCreator
;
16 use VC71WorkspaceCreator
;
19 @ISA = qw(VC71WorkspaceCreator);
21 # ************************************************************
23 # ************************************************************
25 ## NOTE: We call the constant as a function to support Perl 5.6.
26 my %lang_map = (Creator
::cplusplus
() => 'Visual C#',
27 Creator
::csharp
() => 'Visual C#',
28 Creator
::vb
() => 'Visual Basic',
29 Creator
::java
() => 'Visual J#');
31 # ************************************************************
33 # ************************************************************
37 my $crlf = $self->crlf();
39 ## This identifies it as a Visual Studio 2005 file
41 'Microsoft Visual Studio Solution File, Format Version 9.00', $crlf;
43 ## Optionally print the workspace comment
44 $self->print_workspace_comment($fh,
45 '# Visual Studio 2005', $crlf,
48 '# This file was generated by MPC. Any changes made directly to', $crlf,
49 '# this file will be lost the next time it is generated.', $crlf,
51 '# MPC Command:', $crlf,
52 '# ', $self->create_command_line_string($0, @ARGV), $crlf);
56 my($self, $fh, $creator) = @_;
57 my $pjs = $self->get_project_info();
58 my @projects = $self->sort_dependencies($self->get_projects(), 0);
61 ## Store a map of the project name to project guid and whether or not
62 ## it is suitable to be referenced. Adding a reference to a
63 ## non-managed c++ library or a "utility" project causes a warning in
64 ## Visual Studio 2008 and higher.
65 foreach my $project (@projects) {
66 my($name, $guid, $lang, $custom_only, $managed) =
67 $creator->access_pi_values($pjs, $project,
68 ProjectCreator
::PROJECT_NAME
,
69 ProjectCreator
::PROJECT_GUID
,
70 ProjectCreator
::LANGUAGE
,
71 ProjectCreator
::CUSTOM_ONLY
,
72 ProjectCreator
::MANAGED_PROJECT
);
73 $gmap{$name} = [$guid, !$custom_only && ($managed ||
74 $lang ne Creator
::cplusplus
)];
77 ## Now go through the projects and check for the need to add external
79 foreach my $project (@projects) {
80 my $ph = new FileHandle
();
81 my $outdir = $self->get_outdir();
82 my $cwd = $self->getcwd();
83 $outdir = $cwd if ($outdir eq '.');
84 my $full = $self->path_is_relative($project) ?
85 "$outdir/$project" : $project;
86 if (open($ph, $full)) {
89 my $crlf = $self->crlf();
90 my $lang = $$pjs{$project}->[ProjectCreator
::LANGUAGE
];
91 my $managed = $$pjs{$project}->[ProjectCreator
::MANAGED_PROJECT
];
94 ## This is a comment found in vc8.mpd if the project contains the
95 ## 'after' keyword setting and the 'add_references' template
97 if (/^(\s*)<!\-\-\s+MPC\s+ADD\s+DEPENDENCIES/) {
99 my $deps = $self->get_validated_ordering($project);
100 foreach my $dep (@
$deps) {
101 my $relative = $self->get_relative_dep_file($creator,
103 if (defined $relative) {
104 $relative =~ s!/!\\!g;
106 if ($lang eq Creator
::cplusplus
) {
107 ## If the current project is not managed, then we will
108 ## add references (although I doubt that will be useful).
109 ## If the current project is managed, then the reference
110 ## project must be managed or a non-c++ project.
111 if (!$managed || ($managed && $gmap{$dep}->[1])) {
112 ## See if the dependency has an associated attribute.
113 ## If it does, split it into name value pairs for use in
114 ## the resulting generated XML.
116 my $attr = $creator->get_dependency_attribute($dep);
118 foreach my $a (split(',', $attr)) {
119 my @nvp = split('=', $a);
120 $attr{lc($nvp[0])} = $nvp[1] if (defined $nvp[0] &&
125 push(@read, $self->cpp_proj_ref($spc, $gmap{$dep}->[0],
129 ## This is a non-c++ language. So, it should not reference
130 ## unmanaged c++ libraries. If it's a managed project or
131 ## it's not a c++ project, it's ok to add a reference.
132 elsif ($gmap{$dep}->[1]) {
133 ## There are situations where, in C#, we want a dependency
134 ## between projects but not want them linked together (via a
135 ## ProjectReference). There is a build dependency, i.e.,
136 ## this project needs to be built if some other project is
137 ## built. But, that's where the dependency ends. Setting
138 ## the ProjectReference attribute to false allows us to do
140 my $attr = $creator->get_dependency_attribute($dep);
141 if (!defined $attr || $attr !~ /ProjectReference=false/i) {
142 push(@read, $spc . '<ProjectReference Include="' .
143 $relative . '">' . $crlf,
144 $spc . ' <Project>{' . $gmap{$dep}->[0] .
145 '}</Project>' . $crlf,
146 $spc . ' <Name>' . $dep . '</Name>' . $crlf,
147 $spc . '</ProjectReference>' . $crlf);
151 ## Indicate that we need to re-write the file
163 ## If we need to re-write the file, then do so
164 if ($write && open($ph, ">$full")) {
165 foreach my $line (@read) {
175 my ($self, $spc, $refguid, $attr, $relative) = @_;
176 my $crlf = $self->crlf();
177 return $spc . '<ProjectReference' . $crlf .
178 $spc . "\tReferencedProjectIdentifier=\"\{$refguid\}\"$crlf" .
179 (defined $$attr{'copylocal'}
180 ?
$spc . "\tCopyLocal=\"" . $$attr{'copylocal'} . "\"$crlf"
183 $spc . "\tRelativePathToProject=\"$relative\"$crlf" .
188 my($self, $name, $proj, $lang) = @_;
190 ## For websites, the project needs to be the directory of the actual
191 ## project file with a trailing slash. The name needs a trailing slash
193 if ($lang eq Creator
::website
) {
194 $proj = $self->mpc_dirname($proj);
196 $name .= '\\' if $self->website_trailing_slash();
199 ## This always needs to be a path with the Windows style directory
205 sub website_trailing_slash
{
209 sub website_extra_props
{
212 sub get_short_config_name
{
213 #my($self, $cfg) = @_;
217 sub get_solution_config_section_name
{
219 return 'SolutionConfigurationPlatforms';
222 sub get_project_config_section_name
{
224 return 'ProjectConfigurationPlatforms';
227 sub print_additional_sections
{
229 my $crlf = $self->crlf();
231 print $fh "\tGlobalSection(SolutionProperties) = preSolution$crlf",
232 "\t\tHideSolutionNode = FALSE$crlf",
233 "\tEndGlobalSection$crlf";
236 sub allow_empty_dependencies
{
241 sub print_inner_project
{
242 my($self, $fh, $gen, $currguid, $deps, $name, $name_to_guid_map, $proj_language, $cfgs) = @_;
244 ## We need to perform a lot of work, but only for websites.
245 if ($proj_language eq Creator
::website
) {
246 my $crlf = $self->crlf();
247 my $directory = ($name eq '.\\' ?
248 $self->get_workspace_name() . '\\' : $name);
250 ## We need the directory name with no trailing back-slash for use
252 my $notrail = $directory;
255 # Print the website project.
256 print $fh "\tProjectSection(WebsiteProperties) = preProject", $crlf;
258 $self->website_extra_props($fh);
260 ## Print out the references
262 foreach my $dep (@
$deps) {
263 if (defined $$name_to_guid_map{$dep}) {
264 $references = "\t\t" .
265 'ProjectReferences = "' if (!defined $references);
266 $references .= "{$$name_to_guid_map{$dep}}|$dep;";
269 print $fh $references, '"', $crlf if (defined $references);
271 ## And now the configurations
273 foreach my $config (@
$cfgs) {
275 if (!$cfg_seen{$config}) {
276 print $fh "\t\t$config.AspNetCompiler.VirtualPath = \"/$notrail\"", $crlf,
277 "\t\t$config.AspNetCompiler.PhysicalPath = \"$directory\"", $crlf,
278 "\t\t$config.AspNetCompiler.TargetPath = \"PrecompiledWeb\\$directory\"", $crlf,
279 "\t\t$config.AspNetCompiler.Updateable = \"true\"", $crlf,
280 "\t\t$config.AspNetCompiler.ForceOverwrite = \"true\"", $crlf,
281 "\t\t$config.AspNetCompiler.FixedNames = \"true\"", $crlf,
282 "\t\t$config.AspNetCompiler.Debug = \"",
283 ($config =~ /debug/i ?
'True' : 'False'), "\"", $crlf;
284 $cfg_seen{$config} = 1;
287 print $fh "\t\tVWDPort = \"1573\"", $crlf,
288 "\t\tDefaultWebSiteLanguage = \"",
289 $lang_map{$self->get_language()}, "\"", $crlf,
290 "\tEndProjectSection", $crlf;
293 # We can ignore this project and pass it to the
294 # SUPER since it's not a website.
295 $self->SUPER::print_inner_project
($fh, $gen, $currguid, $deps,
296 $name, $name_to_guid_map);