Fix Xcode project references to the source tree
[cmake.git] / Source / cmLocalVisualStudio7Generator.cxx
bloba871cc7ea48f480d1971b5fd42dbb2aac1dd6d9c
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmLocalVisualStudio7Generator.cxx,v $
5 Language: C++
6 Date: $Date: 2009-09-17 13:18:21 $
7 Version: $Revision: 1.252 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmGlobalVisualStudio7Generator.h"
18 #include "cmLocalVisualStudio7Generator.h"
19 #include "cmXMLParser.h"
20 #include <cm_expat.h>
21 #include "cmMakefile.h"
22 #include "cmSystemTools.h"
23 #include "cmSourceFile.h"
24 #include "cmCacheManager.h"
25 #include "cmake.h"
27 #include "cmComputeLinkInformation.h"
28 #include "cmGeneratedFileStream.h"
30 #include <cmsys/System.h>
32 #include <ctype.h> // for isspace
34 // Package GUID of Intel Visual Fortran plugin to VS IDE
35 #define CM_INTEL_PLUGIN_GUID "{B68A201D-CB9B-47AF-A52F-7EEC72E217E4}"
37 static bool cmLVS6G_IsFAT(const char* dir);
39 class cmLocalVisualStudio7GeneratorInternals
41 public:
42 cmLocalVisualStudio7GeneratorInternals(cmLocalVisualStudio7Generator* e):
43 LocalGenerator(e) {}
44 typedef cmComputeLinkInformation::ItemVector ItemVector;
45 void OutputLibraries(std::ostream& fout, ItemVector const& libs);
46 private:
47 cmLocalVisualStudio7Generator* LocalGenerator;
50 extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
52 //----------------------------------------------------------------------------
53 cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator()
55 this->Version = 7;
56 this->PlatformName = "Win32";
57 this->ExtraFlagTable = 0;
58 this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
61 cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
63 delete this->Internal;
66 void cmLocalVisualStudio7Generator::AddHelperCommands()
68 std::set<cmStdString> lang;
69 lang.insert("C");
70 lang.insert("CXX");
71 lang.insert("RC");
72 lang.insert("IDL");
73 lang.insert("DEF");
74 lang.insert("Fortran");
75 this->CreateCustomTargetsAndCommands(lang);
76 this->FixGlobalTargets();
79 void cmLocalVisualStudio7Generator::Generate()
81 this->WriteProjectFiles();
82 this->WriteStampFiles();
85 void cmLocalVisualStudio7Generator::FixGlobalTargets()
87 // Visual Studio .NET 2003 Service Pack 1 will not run post-build
88 // commands for targets in which no sources are built. Add dummy
89 // rules to force these targets to build.
90 cmTargets &tgts = this->Makefile->GetTargets();
91 for(cmTargets::iterator l = tgts.begin();
92 l != tgts.end(); l++)
94 cmTarget& tgt = l->second;
95 if(tgt.GetType() == cmTarget::GLOBAL_TARGET)
97 std::vector<std::string> no_depends;
98 cmCustomCommandLine force_command;
99 force_command.push_back("cd");
100 force_command.push_back(".");
101 cmCustomCommandLines force_commands;
102 force_commands.push_back(force_command);
103 const char* no_main_dependency = 0;
104 std::string force = this->Makefile->GetStartOutputDirectory();
105 force += cmake::GetCMakeFilesDirectory();
106 force += "/";
107 force += tgt.GetName();
108 force += "_force";
109 this->Makefile->AddCustomCommandToOutput(force.c_str(), no_depends,
110 no_main_dependency,
111 force_commands, " ", 0, true);
112 if(cmSourceFile* file =
113 this->Makefile->GetSourceFileWithOutput(force.c_str()))
115 tgt.AddSourceFile(file);
121 // TODO
122 // for CommandLine= need to repleace quotes with &quot
123 // write out configurations
124 void cmLocalVisualStudio7Generator::WriteProjectFiles()
126 // If not an in source build, then create the output directory
127 if(strcmp(this->Makefile->GetStartOutputDirectory(),
128 this->Makefile->GetHomeDirectory()) != 0)
130 if(!cmSystemTools::MakeDirectory
131 (this->Makefile->GetStartOutputDirectory()))
133 cmSystemTools::Error("Error creating directory ",
134 this->Makefile->GetStartOutputDirectory());
138 // Get the set of targets in this directory.
139 cmTargets &tgts = this->Makefile->GetTargets();
141 // Create the regeneration custom rule.
142 if(!this->Makefile->IsOn("CMAKE_SUPPRESS_REGENERATION"))
144 // Create a rule to regenerate the build system when the target
145 // specification source changes.
146 if(cmSourceFile* sf = this->CreateVCProjBuildRule())
148 // Add the rule to targets that need it.
149 for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
151 if(l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
153 l->second.AddSourceFile(sf);
159 // Create the project file for each target.
160 for(cmTargets::iterator l = tgts.begin();
161 l != tgts.end(); l++)
163 // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
164 // so don't build a projectfile for it
165 if(!l->second.GetProperty("EXTERNAL_MSPROJECT"))
167 this->CreateSingleVCProj(l->first.c_str(),l->second);
172 //----------------------------------------------------------------------------
173 void cmLocalVisualStudio7Generator::WriteStampFiles()
175 // Touch a timestamp file used to determine when the project file is
176 // out of date.
177 std::string stampName = this->Makefile->GetStartOutputDirectory();
178 stampName += cmake::GetCMakeFilesDirectory();
179 cmSystemTools::MakeDirectory(stampName.c_str());
180 stampName += "/";
181 stampName += "generate.stamp";
182 std::ofstream stamp(stampName.c_str());
183 stamp << "# CMake generation timestamp file this directory.\n";
185 // Create a helper file so CMake can determine when it is run
186 // through the rule created by CreateVCProjBuildRule whether it
187 // really needs to regenerate the project. This file lists its own
188 // dependencies. If any file listed in it is newer than itself then
189 // CMake must rerun. Otherwise the project files are up to date and
190 // the stamp file can just be touched.
191 std::string depName = stampName;
192 depName += ".depend";
193 std::ofstream depFile(depName.c_str());
194 depFile << "# CMake generation dependency list for this directory.\n";
195 std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
196 for(std::vector<std::string>::const_iterator lf = listFiles.begin();
197 lf != listFiles.end(); ++lf)
199 depFile << *lf << std::endl;
203 //----------------------------------------------------------------------------
204 void cmLocalVisualStudio7Generator
205 ::CreateSingleVCProj(const char *lname, cmTarget &target)
207 this->FortranProject =
208 static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
209 ->TargetIsFortranOnly(target);
210 // add to the list of projects
211 std::string pname = lname;
212 target.SetProperty("GENERATOR_FILE_NAME",lname);
213 // create the dsp.cmake file
214 std::string fname;
215 fname = this->Makefile->GetStartOutputDirectory();
216 fname += "/";
217 fname += lname;
218 if(this->FortranProject)
220 fname += ".vfproj";
222 else
224 fname += ".vcproj";
227 // Generate the project file and replace it atomically with
228 // copy-if-different. We use a separate timestamp so that the IDE
229 // does not reload project files unnecessarily.
230 cmGeneratedFileStream fout(fname.c_str());
231 fout.SetCopyIfDifferent(true);
232 this->WriteVCProjFile(fout,lname,target);
233 if (fout.Close())
235 this->GlobalGenerator->FileReplacedDuringGenerate(fname);
239 //----------------------------------------------------------------------------
240 cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
242 std::string stampName = cmake::GetCMakeFilesDirectoryPostSlash();
243 stampName += "generate.stamp";
244 const char* dsprule =
245 this->Makefile->GetRequiredDefinition("CMAKE_COMMAND");
246 cmCustomCommandLine commandLine;
247 commandLine.push_back(dsprule);
248 std::string makefileIn = this->Makefile->GetStartDirectory();
249 makefileIn += "/";
250 makefileIn += "CMakeLists.txt";
251 makefileIn = cmSystemTools::CollapseFullPath(makefileIn.c_str());
252 if(!cmSystemTools::FileExists(makefileIn.c_str()))
254 return 0;
256 std::string comment = "Building Custom Rule ";
257 comment += makefileIn;
258 std::string args;
259 args = "-H";
260 args += this->Convert(this->Makefile->GetHomeDirectory(),
261 START_OUTPUT, UNCHANGED, true);
262 commandLine.push_back(args);
263 args = "-B";
264 args +=
265 this->Convert(this->Makefile->GetHomeOutputDirectory(),
266 START_OUTPUT, UNCHANGED, true);
267 commandLine.push_back(args);
268 commandLine.push_back("--check-stamp-file");
269 commandLine.push_back(stampName.c_str());
271 std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
273 cmCustomCommandLines commandLines;
274 commandLines.push_back(commandLine);
275 const char* no_working_directory = 0;
276 this->Makefile->AddCustomCommandToOutput(stampName.c_str(), listFiles,
277 makefileIn.c_str(), commandLines,
278 comment.c_str(),
279 no_working_directory, true);
280 if(cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str()))
282 return file;
284 else
286 cmSystemTools::Error("Error adding rule for ", makefileIn.c_str());
287 return 0;
291 void cmLocalVisualStudio7Generator::WriteConfigurations(std::ostream& fout,
292 const char *libName,
293 cmTarget &target)
295 std::vector<std::string> *configs =
296 static_cast<cmGlobalVisualStudio7Generator *>
297 (this->GlobalGenerator)->GetConfigurations();
299 fout << "\t<Configurations>\n";
300 for( std::vector<std::string>::iterator i = configs->begin();
301 i != configs->end(); ++i)
303 this->WriteConfiguration(fout, i->c_str(), libName, target);
305 fout << "\t</Configurations>\n";
307 cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] =
309 {"Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0},
310 {"SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0},
311 {"DebugInformationFormat", "Zi", "full debug", "debugEnabled", 0},
312 {"DebugInformationFormat", "debug:full", "full debug", "debugEnabled", 0},
313 {"DebugInformationFormat", "Z7", "c7 compat", "debugOldStyleInfo", 0},
314 {"DebugInformationFormat", "Zd", "line numbers", "debugLineInfoOnly", 0},
315 {"Optimization", "Od", "disable optimization", "optimizeDisabled", 0},
316 {"Optimization", "O1", "min space", "optimizeMinSpace", 0},
317 {"Optimization", "O3", "full optimize", "optimizeFull", 0},
318 {"GlobalOptimizations", "Og", "global optimize", "true", 0},
319 {"InlineFunctionExpansion", "Ob0", "", "expandDisable", 0},
320 {"InlineFunctionExpansion", "Ob1", "", "expandOnlyInline", 0},
321 {"FavorSizeOrSpeed", "Os", "", "favorSize", 0},
322 {"OmitFramePointers", "Oy-", "", "false", 0},
323 {"OptimizeForProcessor", "GB", "", "procOptimizeBlended", 0},
324 {"OptimizeForProcessor", "G5", "", "procOptimizePentium", 0},
325 {"OptimizeForProcessor", "G6", "", "procOptimizePentiumProThruIII", 0},
326 {"UseProcessorExtensions", "QzxK", "", "codeForStreamingSIMD", 0},
327 {"OptimizeForProcessor", "QaxN", "", "codeForPentium4", 0},
328 {"OptimizeForProcessor", "QaxB", "", "codeForPentiumM", 0},
329 {"OptimizeForProcessor", "QaxP", "", "codeForCodeNamedPrescott", 0},
330 {"OptimizeForProcessor", "QaxT", "", "codeForCore2Duo", 0},
331 {"OptimizeForProcessor", "QxK", "", "codeExclusivelyStreamingSIMD", 0},
332 {"OptimizeForProcessor", "QxN", "", "codeExclusivelyPentium4", 0},
333 {"OptimizeForProcessor", "QxB", "", "codeExclusivelyPentiumM", 0},
334 {"OptimizeForProcessor", "QxP", "", "codeExclusivelyCodeNamedPrescott", 0},
335 {"OptimizeForProcessor", "QxT", "", "codeExclusivelyCore2Duo", 0},
336 {"OptimizeForProcessor", "QxO", "", "codeExclusivelyCore2StreamingSIMD", 0},
337 {"OptimizeForProcessor", "QxS", "", "codeExclusivelyCore2StreamingSIMD4", 0},
339 {"ModulePath", "module:", "", "",
340 cmVS7FlagTable::UserValueRequired},
341 {"LoopUnrolling", "Qunroll:", "", "",
342 cmVS7FlagTable::UserValueRequired},
343 {"AutoParallelThreshold", "Qpar-threshold:", "", "",
344 cmVS7FlagTable::UserValueRequired},
345 {"HeapArrays", "heap-arrays:", "", "",
346 cmVS7FlagTable::UserValueRequired},
347 {"ObjectText", "bintext:", "", "",
348 cmVS7FlagTable::UserValueRequired},
349 {"Parallelization", "Qparallel", "", "true", 0},
350 {"PrefetchInsertion", "Qprefetch-", "", "false", 0},
351 {"BufferedIO", "assume:buffered_io", "", "true", 0},
352 {"CallingConvention", "iface:stdcall", "", "callConventionStdCall", 0},
353 {"CallingConvention", "iface:cref", "", "callConventionCRef", 0},
354 {"CallingConvention", "iface:stdref", "", "callConventionStdRef", 0},
355 {"CallingConvention", "iface:stdcall", "", "callConventionStdCall", 0},
356 {"CallingConvention", "iface:cvf", "", "callConventionCVF", 0},
357 {"EnableRecursion", "recursive", "", "true", 0},
358 {"ReentrantCode", "reentrancy", "", "true", 0},
359 // done up to Language
360 {0,0,0,0,0}
362 // fill the table here currently the comment field is not used for
363 // anything other than documentation NOTE: Make sure the longer
364 // commandFlag comes FIRST!
365 cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] =
367 // option flags (some flags map to the same option)
368 {"BasicRuntimeChecks", "GZ", "Stack frame checks", "1", 0},
369 {"BasicRuntimeChecks", "RTCsu",
370 "Both stack and uninitialized checks", "3", 0},
371 {"BasicRuntimeChecks", "RTCs", "Stack frame checks", "1", 0},
372 {"BasicRuntimeChecks", "RTCu", "Uninitialized Variables ", "2", 0},
373 {"BasicRuntimeChecks", "RTC1",
374 "Both stack and uninitialized checks", "3", 0},
375 {"DebugInformationFormat", "Z7", "debug format", "1", 0},
376 {"DebugInformationFormat", "Zd", "debug format", "2", 0},
377 {"DebugInformationFormat", "Zi", "debug format", "3", 0},
378 {"DebugInformationFormat", "ZI", "debug format", "4", 0},
379 {"EnableEnhancedInstructionSet", "arch:SSE2",
380 "Use sse2 instructions", "2", 0},
381 {"EnableEnhancedInstructionSet", "arch:SSE",
382 "Use sse instructions", "1", 0},
383 {"FavorSizeOrSpeed", "Ot", "Favor fast code", "1", 0},
384 {"FavorSizeOrSpeed", "Os", "Favor small code", "2", 0},
385 {"CompileAs", "TC", "Compile as c code", "1", 0},
386 {"CompileAs", "TP", "Compile as c++ code", "2", 0},
387 {"Optimization", "Od", "Non Debug", "0", 0},
388 {"Optimization", "O1", "Min Size", "1", 0},
389 {"Optimization", "O2", "Max Speed", "2", 0},
390 {"Optimization", "Ox", "Max Optimization", "3", 0},
391 {"OptimizeForProcessor", "GB", "Blended processor mode", "0", 0},
392 {"OptimizeForProcessor", "G5", "Pentium", "1", 0},
393 {"OptimizeForProcessor", "G6", "PPro PII PIII", "2", 0},
394 {"OptimizeForProcessor", "G7", "Pentium 4 or Athlon", "3", 0},
395 {"InlineFunctionExpansion", "Ob0", "no inlines", "0", 0},
396 {"InlineFunctionExpansion", "Ob1", "when inline keyword", "1", 0},
397 {"InlineFunctionExpansion", "Ob2", "any time you can inline", "2", 0},
398 {"RuntimeLibrary", "MTd", "Multithreded debug", "1", 0},
399 {"RuntimeLibrary", "MT", "Multithreded", "0", 0},
400 {"RuntimeLibrary", "MDd", "Multithreded dll debug", "3", 0},
401 {"RuntimeLibrary", "MD", "Multithreded dll", "2", 0},
402 {"RuntimeLibrary", "MLd", "Sinble Thread debug", "5", 0},
403 {"RuntimeLibrary", "ML", "Sinble Thread", "4", 0},
404 {"StructMemberAlignment", "Zp16", "struct align 16 byte ", "5", 0},
405 {"StructMemberAlignment", "Zp1", "struct align 1 byte ", "1", 0},
406 {"StructMemberAlignment", "Zp2", "struct align 2 byte ", "2", 0},
407 {"StructMemberAlignment", "Zp4", "struct align 4 byte ", "3", 0},
408 {"StructMemberAlignment", "Zp8", "struct align 8 byte ", "4", 0},
409 {"WarningLevel", "W0", "Warning level", "0", 0},
410 {"WarningLevel", "W1", "Warning level", "1", 0},
411 {"WarningLevel", "W2", "Warning level", "2", 0},
412 {"WarningLevel", "W3", "Warning level", "3", 0},
413 {"WarningLevel", "W4", "Warning level", "4", 0},
414 {"DisableSpecificWarnings", "wd", "Disable specific warnings", "",
415 cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
417 // Precompiled header and related options. Note that the
418 // UsePrecompiledHeader entries are marked as "Continue" so that the
419 // corresponding PrecompiledHeaderThrough entry can be found.
420 {"UsePrecompiledHeader", "Yc", "Create Precompiled Header", "1",
421 cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
422 {"PrecompiledHeaderThrough", "Yc", "Precompiled Header Name", "",
423 cmVS7FlagTable::UserValueRequired},
424 {"PrecompiledHeaderFile", "Fp", "Generated Precompiled Header", "",
425 cmVS7FlagTable::UserValue},
426 // The YX and Yu options are in a per-global-generator table because
427 // their values differ based on the VS IDE version.
428 {"ForcedIncludeFiles", "FI", "Forced include files", "",
429 cmVS7FlagTable::UserValueRequired},
431 // boolean flags
432 {"BufferSecurityCheck", "GS", "Buffer security check", "TRUE", 0},
433 {"BufferSecurityCheck", "GS-", "Turn off Buffer security check", "FALSE", 0},
434 {"Detect64BitPortabilityProblems", "Wp64",
435 "Detect 64-bit Portability Problems", "TRUE", 0},
436 {"EnableFiberSafeOptimizations", "GT", "Enable Fiber-safe Optimizations",
437 "TRUE", 0},
438 {"EnableFunctionLevelLinking", "Gy",
439 "EnableFunctionLevelLinking", "TRUE", 0},
440 {"EnableIntrinsicFunctions", "Oi", "EnableIntrinsicFunctions", "TRUE", 0},
441 {"GlobalOptimizations", "Og", "Global Optimize", "TRUE", 0},
442 {"ImproveFloatingPointConsistency", "Op",
443 "ImproveFloatingPointConsistency", "TRUE", 0},
444 {"MinimalRebuild", "Gm", "minimal rebuild", "TRUE", 0},
445 {"OmitFramePointers", "Oy", "OmitFramePointers", "TRUE", 0},
446 {"OptimizeForWindowsApplication", "GA", "Optimize for windows", "TRUE", 0},
447 {"RuntimeTypeInfo", "GR",
448 "Turn on Run time type information for c++", "TRUE", 0},
449 {"RuntimeTypeInfo", "GR-",
450 "Turn off Run time type information for c++", "FALSE", 0},
451 {"SmallerTypeCheck", "RTCc", "smaller type check", "TRUE", 0},
452 {"SuppressStartupBanner", "nologo", "SuppressStartupBanner", "TRUE", 0},
453 {"WarnAsError", "WX", "Treat warnings as errors", "TRUE", 0},
454 {"BrowseInformation", "FR", "Generate browse information", "1", 0},
455 {0,0,0,0,0}
460 cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] =
462 // option flags (some flags map to the same option)
463 {"GenerateManifest", "MANIFEST:NO",
464 "disable manifest generation", "FALSE", 0},
465 {"GenerateManifest", "MANIFEST", "enable manifest generation", "TRUE", 0},
466 {"LinkIncremental", "INCREMENTAL:NO", "link incremental", "1", 0},
467 {"LinkIncremental", "INCREMENTAL:YES", "link incremental", "2", 0},
468 {"IgnoreDefaultLibraryNames", "NODEFAULTLIB:", "default libs to ignore", "",
469 cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
470 {"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "ignore all default libs",
471 "TRUE", 0},
472 {"FixedBaseAddress", "FIXED:NO", "Generate a relocation section", "1", 0},
473 {"FixedBaseAddress", "FIXED", "Image must be loaded at a fixed address",
474 "2", 0},
475 {"EnableCOMDATFolding", "OPT:NOICF", "Do not remove redundant COMDATs",
476 "1", 0},
477 {"EnableCOMDATFolding", "OPT:ICF", "Remove redundant COMDATs", "2", 0},
478 {"OptimizeReferences", "OPT:NOREF", "Keep unreferenced data", "1", 0},
479 {"OptimizeReferences", "OPT:REF", "Eliminate unreferenced data", "2", 0},
480 {"TargetMachine", "MACHINE:I386", "Machine x86", "1", 0},
481 {"TargetMachine", "MACHINE:X86", "Machine x86", "1", 0},
482 {"TargetMachine", "MACHINE:X64", "Machine x64", "17", 0},
483 {"ModuleDefinitionFile", "DEF:", "add an export def file", "",
484 cmVS7FlagTable::UserValue},
485 {"GenerateMapFile", "MAP", "enable generation of map file", "TRUE", 0},
486 {0,0,0,0,0}
489 //----------------------------------------------------------------------------
490 // Helper class to write build event <Tool .../> elements.
491 class cmLocalVisualStudio7Generator::EventWriter
493 public:
494 EventWriter(cmLocalVisualStudio7Generator* lg,
495 const char* config, std::ostream& os):
496 LG(lg), Config(config), Stream(os), First(true) {}
497 void Start(const char* tool)
499 this->First = true;
500 this->Stream << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"";
502 void Finish()
504 this->Stream << (this->First? "" : "\"") << "/>\n";
506 void Write(std::vector<cmCustomCommand> const& ccs)
508 for(std::vector<cmCustomCommand>::const_iterator ci = ccs.begin();
509 ci != ccs.end(); ++ci)
511 this->Write(*ci);
514 void Write(cmCustomCommand const& cc)
516 if(this->First)
518 const char* comment = cc.GetComment();
519 if(comment && *comment)
521 this->Stream << "\nDescription=\""
522 << this->LG->EscapeForXML(comment) << "\"";
524 this->Stream << "\nCommandLine=\"";
525 this->First = false;
527 else
529 this->Stream << this->LG->EscapeForXML("\n");
531 std::string script =
532 this->LG->ConstructScript(cc.GetCommandLines(),
533 cc.GetWorkingDirectory(),
534 this->Config,
535 cc.GetEscapeOldStyle(),
536 cc.GetEscapeAllowMakeVars());
537 this->Stream << this->LG->EscapeForXML(script.c_str());
539 private:
540 cmLocalVisualStudio7Generator* LG;
541 const char* Config;
542 std::ostream& Stream;
543 bool First;
546 //----------------------------------------------------------------------------
547 void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
548 const char* configName,
549 const char *libName,
550 cmTarget &target)
552 const char* mfcFlag = this->Makefile->GetDefinition("CMAKE_MFC_FLAG");
553 if(!mfcFlag)
555 mfcFlag = "0";
557 fout << "\t\t<Configuration\n"
558 << "\t\t\tName=\"" << configName << "|" << this->PlatformName << "\"\n"
559 << "\t\t\tOutputDirectory=\"" << configName << "\"\n";
560 // This is an internal type to Visual Studio, it seems that:
561 // 4 == static library
562 // 2 == dll
563 // 1 == executable
564 // 10 == utility
565 const char* configType = "10";
566 const char* projectType = 0;
567 bool targetBuilds = true;
568 switch(target.GetType())
570 case cmTarget::STATIC_LIBRARY:
571 projectType = "typeStaticLibrary";
572 configType = "4";
573 break;
574 case cmTarget::SHARED_LIBRARY:
575 case cmTarget::MODULE_LIBRARY:
576 projectType = "typeDynamicLibrary";
577 configType = "2";
578 break;
579 case cmTarget::EXECUTABLE:
580 configType = "1";
581 break;
582 case cmTarget::UTILITY:
583 case cmTarget::GLOBAL_TARGET:
584 configType = "10";
585 default:
586 targetBuilds = false;
587 break;
589 if(this->FortranProject && projectType)
591 configType = projectType;
593 std::string flags;
594 if(strcmp(configType, "10") != 0)
596 const char* linkLanguage = target.GetLinkerLanguage(configName);
597 if(!linkLanguage)
599 cmSystemTools::Error
600 ("CMake can not determine linker language for target:",
601 target.GetName());
602 return;
604 if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0
605 || strcmp(linkLanguage, "Fortran") == 0)
607 std::string baseFlagVar = "CMAKE_";
608 baseFlagVar += linkLanguage;
609 baseFlagVar += "_FLAGS";
610 flags = this->Makefile->GetRequiredDefinition(baseFlagVar.c_str());
611 std::string flagVar = baseFlagVar + std::string("_") +
612 cmSystemTools::UpperCase(configName);
613 flags += " ";
614 flags += this->Makefile->GetRequiredDefinition(flagVar.c_str());
616 // set the correct language
617 if(strcmp(linkLanguage, "C") == 0)
619 flags += " /TC ";
621 if(strcmp(linkLanguage, "CXX") == 0)
623 flags += " /TP ";
627 // Add the target-specific flags.
628 if(const char* targetFlags = target.GetProperty("COMPILE_FLAGS"))
630 flags += " ";
631 flags += targetFlags;
634 std::string configUpper = cmSystemTools::UpperCase(configName);
635 std::string defPropName = "COMPILE_DEFINITIONS_";
636 defPropName += configUpper;
638 // Get preprocessor definitions for this directory.
639 std::string defineFlags = this->Makefile->GetDefineFlags();
640 Options::Tool t = Options::Compiler;
641 cmVS7FlagTable const* table = cmLocalVisualStudio7GeneratorFlagTable;
642 if(this->FortranProject)
644 t = Options::FortranCompiler;
645 table = cmLocalVisualStudio7GeneratorFortranFlagTable;
647 Options targetOptions(this, this->Version, t,
648 table,
649 this->ExtraFlagTable);
650 targetOptions.FixExceptionHandlingDefault();
651 targetOptions.Parse(flags.c_str());
652 targetOptions.Parse(defineFlags.c_str());
653 targetOptions.AddDefines
654 (this->Makefile->GetProperty("COMPILE_DEFINITIONS"));
655 targetOptions.AddDefines(target.GetProperty("COMPILE_DEFINITIONS"));
656 targetOptions.AddDefines(this->Makefile->GetProperty(defPropName.c_str()));
657 targetOptions.AddDefines(target.GetProperty(defPropName.c_str()));
658 targetOptions.SetVerboseMakefile(
659 this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
661 // Add a definition for the configuration name.
662 std::string configDefine = "CMAKE_INTDIR=\"";
663 configDefine += configName;
664 configDefine += "\"";
665 targetOptions.AddDefine(configDefine);
667 // Add the export symbol definition for shared library objects.
668 if(const char* exportMacro = target.GetExportMacro())
670 targetOptions.AddDefine(exportMacro);
673 // The intermediate directory name consists of a directory for the
674 // target and a subdirectory for the configuration name.
675 std::string intermediateDir = this->GetTargetDirectory(target);
676 intermediateDir += "/";
677 intermediateDir += configName;
678 fout << "\t\t\tIntermediateDirectory=\""
679 << this->ConvertToXMLOutputPath(intermediateDir.c_str())
680 << "\"\n"
681 << "\t\t\tConfigurationType=\"" << configType << "\"\n"
682 << "\t\t\tUseOfMFC=\"" << mfcFlag << "\"\n"
683 << "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n";
685 // If unicode is enabled change the character set to unicode, if not
686 // then default to MBCS.
687 if(targetOptions.UsingUnicode())
689 fout << "\t\t\tCharacterSet=\"1\">\n";
691 else
693 fout << "\t\t\tCharacterSet=\"2\">\n";
695 const char* tool = "VCCLCompilerTool";
696 if(this->FortranProject)
698 tool = "VFFortranCompilerTool";
700 fout << "\t\t\t<Tool\n"
701 << "\t\t\t\tName=\"" << tool << "\"\n";
702 if(this->FortranProject)
704 const char* target_mod_dir =
705 target.GetProperty("Fortran_MODULE_DIRECTORY");
706 std::string modDir;
707 if(target_mod_dir)
709 modDir = this->Convert(target_mod_dir,
710 cmLocalGenerator::START_OUTPUT,
711 cmLocalGenerator::UNCHANGED);
713 else
715 modDir = ".";
717 fout << "\t\t\t\tModulePath=\""
718 << this->ConvertToXMLOutputPath(modDir.c_str())
719 << "\\$(ConfigurationName)\"\n";
721 targetOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
722 fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
723 std::vector<std::string> includes;
724 this->GetIncludeDirectories(includes);
725 std::vector<std::string>::iterator i = includes.begin();
726 for(;i != includes.end(); ++i)
728 // output the include path
729 std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
730 fout << ipath << ";";
731 // if this is fortran then output the include with
732 // a ConfigurationName on the end of it.
733 if(this->FortranProject)
735 ipath = i->c_str();
736 ipath += "/$(ConfigurationName)";
737 ipath = this->ConvertToXMLOutputPath(ipath.c_str());
738 fout << ipath << ";";
741 fout << "\"\n";
742 targetOptions.OutputFlagMap(fout, "\t\t\t\t");
743 targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n");
744 fout << "\t\t\t\tAssemblerListingLocation=\"" << configName << "\"\n";
745 fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n";
746 if(targetBuilds)
748 // We need to specify a program database file name even for
749 // non-debug configurations because VS still creates .idb files.
750 fout << "\t\t\t\tProgramDataBaseFileName=\""
751 << target.GetDirectory(configName) << "/"
752 << target.GetPDBName(configName) << "\"\n";
754 fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
755 tool = "VCCustomBuildTool";
756 if(this->FortranProject)
758 tool = "VFCustomBuildTool";
760 fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"/>\n";
761 tool = "VCResourceCompilerTool";
762 if(this->FortranProject)
764 tool = "VFResourceCompilerTool";
766 fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n"
767 << "\t\t\t\tAdditionalIncludeDirectories=\"";
768 for(i = includes.begin();i != includes.end(); ++i)
770 std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
771 fout << ipath << ";";
773 // add the -D flags to the RC tool
774 fout << "\"";
775 targetOptions.OutputPreprocessorDefinitions(fout, "\n\t\t\t\t", "");
776 fout << "/>\n";
777 tool = "VCMIDLTool";
778 if(this->FortranProject)
780 tool = "VFMIDLTool";
782 fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n";
783 targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n");
784 fout << "\t\t\t\tMkTypLibCompatible=\"FALSE\"\n";
785 if( this->PlatformName == "x64" )
787 fout << "\t\t\t\tTargetEnvironment=\"3\"\n";
789 else if( this->PlatformName == "ia64" )
791 fout << "\t\t\t\tTargetEnvironment=\"2\"\n";
793 else
795 fout << "\t\t\t\tTargetEnvironment=\"1\"\n";
797 fout << "\t\t\t\tGenerateStublessProxies=\"TRUE\"\n";
798 fout << "\t\t\t\tTypeLibraryName=\"$(InputName).tlb\"\n";
799 fout << "\t\t\t\tOutputDirectory=\"$(IntDir)\"\n";
800 fout << "\t\t\t\tHeaderFileName=\"$(InputName).h\"\n";
801 fout << "\t\t\t\tDLLDataFileName=\"\"\n";
802 fout << "\t\t\t\tInterfaceIdentifierFileName=\"$(InputName)_i.c\"\n";
803 fout << "\t\t\t\tProxyFileName=\"$(InputName)_p.c\"/>\n";
804 // end of <Tool Name=VCMIDLTool
806 // Check if we need the FAT32 workaround.
807 if(targetBuilds && this->Version >= 8)
809 // Check the filesystem type where the target will be written.
810 if(cmLVS6G_IsFAT(target.GetDirectory(configName).c_str()))
812 // Add a flag telling the manifest tool to use a workaround
813 // for FAT32 file systems, which can cause an empty manifest
814 // to be embedded into the resulting executable. See CMake
815 // bug #2617.
816 const char* tool = "VCManifestTool";
817 if(this->FortranProject)
819 tool = "VFManifestTool";
821 fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n"
822 << "\t\t\t\tUseFAT32Workaround=\"true\"\n"
823 << "\t\t\t/>\n";
827 this->OutputTargetRules(fout, configName, target, libName);
828 this->OutputBuildTool(fout, configName, target, targetOptions.IsDebug());
829 fout << "\t\t</Configuration>\n";
832 //----------------------------------------------------------------------------
833 std::string
834 cmLocalVisualStudio7Generator
835 ::GetBuildTypeLinkerFlags(std::string rootLinkerFlags, const char* configName)
837 std::string configTypeUpper = cmSystemTools::UpperCase(configName);
838 std::string extraLinkOptionsBuildTypeDef =
839 rootLinkerFlags + "_" + configTypeUpper;
841 std::string extraLinkOptionsBuildType =
842 this->Makefile->GetRequiredDefinition
843 (extraLinkOptionsBuildTypeDef.c_str());
845 return extraLinkOptionsBuildType;
848 void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
849 const char* configName,
850 cmTarget &target,
851 bool isDebug)
853 std::string temp;
854 std::string extraLinkOptions;
855 if(target.GetType() == cmTarget::EXECUTABLE)
857 extraLinkOptions =
858 this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS")
859 + std::string(" ")
860 + GetBuildTypeLinkerFlags("CMAKE_EXE_LINKER_FLAGS", configName);
862 if(target.GetType() == cmTarget::SHARED_LIBRARY)
864 extraLinkOptions =
865 this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS")
866 + std::string(" ")
867 + GetBuildTypeLinkerFlags("CMAKE_SHARED_LINKER_FLAGS", configName);
869 if(target.GetType() == cmTarget::MODULE_LIBRARY)
871 extraLinkOptions =
872 this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS")
873 + std::string(" ")
874 + GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName);
877 const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
878 if(targetLinkFlags)
880 extraLinkOptions += " ";
881 extraLinkOptions += targetLinkFlags;
883 std::string configTypeUpper = cmSystemTools::UpperCase(configName);
884 std::string linkFlagsConfig = "LINK_FLAGS_";
885 linkFlagsConfig += configTypeUpper;
886 targetLinkFlags = target.GetProperty(linkFlagsConfig.c_str());
887 if(targetLinkFlags)
889 extraLinkOptions += " ";
890 extraLinkOptions += targetLinkFlags;
892 Options linkOptions(this, this->Version, Options::Linker,
893 cmLocalVisualStudio7GeneratorLinkFlagTable);
894 linkOptions.Parse(extraLinkOptions.c_str());
895 switch(target.GetType())
897 case cmTarget::STATIC_LIBRARY:
899 std::string targetNameFull = target.GetFullName(configName);
900 std::string libpath = target.GetDirectory(configName);
901 libpath += "/";
902 libpath += targetNameFull;
903 const char* tool = "VCLibrarianTool";
904 if(this->FortranProject)
906 tool = "VFLibrarianTool";
908 fout << "\t\t\t<Tool\n"
909 << "\t\t\t\tName=\"" << tool << "\"\n";
910 if(const char* libflags = target.GetProperty("STATIC_LIBRARY_FLAGS"))
912 fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
914 fout << "\t\t\t\tOutputFile=\""
915 << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
916 break;
918 case cmTarget::SHARED_LIBRARY:
919 case cmTarget::MODULE_LIBRARY:
921 std::string targetName;
922 std::string targetNameSO;
923 std::string targetNameFull;
924 std::string targetNameImport;
925 std::string targetNamePDB;
926 target.GetLibraryNames(targetName, targetNameSO, targetNameFull,
927 targetNameImport, targetNamePDB, configName);
929 // Compute the link library and directory information.
930 cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
931 if(!pcli)
933 return;
935 cmComputeLinkInformation& cli = *pcli;
936 const char* linkLanguage = cli.GetLinkLanguage();
938 // Compute the variable name to lookup standard libraries for this
939 // language.
940 std::string standardLibsVar = "CMAKE_";
941 standardLibsVar += linkLanguage;
942 standardLibsVar += "_STANDARD_LIBRARIES";
943 const char* tool = "VCLinkerTool";
944 if(this->FortranProject)
946 tool = "VFLinkerTool";
948 fout << "\t\t\t<Tool\n"
949 << "\t\t\t\tName=\"" << tool << "\"\n";
950 linkOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
951 // Use the NOINHERIT macro to avoid getting VS project default
952 // libraries which may be set by the user to something bad.
953 fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
954 << this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
955 << " ";
956 this->Internal->OutputLibraries(fout, cli.GetItems());
957 fout << "\"\n";
958 temp = target.GetDirectory(configName);
959 temp += "/";
960 temp += targetNameFull;
961 fout << "\t\t\t\tOutputFile=\""
962 << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
963 this->WriteTargetVersionAttribute(fout, target);
964 linkOptions.OutputFlagMap(fout, "\t\t\t\t");
965 fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
966 this->OutputLibraryDirectories(fout, cli.GetDirectories());
967 fout << "\"\n";
968 this->OutputModuleDefinitionFile(fout, target);
969 temp = target.GetDirectory(configName);
970 temp += "/";
971 temp += targetNamePDB;
972 fout << "\t\t\t\tProgramDataBaseFile=\"" <<
973 this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
974 if(isDebug)
976 fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
978 std::string stackVar = "CMAKE_";
979 stackVar += linkLanguage;
980 stackVar += "_STACK_SIZE";
981 const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
982 if(stackVal)
984 fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n";
986 temp = target.GetDirectory(configName, true);
987 temp += "/";
988 temp += targetNameImport;
989 fout << "\t\t\t\tImportLibrary=\""
990 << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
992 break;
993 case cmTarget::EXECUTABLE:
995 std::string targetName;
996 std::string targetNameFull;
997 std::string targetNameImport;
998 std::string targetNamePDB;
999 target.GetExecutableNames(targetName, targetNameFull,
1000 targetNameImport, targetNamePDB, configName);
1002 // Compute the link library and directory information.
1003 cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
1004 if(!pcli)
1006 return;
1008 cmComputeLinkInformation& cli = *pcli;
1009 const char* linkLanguage = cli.GetLinkLanguage();
1011 // Compute the variable name to lookup standard libraries for this
1012 // language.
1013 std::string standardLibsVar = "CMAKE_";
1014 standardLibsVar += linkLanguage;
1015 standardLibsVar += "_STANDARD_LIBRARIES";
1016 const char* tool = "VCLinkerTool";
1017 if(this->FortranProject)
1019 tool = "VFLinkerTool";
1021 fout << "\t\t\t<Tool\n"
1022 << "\t\t\t\tName=\"" << tool << "\"\n";
1023 linkOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
1024 // Use the NOINHERIT macro to avoid getting VS project default
1025 // libraries which may be set by the user to something bad.
1026 fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
1027 << this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
1028 << " ";
1029 this->Internal->OutputLibraries(fout, cli.GetItems());
1030 fout << "\"\n";
1031 temp = target.GetDirectory(configName);
1032 temp += "/";
1033 temp += targetNameFull;
1034 fout << "\t\t\t\tOutputFile=\""
1035 << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
1036 this->WriteTargetVersionAttribute(fout, target);
1037 linkOptions.OutputFlagMap(fout, "\t\t\t\t");
1038 fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
1039 this->OutputLibraryDirectories(fout, cli.GetDirectories());
1040 fout << "\"\n";
1041 fout << "\t\t\t\tProgramDataBaseFile=\""
1042 << target.GetDirectory(configName) << "/" << targetNamePDB
1043 << "\"\n";
1044 if(isDebug)
1046 fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
1048 if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
1050 fout << "\t\t\t\tSubSystem=\"2\"\n";
1052 else
1054 fout << "\t\t\t\tSubSystem=\"1\"\n";
1056 std::string stackVar = "CMAKE_";
1057 stackVar += linkLanguage;
1058 stackVar += "_STACK_SIZE";
1059 const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
1060 if(stackVal)
1062 fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
1064 temp = target.GetDirectory(configName, true);
1065 temp += "/";
1066 temp += targetNameImport;
1067 fout << "\t\t\t\tImportLibrary=\""
1068 << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
1069 break;
1071 case cmTarget::UTILITY:
1072 case cmTarget::GLOBAL_TARGET:
1073 break;
1077 //----------------------------------------------------------------------------
1078 void
1079 cmLocalVisualStudio7Generator
1080 ::WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target)
1082 int major;
1083 int minor;
1084 target.GetTargetVersion(major, minor);
1085 fout << "\t\t\t\tVersion=\"" << major << "." << minor << "\"\n";
1088 void cmLocalVisualStudio7Generator
1089 ::OutputModuleDefinitionFile(std::ostream& fout,
1090 cmTarget &target)
1092 std::vector<cmSourceFile*> const& classes = target.GetSourceFiles();
1093 for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
1094 i != classes.end(); i++)
1096 cmSourceFile* sf = *i;
1097 if(cmSystemTools::UpperCase(sf->GetExtension()) == "DEF")
1099 fout << "\t\t\t\tModuleDefinitionFile=\""
1100 << this->ConvertToXMLOutputPath(sf->GetFullPath().c_str())
1101 << "\"\n";
1102 return;
1108 //----------------------------------------------------------------------------
1109 void
1110 cmLocalVisualStudio7GeneratorInternals
1111 ::OutputLibraries(std::ostream& fout, ItemVector const& libs)
1113 cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
1114 for(ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l)
1116 if(l->IsPath)
1118 std::string rel = lg->Convert(l->Value.c_str(),
1119 cmLocalGenerator::START_OUTPUT,
1120 cmLocalGenerator::UNCHANGED);
1121 fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " ";
1123 else
1125 fout << l->Value << " ";
1130 //----------------------------------------------------------------------------
1131 void
1132 cmLocalVisualStudio7Generator
1133 ::OutputLibraryDirectories(std::ostream& fout,
1134 std::vector<std::string> const& dirs)
1136 const char* comma = "";
1137 for(std::vector<std::string>::const_iterator d = dirs.begin();
1138 d != dirs.end(); ++d)
1140 // Remove any trailing slash and skip empty paths.
1141 std::string dir = *d;
1142 if(dir[dir.size()-1] == '/')
1144 dir = dir.substr(0, dir.size()-1);
1146 if(dir.empty())
1148 continue;
1151 // Switch to a relative path specification if it is shorter.
1152 if(cmSystemTools::FileIsFullPath(dir.c_str()))
1154 std::string rel = this->Convert(dir.c_str(), START_OUTPUT, UNCHANGED);
1155 if(rel.size() < dir.size())
1157 dir = rel;
1161 // First search a configuration-specific subdirectory and then the
1162 // original directory.
1163 fout << comma << this->ConvertToXMLOutputPath((dir+"/$(OutDir)").c_str())
1164 << "," << this->ConvertToXMLOutputPath(dir.c_str());
1165 comma = ",";
1169 void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
1170 const char *libName,
1171 cmTarget &target)
1173 // get the configurations
1174 std::vector<std::string> *configs =
1175 static_cast<cmGlobalVisualStudio7Generator *>
1176 (this->GlobalGenerator)->GetConfigurations();
1178 // We may be modifying the source groups temporarily, so make a copy.
1179 std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
1181 // get the classes from the source lists then add them to the groups
1182 std::vector<cmSourceFile*>const & classes = target.GetSourceFiles();
1183 for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
1184 i != classes.end(); i++)
1186 // Add the file to the list of sources.
1187 std::string source = (*i)->GetFullPath();
1188 if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF")
1190 this->ModuleDefinitionFile = (*i)->GetFullPath();
1192 cmSourceGroup& sourceGroup =
1193 this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
1194 sourceGroup.AssignSource(*i);
1197 // Compute which sources need unique object computation.
1198 this->ComputeObjectNameRequirements(sourceGroups);
1200 // open the project
1201 this->WriteProjectStart(fout, libName, target, sourceGroups);
1202 // write the configuration information
1203 this->WriteConfigurations(fout, libName, target);
1205 fout << "\t<Files>\n";
1208 // Loop through every source group.
1209 for(unsigned int i = 0; i < sourceGroups.size(); ++i)
1211 cmSourceGroup sg = sourceGroups[i];
1212 this->WriteGroup(&sg, target, fout, libName, configs);
1217 fout << "\t</Files>\n";
1219 // Write the VCProj file's footer.
1220 this->WriteVCProjFooter(fout);
1223 struct cmLVS7GFileConfig
1225 std::string ObjectName;
1226 std::string CompileFlags;
1227 std::string CompileDefs;
1228 std::string CompileDefsConfig;
1229 std::string AdditionalDeps;
1230 bool ExcludedFromBuild;
1233 class cmLocalVisualStudio7GeneratorFCInfo
1235 public:
1236 cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
1237 cmTarget& target,
1238 cmSourceFile const& sf,
1239 std::vector<std::string>* configs,
1240 std::string const& dir_max);
1241 std::map<cmStdString, cmLVS7GFileConfig> FileConfigMap;
1244 cmLocalVisualStudio7GeneratorFCInfo
1245 ::cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
1246 cmTarget& target,
1247 cmSourceFile const& sf,
1248 std::vector<std::string>* configs,
1249 std::string const& dir_max)
1251 std::string objectName;
1252 if(lg->NeedObjectName.find(&sf) != lg->NeedObjectName.end())
1254 objectName = lg->GetObjectFileNameWithoutTarget(sf, dir_max);
1257 // Compute per-source, per-config information.
1258 for(std::vector<std::string>::iterator i = configs->begin();
1259 i != configs->end(); ++i)
1261 std::string configUpper = cmSystemTools::UpperCase(*i);
1262 cmLVS7GFileConfig fc;
1263 bool needfc = false;
1264 if(!objectName.empty())
1266 fc.ObjectName = objectName;
1267 needfc = true;
1269 if(const char* cflags = sf.GetProperty("COMPILE_FLAGS"))
1271 fc.CompileFlags = cflags;
1272 needfc = true;
1274 if(const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS"))
1276 fc.CompileDefs = cdefs;
1277 needfc = true;
1279 std::string defPropName = "COMPILE_DEFINITIONS_";
1280 defPropName += configUpper;
1281 if(const char* ccdefs = sf.GetProperty(defPropName.c_str()))
1283 fc.CompileDefsConfig = ccdefs;
1284 needfc = true;
1287 // Check for extra object-file dependencies.
1288 if(const char* deps = sf.GetProperty("OBJECT_DEPENDS"))
1290 std::vector<std::string> depends;
1291 cmSystemTools::ExpandListArgument(deps, depends);
1292 const char* sep = "";
1293 for(std::vector<std::string>::iterator j = depends.begin();
1294 j != depends.end(); ++j)
1296 fc.AdditionalDeps += sep;
1297 fc.AdditionalDeps += lg->ConvertToXMLOutputPath(j->c_str());
1298 sep = ";";
1299 needfc = true;
1303 const char* lang =
1304 lg->GlobalGenerator->GetLanguageFromExtension
1305 (sf.GetExtension().c_str());
1306 const char* sourceLang = lg->GetSourceFileLanguage(sf);
1307 const char* linkLanguage = target.GetLinkerLanguage(i->c_str());
1308 bool needForceLang = false;
1309 // source file does not match its extension language
1310 if(lang && sourceLang && strcmp(lang, sourceLang) != 0)
1312 needForceLang = true;
1313 lang = sourceLang;
1315 // If HEADER_FILE_ONLY is set, we must suppress this generation in
1316 // the project file
1317 fc.ExcludedFromBuild =
1318 (sf.GetPropertyAsBool("HEADER_FILE_ONLY"));
1319 if(fc.ExcludedFromBuild)
1321 needfc = true;
1324 // if the source file does not match the linker language
1325 // then force c or c++
1326 if(needForceLang || (linkLanguage && lang
1327 && strcmp(lang, linkLanguage) != 0))
1329 if(strcmp(lang, "CXX") == 0)
1331 // force a C++ file type
1332 fc.CompileFlags += " /TP ";
1333 needfc = true;
1335 else if(strcmp(lang, "C") == 0)
1337 // force to c
1338 fc.CompileFlags += " /TC ";
1339 needfc = true;
1343 if(needfc)
1345 this->FileConfigMap[*i] = fc;
1351 void cmLocalVisualStudio7Generator
1352 ::ComputeMaxDirectoryLength(std::string& maxdir,
1353 cmTarget& target)
1355 std::vector<std::string> *configs =
1356 static_cast<cmGlobalVisualStudio7Generator *>
1357 (this->GlobalGenerator)->GetConfigurations();
1358 // Compute the maximum length configuration name.
1359 std::string config_max;
1360 for(std::vector<std::string>::iterator i = configs->begin();
1361 i != configs->end(); ++i)
1363 if(i->size() > config_max.size())
1365 config_max = *i;
1369 // Compute the maximum length full path to the intermediate
1370 // files directory for any configuration. This is used to construct
1371 // object file names that do not produce paths that are too long.
1372 std::string dir_max;
1373 dir_max += this->Makefile->GetCurrentOutputDirectory();
1374 dir_max += "/";
1375 dir_max += this->GetTargetDirectory(target);
1376 dir_max += "/";
1377 dir_max += config_max;
1378 dir_max += "/";
1379 maxdir = dir_max;
1382 void cmLocalVisualStudio7Generator
1383 ::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
1384 std::ostream &fout, const char *libName,
1385 std::vector<std::string> *configs)
1387 const std::vector<const cmSourceFile *> &sourceFiles =
1388 sg->GetSourceFiles();
1389 // If the group is empty, don't write it at all.
1390 if(sourceFiles.empty() && sg->GetGroupChildren().empty())
1392 return;
1395 // If the group has a name, write the header.
1396 std::string name = sg->GetName();
1397 if(name != "")
1399 this->WriteVCProjBeginGroup(fout, name.c_str(), "");
1402 // Compute the maximum length full path to the intermediate
1403 // files directory for any configuration. This is used to construct
1404 // object file names that do not produce paths that are too long.
1405 std::string dir_max;
1406 this->ComputeMaxDirectoryLength(dir_max, target);
1408 // Loop through each source in the source group.
1409 std::string objectName;
1410 for(std::vector<const cmSourceFile *>::const_iterator sf =
1411 sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
1413 std::string source = (*sf)->GetFullPath();
1414 FCInfo fcinfo(this, target, *(*sf), configs, dir_max);
1416 if (source != libName || target.GetType() == cmTarget::UTILITY ||
1417 target.GetType() == cmTarget::GLOBAL_TARGET )
1419 fout << "\t\t\t<File\n";
1420 std::string d = this->ConvertToXMLOutputPathSingle(source.c_str());
1421 // Tell MS-Dev what the source is. If the compiler knows how to
1422 // build it, then it will.
1423 fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
1424 if(cmCustomCommand const* command = (*sf)->GetCustomCommand())
1426 this->WriteCustomRule(fout, source.c_str(), *command, fcinfo);
1428 else if(!fcinfo.FileConfigMap.empty())
1430 const char* aCompilerTool = "VCCLCompilerTool";
1431 std::string ext = (*sf)->GetExtension();
1432 ext = cmSystemTools::LowerCase(ext);
1433 if(ext == "idl")
1435 aCompilerTool = "VCMIDLTool";
1436 if(this->FortranProject)
1438 aCompilerTool = "VFMIDLTool";
1441 if(ext == "rc")
1443 aCompilerTool = "VCResourceCompilerTool";
1444 if(this->FortranProject)
1446 aCompilerTool = "VFResourceCompilerTool";
1449 if(ext == "def")
1451 aCompilerTool = "VCCustomBuildTool";
1452 if(this->FortranProject)
1454 aCompilerTool = "VFCustomBuildTool";
1457 for(std::map<cmStdString, cmLVS7GFileConfig>::const_iterator
1458 fci = fcinfo.FileConfigMap.begin();
1459 fci != fcinfo.FileConfigMap.end(); ++fci)
1461 cmLVS7GFileConfig const& fc = fci->second;
1462 fout << "\t\t\t\t<FileConfiguration\n"
1463 << "\t\t\t\t\tName=\"" << fci->first
1464 << "|" << this->PlatformName << "\"";
1465 if(fc.ExcludedFromBuild)
1467 fout << " ExcludedFromBuild=\"true\"";
1469 fout << ">\n";
1470 fout << "\t\t\t\t\t<Tool\n"
1471 << "\t\t\t\t\tName=\"" << aCompilerTool << "\"\n";
1472 if(!fc.CompileFlags.empty() ||
1473 !fc.CompileDefs.empty() ||
1474 !fc.CompileDefsConfig.empty())
1476 Options fileOptions(this, this->Version, Options::Compiler,
1477 cmLocalVisualStudio7GeneratorFlagTable,
1478 this->ExtraFlagTable);
1479 fileOptions.Parse(fc.CompileFlags.c_str());
1480 fileOptions.AddDefines(fc.CompileDefs.c_str());
1481 fileOptions.AddDefines(fc.CompileDefsConfig.c_str());
1482 fileOptions.OutputAdditionalOptions(fout, "\t\t\t\t\t", "\n");
1483 fileOptions.OutputFlagMap(fout, "\t\t\t\t\t");
1484 fileOptions.OutputPreprocessorDefinitions(fout,
1485 "\t\t\t\t\t", "\n");
1487 if(!fc.AdditionalDeps.empty())
1489 fout << "\t\t\t\t\tAdditionalDependencies=\""
1490 << fc.AdditionalDeps.c_str() << "\"\n";
1492 if(!fc.ObjectName.empty())
1494 fout << "\t\t\t\t\tObjectFile=\"$(IntDir)/"
1495 << fc.ObjectName.c_str() << "\"\n";
1497 fout << "\t\t\t\t\t/>\n"
1498 << "\t\t\t\t</FileConfiguration>\n";
1501 fout << "\t\t\t</File>\n";
1505 std::vector<cmSourceGroup> const& children = sg->GetGroupChildren();
1507 for(unsigned int i=0;i<children.size();++i)
1509 this->WriteGroup(&children[i], target, fout, libName, configs);
1512 // If the group has a name, write the footer.
1513 if(name != "")
1515 this->WriteVCProjEndGroup(fout);
1519 void cmLocalVisualStudio7Generator::
1520 WriteCustomRule(std::ostream& fout,
1521 const char* source,
1522 const cmCustomCommand& command,
1523 FCInfo& fcinfo)
1525 std::string comment = this->ConstructComment(command);
1527 // Write the rule for each configuration.
1528 std::vector<std::string>::iterator i;
1529 std::vector<std::string> *configs =
1530 static_cast<cmGlobalVisualStudio7Generator *>
1531 (this->GlobalGenerator)->GetConfigurations();
1532 const char* compileTool = "VCCLCompilerTool";
1533 if(this->FortranProject)
1535 compileTool = "VFCLCompilerTool";
1537 const char* customTool = "VCCustomBuildTool";
1538 if(this->FortranProject)
1540 customTool = "VFCustomBuildTool";
1542 for(i = configs->begin(); i != configs->end(); ++i)
1544 cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[*i];
1545 fout << "\t\t\t\t<FileConfiguration\n";
1546 fout << "\t\t\t\t\tName=\"" << *i << "|" << this->PlatformName << "\">\n";
1547 if(!fc.CompileFlags.empty())
1549 fout << "\t\t\t\t\t<Tool\n"
1550 << "\t\t\t\t\tName=\"" << compileTool << "\"\n"
1551 << "\t\t\t\t\tAdditionalOptions=\""
1552 << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
1555 std::string script =
1556 this->ConstructScript(command.GetCommandLines(),
1557 command.GetWorkingDirectory(),
1558 i->c_str(),
1559 command.GetEscapeOldStyle(),
1560 command.GetEscapeAllowMakeVars());
1561 fout << "\t\t\t\t\t<Tool\n"
1562 << "\t\t\t\t\tName=\"" << customTool << "\"\n"
1563 << "\t\t\t\t\tDescription=\""
1564 << this->EscapeForXML(comment.c_str()) << "\"\n"
1565 << "\t\t\t\t\tCommandLine=\""
1566 << this->EscapeForXML(script.c_str()) << "\"\n"
1567 << "\t\t\t\t\tAdditionalDependencies=\"";
1568 if(command.GetDepends().empty())
1570 // There are no real dependencies. Produce an artificial one to
1571 // make sure the rule runs reliably.
1572 if(!cmSystemTools::FileExists(source))
1574 std::ofstream depout(source);
1575 depout << "Artificial dependency for a custom command.\n";
1577 fout << this->ConvertToXMLOutputPath(source);
1579 else
1581 // Write out the dependencies for the rule.
1582 for(std::vector<std::string>::const_iterator d =
1583 command.GetDepends().begin();
1584 d != command.GetDepends().end();
1585 ++d)
1587 // Get the real name of the dependency in case it is a CMake target.
1588 std::string dep = this->GetRealDependency(d->c_str(), i->c_str());
1589 fout << this->ConvertToXMLOutputPath(dep.c_str())
1590 << ";";
1593 fout << "\"\n";
1594 fout << "\t\t\t\t\tOutputs=\"";
1595 if(command.GetOutputs().empty())
1597 fout << source << "_force";
1599 else
1601 // Write a rule for the output generated by this command.
1602 const char* sep = "";
1603 for(std::vector<std::string>::const_iterator o =
1604 command.GetOutputs().begin();
1605 o != command.GetOutputs().end();
1606 ++o)
1608 fout << sep << this->ConvertToXMLOutputPathSingle(o->c_str());
1609 sep = ";";
1612 fout << "\"/>\n";
1613 fout << "\t\t\t\t</FileConfiguration>\n";
1618 void cmLocalVisualStudio7Generator::WriteVCProjBeginGroup(std::ostream& fout,
1619 const char* group,
1620 const char* )
1622 fout << "\t\t<Filter\n"
1623 << "\t\t\tName=\"" << group << "\"\n"
1624 << "\t\t\tFilter=\"\">\n";
1628 void cmLocalVisualStudio7Generator::WriteVCProjEndGroup(std::ostream& fout)
1630 fout << "\t\t</Filter>\n";
1634 // look for custom rules on a target and collect them together
1635 void cmLocalVisualStudio7Generator
1636 ::OutputTargetRules(std::ostream& fout,
1637 const char* configName,
1638 cmTarget &target,
1639 const char * /*libName*/)
1641 if (target.GetType() > cmTarget::GLOBAL_TARGET)
1643 return;
1645 EventWriter event(this, configName, fout);
1647 // Add pre-build event.
1648 const char* tool =
1649 this->FortranProject? "VFPreBuildEventTool":"VCPreBuildEventTool";
1650 event.Start(tool);
1651 event.Write(target.GetPreBuildCommands());
1652 event.Finish();
1654 // Add pre-link event.
1655 tool = this->FortranProject? "VFPreLinkEventTool":"VCPreLinkEventTool";
1656 event.Start(tool);
1657 event.Write(target.GetPreLinkCommands());
1658 cmsys::auto_ptr<cmCustomCommand> pcc(
1659 this->MaybeCreateImplibDir(target, configName));
1660 if(pcc.get())
1662 event.Write(*pcc);
1664 event.Finish();
1666 // Add post-build event.
1667 tool = this->FortranProject? "VFPostBuildEventTool":"VCPostBuildEventTool";
1668 event.Start(tool);
1669 event.Write(target.GetPostBuildCommands());
1670 event.Finish();
1673 void
1674 cmLocalVisualStudio7Generator
1675 ::WriteProjectStartFortran(std::ostream& fout,
1676 const char *libName,
1677 cmTarget & target)
1680 cmGlobalVisualStudio7Generator* gg =
1681 static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
1683 // Compute the version of the Intel plugin to the VS IDE.
1684 // If the key does not exist then use a default guess.
1685 std::string intelVersion = "9.10";
1686 std::string vskey = gg->GetRegistryBase();
1687 vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
1688 cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
1689 cmSystemTools::KeyWOW64_32);
1691 fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
1692 << "<VisualStudioProject\n"
1693 << "\tProjectCreator=\"Intel Fortran\"\n"
1694 << "\tVersion=\"" << intelVersion << "\"\n";
1695 const char* keyword = target.GetProperty("VS_KEYWORD");
1696 if(!keyword)
1698 keyword = "Console Application";
1700 const char* projectType = 0;
1701 switch(target.GetType())
1703 case cmTarget::STATIC_LIBRARY:
1704 projectType = "typeStaticLibrary";
1705 if(keyword)
1707 keyword = "Static Library";
1709 break;
1710 case cmTarget::SHARED_LIBRARY:
1711 case cmTarget::MODULE_LIBRARY:
1712 projectType = "typeDynamicLibrary";
1713 if(!keyword)
1715 keyword = "Dll";
1717 break;
1718 case cmTarget::EXECUTABLE:
1719 if(!keyword)
1721 keyword = "Console Application";
1723 projectType = 0;
1724 break;
1725 case cmTarget::UTILITY:
1726 case cmTarget::GLOBAL_TARGET:
1727 default:
1728 break;
1730 if(projectType)
1732 fout << "\tProjectType=\"" << projectType << "\"\n";
1734 fout<< "\tKeyword=\"" << keyword << "\">\n"
1735 << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\">\n"
1736 << "\t<Platforms>\n"
1737 << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n"
1738 << "\t</Platforms>\n";
1742 void
1743 cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout,
1744 const char *libName,
1745 cmTarget & target,
1746 std::vector<cmSourceGroup> &)
1748 if(this->FortranProject)
1750 this->WriteProjectStartFortran(fout, libName, target);
1751 return;
1753 fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
1754 << "<VisualStudioProject\n"
1755 << "\tProjectType=\"Visual C++\"\n";
1756 if(this->Version == 71)
1758 fout << "\tVersion=\"7.10\"\n";
1760 else
1762 fout << "\tVersion=\"" << this->Version << ".00\"\n";
1764 const char* projLabel = target.GetProperty("PROJECT_LABEL");
1765 if(!projLabel)
1767 projLabel = libName;
1769 const char* keyword = target.GetProperty("VS_KEYWORD");
1770 if(!keyword)
1772 keyword = "Win32Proj";
1774 const char* vsProjectname = target.GetProperty("VS_SCC_PROJECTNAME");
1775 const char* vsLocalpath = target.GetProperty("VS_SCC_LOCALPATH");
1776 const char* vsProvider = target.GetProperty("VS_SCC_PROVIDER");
1777 cmGlobalVisualStudio7Generator* gg =
1778 static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
1779 fout << "\tName=\"" << projLabel << "\"\n";
1780 if(this->Version >= 8)
1782 fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n";
1784 // if we have all the required Source code control tags
1785 // then add that to the project
1786 if(vsProvider && vsLocalpath && vsProjectname)
1788 fout << "\tSccProjectName=\"" << vsProjectname << "\"\n"
1789 << "\tSccLocalPath=\"" << vsLocalpath << "\"\n"
1790 << "\tSccProvider=\"" << vsProvider << "\"\n";
1792 fout << "\tKeyword=\"" << keyword << "\">\n"
1793 << "\t<Platforms>\n"
1794 << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n"
1795 << "\t</Platforms>\n";
1799 void cmLocalVisualStudio7Generator::WriteVCProjFooter(std::ostream& fout)
1801 fout << "\t<Globals>\n"
1802 << "\t</Globals>\n"
1803 << "</VisualStudioProject>\n";
1806 std::string cmLocalVisualStudio7GeneratorEscapeForXML(const char* s)
1808 std::string ret = s;
1809 cmSystemTools::ReplaceString(ret, "&", "&amp;");
1810 cmSystemTools::ReplaceString(ret, "\"", "&quot;");
1811 cmSystemTools::ReplaceString(ret, "<", "&lt;");
1812 cmSystemTools::ReplaceString(ret, ">", "&gt;");
1813 cmSystemTools::ReplaceString(ret, "\n", "&#x0D;&#x0A;");
1814 return ret;
1817 std::string cmLocalVisualStudio7Generator::EscapeForXML(const char* s)
1819 return cmLocalVisualStudio7GeneratorEscapeForXML(s);
1822 std::string cmLocalVisualStudio7Generator
1823 ::ConvertToXMLOutputPath(const char* path)
1825 std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
1826 cmSystemTools::ReplaceString(ret, "&", "&amp;");
1827 cmSystemTools::ReplaceString(ret, "\"", "&quot;");
1828 cmSystemTools::ReplaceString(ret, "<", "&lt;");
1829 cmSystemTools::ReplaceString(ret, ">", "&gt;");
1830 return ret;
1833 std::string cmLocalVisualStudio7Generator
1834 ::ConvertToXMLOutputPathSingle(const char* path)
1836 std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
1837 cmSystemTools::ReplaceString(ret, "\"", "");
1838 cmSystemTools::ReplaceString(ret, "&", "&amp;");
1839 cmSystemTools::ReplaceString(ret, "<", "&lt;");
1840 cmSystemTools::ReplaceString(ret, ">", "&gt;");
1841 return ret;
1845 // This class is used to parse an existing vs 7 project
1846 // and extract the GUID
1847 class cmVS7XMLParser : public cmXMLParser
1849 public:
1850 virtual void EndElement(const char* /* name */)
1853 virtual void StartElement(const char* name, const char** atts)
1855 // once the GUID is found do nothing
1856 if(this->GUID.size())
1858 return;
1860 int i =0;
1861 if(strcmp("VisualStudioProject", name) == 0)
1863 while(atts[i])
1865 if(strcmp(atts[i], "ProjectGUID") == 0)
1867 if(atts[i+1])
1869 this->GUID = atts[i+1];
1870 this->GUID = this->GUID.substr(1, this->GUID.size()-2);
1872 else
1874 this->GUID = "";
1876 return;
1878 ++i;
1882 int InitializeParser()
1884 int ret = cmXMLParser::InitializeParser();
1885 if(ret == 0)
1887 return ret;
1889 // visual studio projects have a strange encoding, but it is
1890 // really utf-8
1891 XML_SetEncoding(static_cast<XML_Parser>(this->Parser), "utf-8");
1892 return 1;
1894 std::string GUID;
1897 void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
1898 const char* name,
1899 const char* path)
1901 cmVS7XMLParser parser;
1902 parser.ParseFile(path);
1903 // if we can not find a GUID then create one
1904 if(parser.GUID.size() == 0)
1906 cmGlobalVisualStudio7Generator* gg =
1907 static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
1908 gg->CreateGUID(name);
1909 return;
1911 std::string guidStoreName = name;
1912 guidStoreName += "_GUID_CMAKE";
1913 // save the GUID in the cache
1914 this->GlobalGenerator->GetCMakeInstance()->
1915 AddCacheEntry(guidStoreName.c_str(),
1916 parser.GUID.c_str(),
1917 "Stored GUID",
1918 cmCacheManager::INTERNAL);
1922 void cmLocalVisualStudio7Generator::ConfigureFinalPass()
1924 cmLocalGenerator::ConfigureFinalPass();
1925 cmTargets &tgts = this->Makefile->GetTargets();
1927 cmGlobalVisualStudio7Generator* gg =
1928 static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
1929 for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
1931 const char* path = l->second.GetProperty("EXTERNAL_MSPROJECT");
1932 if(path)
1934 this->ReadAndStoreExternalGUID(
1935 l->second.GetName(), path);
1937 else
1939 gg->CreateGUID(l->first.c_str());
1945 //----------------------------------------------------------------------------
1946 std::string cmLocalVisualStudio7Generator
1947 ::GetTargetDirectory(cmTarget const& target) const
1949 std::string dir;
1950 dir += target.GetName();
1951 dir += ".dir";
1952 return dir;
1955 void cmLocalVisualStudio7Generator::
1956 GetTargetObjectFileDirectories(cmTarget* target,
1957 std::vector<std::string>&
1958 dirs)
1960 std::string dir = this->Makefile->GetCurrentOutputDirectory();
1961 dir += "/";
1962 dir += this->GetTargetDirectory(*target);
1963 dir += "/";
1964 dir += this->GetGlobalGenerator()->GetCMakeCFGInitDirectory();
1965 dirs.push_back(dir);
1968 //----------------------------------------------------------------------------
1969 #include <windows.h>
1970 static bool cmLVS6G_IsFAT(const char* dir)
1972 if(dir[0] && dir[1] == ':')
1974 char volRoot[4] = "_:/";
1975 volRoot[0] = dir[0];
1976 char fsName[16];
1977 if(GetVolumeInformation(volRoot, 0, 0, 0, 0, 0, fsName, 16) &&
1978 strstr(fsName, "FAT") != 0)
1980 return true;
1983 return false;