1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmGlobalVisualStudio7Generator.h"
13 #include "cmLocalVisualStudio7Generator.h"
14 #include "cmXMLParser.h"
16 #include "cmMakefile.h"
17 #include "cmSystemTools.h"
18 #include "cmSourceFile.h"
19 #include "cmCacheManager.h"
20 #include "cmGeneratorTarget.h"
23 #include "cmComputeLinkInformation.h"
24 #include "cmGeneratedFileStream.h"
26 #include <cmsys/System.h>
28 #include <ctype.h> // for isspace
30 // Package GUID of Intel Visual Fortran plugin to VS IDE
31 #define CM_INTEL_PLUGIN_GUID "{B68A201D-CB9B-47AF-A52F-7EEC72E217E4}"
33 static bool cmLVS6G_IsFAT(const char* dir);
35 class cmLocalVisualStudio7GeneratorInternals
38 cmLocalVisualStudio7GeneratorInternals(cmLocalVisualStudio7Generator* e):
40 typedef cmComputeLinkInformation::ItemVector ItemVector;
41 void OutputLibraries(std::ostream& fout, ItemVector const& libs);
42 void OutputObjects(std::ostream& fout, cmTarget* t, const char* isep = 0);
44 cmLocalVisualStudio7Generator* LocalGenerator;
47 extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
49 //----------------------------------------------------------------------------
50 cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator(VSVersion v):
51 cmLocalVisualStudioGenerator(v)
53 this->PlatformName = "Win32";
54 this->ExtraFlagTable = 0;
55 this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
58 cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
60 delete this->Internal;
63 void cmLocalVisualStudio7Generator::AddHelperCommands()
65 std::set<cmStdString> lang;
71 lang.insert("Fortran");
72 this->CreateCustomTargetsAndCommands(lang);
74 // Now create GUIDs for targets
75 cmTargets &tgts = this->Makefile->GetTargets();
77 cmGlobalVisualStudio7Generator* gg =
78 static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
79 for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
81 const char* path = l->second.GetProperty("EXTERNAL_MSPROJECT");
84 this->ReadAndStoreExternalGUID(
85 l->second.GetName(), path);
89 gg->CreateGUID(l->first.c_str());
94 this->FixGlobalTargets();
97 void cmLocalVisualStudio7Generator::Generate()
99 this->WriteProjectFiles();
100 this->WriteStampFiles();
103 void cmLocalVisualStudio7Generator::AddCMakeListsRules()
105 cmTargets &tgts = this->Makefile->GetTargets();
106 // Create the regeneration custom rule.
107 if(!this->Makefile->IsOn("CMAKE_SUPPRESS_REGENERATION"))
109 // Create a rule to regenerate the build system when the target
110 // specification source changes.
111 if(cmSourceFile* sf = this->CreateVCProjBuildRule())
113 // Add the rule to targets that need it.
114 for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
116 if(l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
118 l->second.AddSourceFile(sf);
125 void cmLocalVisualStudio7Generator::FixGlobalTargets()
127 // Visual Studio .NET 2003 Service Pack 1 will not run post-build
128 // commands for targets in which no sources are built. Add dummy
129 // rules to force these targets to build.
130 cmTargets &tgts = this->Makefile->GetTargets();
131 for(cmTargets::iterator l = tgts.begin();
132 l != tgts.end(); l++)
134 cmTarget& tgt = l->second;
135 if(tgt.GetType() == cmTarget::GLOBAL_TARGET)
137 std::vector<std::string> no_depends;
138 cmCustomCommandLine force_command;
139 force_command.push_back("cd");
140 force_command.push_back(".");
141 cmCustomCommandLines force_commands;
142 force_commands.push_back(force_command);
143 const char* no_main_dependency = 0;
144 std::string force = this->Makefile->GetStartOutputDirectory();
145 force += cmake::GetCMakeFilesDirectory();
147 force += tgt.GetName();
149 if(cmSourceFile* file =
150 this->Makefile->AddCustomCommandToOutput(
151 force.c_str(), no_depends, no_main_dependency,
152 force_commands, " ", 0, true))
154 tgt.AddSourceFile(file);
161 // for CommandLine= need to repleace quotes with "
162 // write out configurations
163 void cmLocalVisualStudio7Generator::WriteProjectFiles()
165 // If not an in source build, then create the output directory
166 if(strcmp(this->Makefile->GetStartOutputDirectory(),
167 this->Makefile->GetHomeDirectory()) != 0)
169 if(!cmSystemTools::MakeDirectory
170 (this->Makefile->GetStartOutputDirectory()))
172 cmSystemTools::Error("Error creating directory ",
173 this->Makefile->GetStartOutputDirectory());
177 // Get the set of targets in this directory.
178 cmTargets &tgts = this->Makefile->GetTargets();
180 // Create the project file for each target.
181 for(cmTargets::iterator l = tgts.begin();
182 l != tgts.end(); l++)
184 // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
185 // so don't build a projectfile for it
186 if(!l->second.GetProperty("EXTERNAL_MSPROJECT"))
188 this->CreateSingleVCProj(l->first.c_str(),l->second);
193 //----------------------------------------------------------------------------
194 void cmLocalVisualStudio7Generator::WriteStampFiles()
196 // Touch a timestamp file used to determine when the project file is
198 std::string stampName = this->Makefile->GetStartOutputDirectory();
199 stampName += cmake::GetCMakeFilesDirectory();
200 cmSystemTools::MakeDirectory(stampName.c_str());
202 stampName += "generate.stamp";
203 std::ofstream stamp(stampName.c_str());
204 stamp << "# CMake generation timestamp file for this directory.\n";
206 // Create a helper file so CMake can determine when it is run
207 // through the rule created by CreateVCProjBuildRule whether it
208 // really needs to regenerate the project. This file lists its own
209 // dependencies. If any file listed in it is newer than itself then
210 // CMake must rerun. Otherwise the project files are up to date and
211 // the stamp file can just be touched.
212 std::string depName = stampName;
213 depName += ".depend";
214 std::ofstream depFile(depName.c_str());
215 depFile << "# CMake generation dependency list for this directory.\n";
216 std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
217 for(std::vector<std::string>::const_iterator lf = listFiles.begin();
218 lf != listFiles.end(); ++lf)
220 depFile << *lf << std::endl;
224 //----------------------------------------------------------------------------
225 void cmLocalVisualStudio7Generator
226 ::CreateSingleVCProj(const char *lname, cmTarget &target)
228 this->FortranProject =
229 static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
230 ->TargetIsFortranOnly(target);
231 this->WindowsCEProject =
232 static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
233 ->TargetsWindowsCE();
235 // Intel Fortran for VS10 uses VS9 format ".vfproj" files.
236 VSVersion realVersion = this->Version;
237 if(this->FortranProject && this->Version >= VS10)
242 // add to the list of projects
243 std::string pname = lname;
244 target.SetProperty("GENERATOR_FILE_NAME",lname);
245 // create the dsp.cmake file
247 fname = this->Makefile->GetStartOutputDirectory();
250 if(this->FortranProject)
259 // Generate the project file and replace it atomically with
260 // copy-if-different. We use a separate timestamp so that the IDE
261 // does not reload project files unnecessarily.
262 cmGeneratedFileStream fout(fname.c_str());
263 fout.SetCopyIfDifferent(true);
264 this->WriteVCProjFile(fout,lname,target);
267 this->GlobalGenerator->FileReplacedDuringGenerate(fname);
270 this->Version = realVersion;
273 //----------------------------------------------------------------------------
274 cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
276 std::string stampName = this->Makefile->GetCurrentOutputDirectory();
278 stampName += cmake::GetCMakeFilesDirectoryPostSlash();
279 stampName += "generate.stamp";
280 const char* dsprule =
281 this->Makefile->GetRequiredDefinition("CMAKE_COMMAND");
282 cmCustomCommandLine commandLine;
283 commandLine.push_back(dsprule);
284 std::string makefileIn = this->Makefile->GetStartDirectory();
286 makefileIn += "CMakeLists.txt";
287 makefileIn = cmSystemTools::CollapseFullPath(makefileIn.c_str());
288 if(!cmSystemTools::FileExists(makefileIn.c_str()))
292 std::string comment = "Building Custom Rule ";
293 comment += makefileIn;
296 args += this->Convert(this->Makefile->GetHomeDirectory(),
297 START_OUTPUT, UNCHANGED, true);
298 commandLine.push_back(args);
301 this->Convert(this->Makefile->GetHomeOutputDirectory(),
302 START_OUTPUT, UNCHANGED, true);
303 commandLine.push_back(args);
304 commandLine.push_back("--check-stamp-file");
305 std::string stampFilename = this->Convert(stampName.c_str(), FULL,
307 commandLine.push_back(stampFilename.c_str());
309 std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
311 cmCustomCommandLines commandLines;
312 commandLines.push_back(commandLine);
313 const char* no_working_directory = 0;
314 std::string fullpathStampName = this->Convert(stampName.c_str(), FULL,
316 this->Makefile->AddCustomCommandToOutput(fullpathStampName.c_str(),
317 listFiles, makefileIn.c_str(),
318 commandLines, comment.c_str(),
319 no_working_directory, true);
320 if(cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str()))
326 cmSystemTools::Error("Error adding rule for ", makefileIn.c_str());
331 void cmLocalVisualStudio7Generator::WriteConfigurations(std::ostream& fout,
335 std::vector<std::string> *configs =
336 static_cast<cmGlobalVisualStudio7Generator *>
337 (this->GlobalGenerator)->GetConfigurations();
339 fout << "\t<Configurations>\n";
340 for( std::vector<std::string>::iterator i = configs->begin();
341 i != configs->end(); ++i)
343 this->WriteConfiguration(fout, i->c_str(), libName, target);
345 fout << "\t</Configurations>\n";
347 cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] =
349 {"Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0},
350 {"SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0},
351 {"SourceFileFormat", "fixed", "Use Fixed Format", "fileFormatFixed", 0},
352 {"SourceFileFormat", "free", "Use Free Format", "fileFormatFree", 0},
353 {"DebugInformationFormat", "Zi", "full debug", "debugEnabled", 0},
354 {"DebugInformationFormat", "debug:full", "full debug", "debugEnabled", 0},
355 {"DebugInformationFormat", "Z7", "c7 compat", "debugOldStyleInfo", 0},
356 {"DebugInformationFormat", "Zd", "line numbers", "debugLineInfoOnly", 0},
357 {"Optimization", "Od", "disable optimization", "optimizeDisabled", 0},
358 {"Optimization", "O1", "min space", "optimizeMinSpace", 0},
359 {"Optimization", "O3", "full optimize", "optimizeFull", 0},
360 {"GlobalOptimizations", "Og", "global optimize", "true", 0},
361 {"InlineFunctionExpansion", "Ob0", "", "expandDisable", 0},
362 {"InlineFunctionExpansion", "Ob1", "", "expandOnlyInline", 0},
363 {"FavorSizeOrSpeed", "Os", "", "favorSize", 0},
364 {"OmitFramePointers", "Oy-", "", "false", 0},
365 {"OptimizeForProcessor", "GB", "", "procOptimizeBlended", 0},
366 {"OptimizeForProcessor", "G5", "", "procOptimizePentium", 0},
367 {"OptimizeForProcessor", "G6", "", "procOptimizePentiumProThruIII", 0},
368 {"UseProcessorExtensions", "QzxK", "", "codeForStreamingSIMD", 0},
369 {"OptimizeForProcessor", "QaxN", "", "codeForPentium4", 0},
370 {"OptimizeForProcessor", "QaxB", "", "codeForPentiumM", 0},
371 {"OptimizeForProcessor", "QaxP", "", "codeForCodeNamedPrescott", 0},
372 {"OptimizeForProcessor", "QaxT", "", "codeForCore2Duo", 0},
373 {"OptimizeForProcessor", "QxK", "", "codeExclusivelyStreamingSIMD", 0},
374 {"OptimizeForProcessor", "QxN", "", "codeExclusivelyPentium4", 0},
375 {"OptimizeForProcessor", "QxB", "", "codeExclusivelyPentiumM", 0},
376 {"OptimizeForProcessor", "QxP", "", "codeExclusivelyCodeNamedPrescott", 0},
377 {"OptimizeForProcessor", "QxT", "", "codeExclusivelyCore2Duo", 0},
378 {"OptimizeForProcessor", "QxO", "", "codeExclusivelyCore2StreamingSIMD", 0},
379 {"OptimizeForProcessor", "QxS", "", "codeExclusivelyCore2StreamingSIMD4", 0},
381 {"ModulePath", "module:", "", "",
382 cmVS7FlagTable::UserValueRequired},
383 {"LoopUnrolling", "Qunroll:", "", "",
384 cmVS7FlagTable::UserValueRequired},
385 {"AutoParallelThreshold", "Qpar-threshold:", "", "",
386 cmVS7FlagTable::UserValueRequired},
387 {"HeapArrays", "heap-arrays:", "", "",
388 cmVS7FlagTable::UserValueRequired},
389 {"ObjectText", "bintext:", "", "",
390 cmVS7FlagTable::UserValueRequired},
391 {"Parallelization", "Qparallel", "", "true", 0},
392 {"PrefetchInsertion", "Qprefetch-", "", "false", 0},
393 {"BufferedIO", "assume:buffered_io", "", "true", 0},
394 {"CallingConvention", "iface:stdcall", "", "callConventionStdCall", 0},
395 {"CallingConvention", "iface:cref", "", "callConventionCRef", 0},
396 {"CallingConvention", "iface:stdref", "", "callConventionStdRef", 0},
397 {"CallingConvention", "iface:stdcall", "", "callConventionStdCall", 0},
398 {"CallingConvention", "iface:cvf", "", "callConventionCVF", 0},
399 {"EnableRecursion", "recursive", "", "true", 0},
400 {"ReentrantCode", "reentrancy", "", "true", 0},
401 // done up to Language
404 // fill the table here currently the comment field is not used for
405 // anything other than documentation NOTE: Make sure the longer
406 // commandFlag comes FIRST!
407 cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] =
409 // option flags (some flags map to the same option)
410 {"BasicRuntimeChecks", "GZ", "Stack frame checks", "1", 0},
411 {"BasicRuntimeChecks", "RTCsu",
412 "Both stack and uninitialized checks", "3", 0},
413 {"BasicRuntimeChecks", "RTCs", "Stack frame checks", "1", 0},
414 {"BasicRuntimeChecks", "RTCu", "Uninitialized Variables ", "2", 0},
415 {"BasicRuntimeChecks", "RTC1",
416 "Both stack and uninitialized checks", "3", 0},
417 {"DebugInformationFormat", "Z7", "debug format", "1", 0},
418 {"DebugInformationFormat", "Zd", "debug format", "2", 0},
419 {"DebugInformationFormat", "Zi", "debug format", "3", 0},
420 {"DebugInformationFormat", "ZI", "debug format", "4", 0},
421 {"EnableEnhancedInstructionSet", "arch:SSE2",
422 "Use sse2 instructions", "2", 0},
423 {"EnableEnhancedInstructionSet", "arch:SSE",
424 "Use sse instructions", "1", 0},
425 {"FloatingPointModel", "fp:precise",
426 "Use precise floating point model", "0", 0},
427 {"FloatingPointModel", "fp:strict",
428 "Use strict floating point model", "1", 0},
429 {"FloatingPointModel", "fp:fast", "Use fast floating point model", "2", 0},
430 {"FavorSizeOrSpeed", "Ot", "Favor fast code", "1", 0},
431 {"FavorSizeOrSpeed", "Os", "Favor small code", "2", 0},
432 {"CompileAs", "TC", "Compile as c code", "1", 0},
433 {"CompileAs", "TP", "Compile as c++ code", "2", 0},
434 {"Optimization", "Od", "Non Debug", "0", 0},
435 {"Optimization", "O1", "Min Size", "1", 0},
436 {"Optimization", "O2", "Max Speed", "2", 0},
437 {"Optimization", "Ox", "Max Optimization", "3", 0},
438 {"OptimizeForProcessor", "GB", "Blended processor mode", "0", 0},
439 {"OptimizeForProcessor", "G5", "Pentium", "1", 0},
440 {"OptimizeForProcessor", "G6", "PPro PII PIII", "2", 0},
441 {"OptimizeForProcessor", "G7", "Pentium 4 or Athlon", "3", 0},
442 {"InlineFunctionExpansion", "Ob0", "no inlines", "0", 0},
443 {"InlineFunctionExpansion", "Ob1", "when inline keyword", "1", 0},
444 {"InlineFunctionExpansion", "Ob2", "any time you can inline", "2", 0},
445 {"RuntimeLibrary", "MTd", "Multithreaded debug", "1", 0},
446 {"RuntimeLibrary", "MT", "Multithreaded", "0", 0},
447 {"RuntimeLibrary", "MDd", "Multithreaded dll debug", "3", 0},
448 {"RuntimeLibrary", "MD", "Multithreaded dll", "2", 0},
449 {"RuntimeLibrary", "MLd", "Single Thread debug", "5", 0},
450 {"RuntimeLibrary", "ML", "Single Thread", "4", 0},
451 {"StructMemberAlignment", "Zp16", "struct align 16 byte ", "5", 0},
452 {"StructMemberAlignment", "Zp1", "struct align 1 byte ", "1", 0},
453 {"StructMemberAlignment", "Zp2", "struct align 2 byte ", "2", 0},
454 {"StructMemberAlignment", "Zp4", "struct align 4 byte ", "3", 0},
455 {"StructMemberAlignment", "Zp8", "struct align 8 byte ", "4", 0},
456 {"WarningLevel", "W0", "Warning level", "0", 0},
457 {"WarningLevel", "W1", "Warning level", "1", 0},
458 {"WarningLevel", "W2", "Warning level", "2", 0},
459 {"WarningLevel", "W3", "Warning level", "3", 0},
460 {"WarningLevel", "W4", "Warning level", "4", 0},
461 {"DisableSpecificWarnings", "wd", "Disable specific warnings", "",
462 cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
464 // Precompiled header and related options. Note that the
465 // UsePrecompiledHeader entries are marked as "Continue" so that the
466 // corresponding PrecompiledHeaderThrough entry can be found.
467 {"UsePrecompiledHeader", "Yc", "Create Precompiled Header", "1",
468 cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
469 {"PrecompiledHeaderThrough", "Yc", "Precompiled Header Name", "",
470 cmVS7FlagTable::UserValueRequired},
471 {"PrecompiledHeaderFile", "Fp", "Generated Precompiled Header", "",
472 cmVS7FlagTable::UserValue},
473 // The YX and Yu options are in a per-global-generator table because
474 // their values differ based on the VS IDE version.
475 {"ForcedIncludeFiles", "FI", "Forced include files", "",
476 cmVS7FlagTable::UserValueRequired | cmVS7FlagTable::SemicolonAppendable},
478 {"AssemblerListingLocation", "Fa", "ASM List Location", "",
479 cmVS7FlagTable::UserValue},
480 {"ProgramDataBaseFileName", "Fd", "Program Database File Name", "",
481 cmVS7FlagTable::UserValue},
484 {"BufferSecurityCheck", "GS", "Buffer security check", "TRUE", 0},
485 {"BufferSecurityCheck", "GS-", "Turn off Buffer security check", "FALSE", 0},
486 {"Detect64BitPortabilityProblems", "Wp64",
487 "Detect 64-bit Portability Problems", "TRUE", 0},
488 {"EnableFiberSafeOptimizations", "GT", "Enable Fiber-safe Optimizations",
490 {"EnableFunctionLevelLinking", "Gy",
491 "EnableFunctionLevelLinking", "TRUE", 0},
492 {"EnableIntrinsicFunctions", "Oi", "EnableIntrinsicFunctions", "TRUE", 0},
493 {"GlobalOptimizations", "Og", "Global Optimize", "TRUE", 0},
494 {"ImproveFloatingPointConsistency", "Op",
495 "ImproveFloatingPointConsistency", "TRUE", 0},
496 {"MinimalRebuild", "Gm", "minimal rebuild", "TRUE", 0},
497 {"OmitFramePointers", "Oy", "OmitFramePointers", "TRUE", 0},
498 {"OptimizeForWindowsApplication", "GA", "Optimize for windows", "TRUE", 0},
499 {"RuntimeTypeInfo", "GR",
500 "Turn on Run time type information for c++", "TRUE", 0},
501 {"RuntimeTypeInfo", "GR-",
502 "Turn off Run time type information for c++", "FALSE", 0},
503 {"SmallerTypeCheck", "RTCc", "smaller type check", "TRUE", 0},
504 {"SuppressStartupBanner", "nologo", "SuppressStartupBanner", "TRUE", 0},
505 {"WholeProgramOptimization", "GL",
506 "Enables whole program optimization", "TRUE", 0},
507 {"WholeProgramOptimization", "GL-",
508 "Disables whole program optimization", "FALSE", 0},
509 {"WarnAsError", "WX", "Treat warnings as errors", "TRUE", 0},
510 {"BrowseInformation", "FR", "Generate browse information", "1", 0},
511 {"StringPooling", "GF", "Enable StringPooling", "TRUE", 0},
517 cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] =
519 // option flags (some flags map to the same option)
520 {"GenerateManifest", "MANIFEST:NO",
521 "disable manifest generation", "FALSE", 0},
522 {"GenerateManifest", "MANIFEST", "enable manifest generation", "TRUE", 0},
523 {"LinkIncremental", "INCREMENTAL:NO", "link incremental", "1", 0},
524 {"LinkIncremental", "INCREMENTAL:YES", "link incremental", "2", 0},
525 {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0},
526 {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0},
527 {"DataExecutionPrevention", "NXCOMPAT:NO",
528 "Not known to work with Windows Data Execution Prevention", "1", 0},
529 {"DataExecutionPrevention", "NXCOMPAT",
530 "Known to work with Windows Data Execution Prevention", "2", 0},
531 {"DelaySign", "DELAYSIGN:NO", "", "false", 0},
532 {"DelaySign", "DELAYSIGN", "", "true", 0},
533 {"EntryPointSymbol", "ENTRY:", "sets the starting address", "",
534 cmVS7FlagTable::UserValue},
535 {"IgnoreDefaultLibraryNames", "NODEFAULTLIB:", "default libs to ignore", "",
536 cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
537 {"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "ignore all default libs",
539 {"FixedBaseAddress", "FIXED:NO", "Generate a relocation section", "1", 0},
540 {"FixedBaseAddress", "FIXED", "Image must be loaded at a fixed address",
542 {"EnableCOMDATFolding", "OPT:NOICF", "Do not remove redundant COMDATs",
544 {"EnableCOMDATFolding", "OPT:ICF", "Remove redundant COMDATs", "2", 0},
545 {"ResourceOnlyDLL", "NOENTRY", "Create DLL with no entry point", "true", 0},
546 {"OptimizeReferences", "OPT:NOREF", "Keep unreferenced data", "1", 0},
547 {"OptimizeReferences", "OPT:REF", "Eliminate unreferenced data", "2", 0},
548 {"Profile", "PROFILE", "", "true", 0},
549 {"RandomizedBaseAddress", "DYNAMICBASE:NO",
550 "Image may not be rebased at load-time", "1", 0},
551 {"RandomizedBaseAddress", "DYNAMICBASE",
552 "Image may be rebased at load-time", "2", 0},
553 {"SetChecksum", "RELEASE", "Enable setting checksum in header", "true", 0},
554 {"SupportUnloadOfDelayLoadedDLL", "DELAY:UNLOAD", "", "true", 0},
555 {"TargetMachine", "MACHINE:I386", "Machine x86", "1", 0},
556 {"TargetMachine", "MACHINE:X86", "Machine x86", "1", 0},
557 {"TargetMachine", "MACHINE:AM33", "Machine AM33", "2", 0},
558 {"TargetMachine", "MACHINE:ARM", "Machine ARM", "3", 0},
559 {"TargetMachine", "MACHINE:EBC", "Machine EBC", "4", 0},
560 {"TargetMachine", "MACHINE:IA64", "Machine IA64", "5", 0},
561 {"TargetMachine", "MACHINE:M32R", "Machine M32R", "6", 0},
562 {"TargetMachine", "MACHINE:MIPS", "Machine MIPS", "7", 0},
563 {"TargetMachine", "MACHINE:MIPS16", "Machine MIPS16", "8", 0},
564 {"TargetMachine", "MACHINE:MIPSFPU)", "Machine MIPSFPU", "9", 0},
565 {"TargetMachine", "MACHINE:MIPSFPU16", "Machine MIPSFPU16", "10", 0},
566 {"TargetMachine", "MACHINE:MIPSR41XX", "Machine MIPSR41XX", "11", 0},
567 {"TargetMachine", "MACHINE:SH3", "Machine SH3", "12", 0},
568 {"TargetMachine", "MACHINE:SH3DSP", "Machine SH3DSP", "13", 0},
569 {"TargetMachine", "MACHINE:SH4", "Machine SH4", "14", 0},
570 {"TargetMachine", "MACHINE:SH5", "Machine SH5", "15", 0},
571 {"TargetMachine", "MACHINE:THUMB", "Machine THUMB", "16", 0},
572 {"TargetMachine", "MACHINE:X64", "Machine x64", "17", 0},
573 {"TurnOffAssemblyGeneration", "NOASSEMBLY",
574 "No assembly even if CLR information is present in objects.", "true", 0},
575 {"ModuleDefinitionFile", "DEF:", "add an export def file", "",
576 cmVS7FlagTable::UserValue},
577 {"GenerateMapFile", "MAP", "enable generation of map file", "TRUE", 0},
581 //----------------------------------------------------------------------------
582 // Helper class to write build event <Tool .../> elements.
583 class cmLocalVisualStudio7Generator::EventWriter
586 EventWriter(cmLocalVisualStudio7Generator* lg,
587 const char* config, std::ostream& os):
588 LG(lg), Config(config), Stream(os), First(true) {}
589 void Start(const char* tool)
592 this->Stream << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"";
596 this->Stream << (this->First? "" : "\"") << "/>\n";
598 void Write(std::vector<cmCustomCommand> const& ccs)
600 for(std::vector<cmCustomCommand>::const_iterator ci = ccs.begin();
601 ci != ccs.end(); ++ci)
606 void Write(cmCustomCommand const& cc)
610 const char* comment = cc.GetComment();
611 if(comment && *comment)
613 this->Stream << "\nDescription=\""
614 << this->LG->EscapeForXML(comment) << "\"";
616 this->Stream << "\nCommandLine=\"";
621 this->Stream << this->LG->EscapeForXML("\n");
623 std::string script = this->LG->ConstructScript(cc, this->Config);
624 this->Stream << this->LG->EscapeForXML(script.c_str());
627 cmLocalVisualStudio7Generator* LG;
629 std::ostream& Stream;
633 //----------------------------------------------------------------------------
634 void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
635 const char* configName,
639 const char* mfcFlag = this->Makefile->GetDefinition("CMAKE_MFC_FLAG");
644 fout << "\t\t<Configuration\n"
645 << "\t\t\tName=\"" << configName << "|" << this->PlatformName << "\"\n"
646 << "\t\t\tOutputDirectory=\"" << configName << "\"\n";
647 // This is an internal type to Visual Studio, it seems that:
648 // 4 == static library
652 const char* configType = "10";
653 const char* projectType = 0;
654 bool targetBuilds = true;
655 switch(target.GetType())
657 case cmTarget::OBJECT_LIBRARY:
658 targetBuilds = false; // TODO: PDB for object library?
659 case cmTarget::STATIC_LIBRARY:
660 projectType = "typeStaticLibrary";
663 case cmTarget::SHARED_LIBRARY:
664 case cmTarget::MODULE_LIBRARY:
665 projectType = "typeDynamicLibrary";
668 case cmTarget::EXECUTABLE:
671 case cmTarget::UTILITY:
672 case cmTarget::GLOBAL_TARGET:
675 targetBuilds = false;
678 if(this->FortranProject && projectType)
680 configType = projectType;
683 if(strcmp(configType, "10") != 0)
685 const char* linkLanguage = (this->FortranProject? "Fortran":
686 target.GetLinkerLanguage(configName));
690 ("CMake can not determine linker language for target: ",
694 if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0
695 || strcmp(linkLanguage, "Fortran") == 0)
697 std::string baseFlagVar = "CMAKE_";
698 baseFlagVar += linkLanguage;
699 baseFlagVar += "_FLAGS";
700 flags = this->Makefile->GetRequiredDefinition(baseFlagVar.c_str());
701 std::string flagVar = baseFlagVar + std::string("_") +
702 cmSystemTools::UpperCase(configName);
704 flags += this->Makefile->GetRequiredDefinition(flagVar.c_str());
706 // set the correct language
707 if(strcmp(linkLanguage, "C") == 0)
711 if(strcmp(linkLanguage, "CXX") == 0)
716 // Add the target-specific flags.
717 this->AddCompileOptions(flags, &target, linkLanguage, configName);
720 if(this->FortranProject)
722 switch(this->GetFortranFormat(target.GetProperty("Fortran_FORMAT")))
724 case FortranFormatFixed: flags += " -fixed"; break;
725 case FortranFormatFree: flags += " -free"; break;
730 // Get preprocessor definitions for this directory.
731 std::string defineFlags = this->Makefile->GetDefineFlags();
732 Options::Tool t = Options::Compiler;
733 cmVS7FlagTable const* table = cmLocalVisualStudio7GeneratorFlagTable;
734 if(this->FortranProject)
736 t = Options::FortranCompiler;
737 table = cmLocalVisualStudio7GeneratorFortranFlagTable;
739 Options targetOptions(this, t,
741 this->ExtraFlagTable);
742 targetOptions.FixExceptionHandlingDefault();
743 std::string asmLocation = std::string(configName) + "/";
744 targetOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str());
745 targetOptions.Parse(flags.c_str());
746 targetOptions.Parse(defineFlags.c_str());
747 targetOptions.ParseFinish();
748 cmGeneratorTarget* gt =
749 this->GlobalGenerator->GetGeneratorTarget(&target);
750 std::vector<std::string> targetDefines;
751 target.GetCompileDefinitions(targetDefines, configName);
752 targetOptions.AddDefines(targetDefines);
753 targetOptions.SetVerboseMakefile(
754 this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
756 // Add a definition for the configuration name.
757 std::string configDefine = "CMAKE_INTDIR=\"";
758 configDefine += configName;
759 configDefine += "\"";
760 targetOptions.AddDefine(configDefine);
762 // Add the export symbol definition for shared library objects.
763 if(const char* exportMacro = target.GetExportMacro())
765 targetOptions.AddDefine(exportMacro);
768 // The intermediate directory name consists of a directory for the
769 // target and a subdirectory for the configuration name.
770 std::string intermediateDir = this->GetTargetDirectory(target);
771 intermediateDir += "/";
772 intermediateDir += configName;
773 fout << "\t\t\tIntermediateDirectory=\""
774 << this->ConvertToXMLOutputPath(intermediateDir.c_str())
776 << "\t\t\tConfigurationType=\"" << configType << "\"\n"
777 << "\t\t\tUseOfMFC=\"" << mfcFlag << "\"\n"
778 << "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n";
780 // If unicode is enabled change the character set to unicode, if not
781 // then default to MBCS.
782 if(targetOptions.UsingUnicode())
784 fout << "\t\t\tCharacterSet=\"1\">\n";
786 else if(targetOptions.UsingSBCS())
788 fout << "\t\t\tCharacterSet=\"0\">\n";
792 fout << "\t\t\tCharacterSet=\"2\">\n";
794 const char* tool = "VCCLCompilerTool";
795 if(this->FortranProject)
797 tool = "VFFortranCompilerTool";
799 fout << "\t\t\t<Tool\n"
800 << "\t\t\t\tName=\"" << tool << "\"\n";
801 if(this->FortranProject)
803 const char* target_mod_dir =
804 target.GetProperty("Fortran_MODULE_DIRECTORY");
808 modDir = this->Convert(target_mod_dir,
809 cmLocalGenerator::START_OUTPUT,
810 cmLocalGenerator::UNCHANGED);
816 fout << "\t\t\t\tModulePath=\""
817 << this->ConvertToXMLOutputPath(modDir.c_str())
818 << "\\$(ConfigurationName)\"\n";
820 targetOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
821 fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
822 std::vector<std::string> includes;
823 this->GetIncludeDirectories(includes, gt, "C", configName);
824 std::vector<std::string>::iterator i = includes.begin();
825 for(;i != includes.end(); ++i)
827 // output the include path
828 std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
829 fout << ipath << ";";
830 // if this is fortran then output the include with
831 // a ConfigurationName on the end of it.
832 if(this->FortranProject)
835 ipath += "/$(ConfigurationName)";
836 ipath = this->ConvertToXMLOutputPath(ipath.c_str());
837 fout << ipath << ";";
841 targetOptions.OutputFlagMap(fout, "\t\t\t\t");
842 targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n", "CXX");
843 fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n";
844 fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
845 tool = "VCCustomBuildTool";
846 if(this->FortranProject)
848 tool = "VFCustomBuildTool";
850 fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"/>\n";
851 tool = "VCResourceCompilerTool";
852 if(this->FortranProject)
854 tool = "VFResourceCompilerTool";
856 fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n"
857 << "\t\t\t\tAdditionalIncludeDirectories=\"";
858 for(i = includes.begin();i != includes.end(); ++i)
860 std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
861 fout << ipath << ";";
863 // add the -D flags to the RC tool
865 targetOptions.OutputPreprocessorDefinitions(fout, "\n\t\t\t\t", "", "RC");
868 if(this->FortranProject)
872 fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n";
873 fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
874 for(i = includes.begin(); i != includes.end(); ++i)
876 std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
877 fout << ipath << ";";
880 fout << "\t\t\t\tMkTypLibCompatible=\"FALSE\"\n";
881 if( this->PlatformName == "x64" )
883 fout << "\t\t\t\tTargetEnvironment=\"3\"\n";
885 else if( this->PlatformName == "ia64" )
887 fout << "\t\t\t\tTargetEnvironment=\"2\"\n";
891 fout << "\t\t\t\tTargetEnvironment=\"1\"\n";
893 fout << "\t\t\t\tGenerateStublessProxies=\"TRUE\"\n";
894 fout << "\t\t\t\tTypeLibraryName=\"$(InputName).tlb\"\n";
895 fout << "\t\t\t\tOutputDirectory=\"$(IntDir)\"\n";
896 fout << "\t\t\t\tHeaderFileName=\"$(InputName).h\"\n";
897 fout << "\t\t\t\tDLLDataFileName=\"\"\n";
898 fout << "\t\t\t\tInterfaceIdentifierFileName=\"$(InputName)_i.c\"\n";
899 fout << "\t\t\t\tProxyFileName=\"$(InputName)_p.c\"/>\n";
900 // end of <Tool Name=VCMIDLTool
902 // Check if we need the FAT32 workaround.
903 if(targetBuilds && this->Version >= VS8)
905 // Check the filesystem type where the target will be written.
906 if(cmLVS6G_IsFAT(target.GetDirectory(configName).c_str()))
908 // Add a flag telling the manifest tool to use a workaround
909 // for FAT32 file systems, which can cause an empty manifest
910 // to be embedded into the resulting executable. See CMake
912 const char* manifestTool = "VCManifestTool";
913 if(this->FortranProject)
915 manifestTool = "VFManifestTool";
917 fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << manifestTool << "\"\n"
918 << "\t\t\t\tUseFAT32Workaround=\"true\"\n"
923 this->OutputTargetRules(fout, configName, target, libName);
924 this->OutputBuildTool(fout, configName, target, targetOptions);
925 fout << "\t\t</Configuration>\n";
928 //----------------------------------------------------------------------------
930 cmLocalVisualStudio7Generator
931 ::GetBuildTypeLinkerFlags(std::string rootLinkerFlags, const char* configName)
933 std::string configTypeUpper = cmSystemTools::UpperCase(configName);
934 std::string extraLinkOptionsBuildTypeDef =
935 rootLinkerFlags + "_" + configTypeUpper;
937 std::string extraLinkOptionsBuildType =
938 this->Makefile->GetRequiredDefinition
939 (extraLinkOptionsBuildTypeDef.c_str());
941 return extraLinkOptionsBuildType;
944 void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
945 const char* configName, cmTarget &target, const Options& targetOptions)
947 cmGlobalVisualStudio7Generator* gg =
948 static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
950 std::string extraLinkOptions;
951 if(target.GetType() == cmTarget::EXECUTABLE)
954 this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS")
956 + GetBuildTypeLinkerFlags("CMAKE_EXE_LINKER_FLAGS", configName);
958 if(target.GetType() == cmTarget::SHARED_LIBRARY)
961 this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS")
963 + GetBuildTypeLinkerFlags("CMAKE_SHARED_LINKER_FLAGS", configName);
965 if(target.GetType() == cmTarget::MODULE_LIBRARY)
968 this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS")
970 + GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName);
973 const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
976 extraLinkOptions += " ";
977 extraLinkOptions += targetLinkFlags;
979 std::string configTypeUpper = cmSystemTools::UpperCase(configName);
980 std::string linkFlagsConfig = "LINK_FLAGS_";
981 linkFlagsConfig += configTypeUpper;
982 targetLinkFlags = target.GetProperty(linkFlagsConfig.c_str());
985 extraLinkOptions += " ";
986 extraLinkOptions += targetLinkFlags;
988 Options linkOptions(this, Options::Linker,
989 cmLocalVisualStudio7GeneratorLinkFlagTable);
990 linkOptions.Parse(extraLinkOptions.c_str());
991 if(!this->ModuleDefinitionFile.empty())
993 std::string defFile =
994 this->ConvertToXMLOutputPath(this->ModuleDefinitionFile.c_str());
995 linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
997 switch(target.GetType())
999 case cmTarget::UNKNOWN_LIBRARY:
1001 case cmTarget::OBJECT_LIBRARY:
1003 std::string libpath = this->GetTargetDirectory(target);
1005 libpath += configName;
1007 libpath += target.GetName();
1010 this->FortranProject? "VFLibrarianTool":"VCLibrarianTool";
1011 fout << "\t\t\t<Tool\n"
1012 << "\t\t\t\tName=\"" << tool << "\"\n";
1013 fout << "\t\t\t\tOutputFile=\""
1014 << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
1017 case cmTarget::STATIC_LIBRARY:
1019 std::string targetNameFull = target.GetFullName(configName);
1020 std::string libpath = target.GetDirectory(configName);
1022 libpath += targetNameFull;
1023 const char* tool = "VCLibrarianTool";
1024 if(this->FortranProject)
1026 tool = "VFLibrarianTool";
1028 fout << "\t\t\t<Tool\n"
1029 << "\t\t\t\tName=\"" << tool << "\"\n";
1031 if(this->GetVersion() < VS8)
1033 cmOStringStream libdeps;
1034 this->Internal->OutputObjects(libdeps, &target);
1035 if(!libdeps.str().empty())
1037 fout << "\t\t\t\tAdditionalDependencies=\"" << libdeps.str() << "\"\n";
1040 std::string libflags;
1041 this->GetStaticLibraryFlags(libflags, configTypeUpper, &target);
1042 if(!libflags.empty())
1044 fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
1046 fout << "\t\t\t\tOutputFile=\""
1047 << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
1050 case cmTarget::SHARED_LIBRARY:
1051 case cmTarget::MODULE_LIBRARY:
1053 std::string targetName;
1054 std::string targetNameSO;
1055 std::string targetNameFull;
1056 std::string targetNameImport;
1057 std::string targetNamePDB;
1058 target.GetLibraryNames(targetName, targetNameSO, targetNameFull,
1059 targetNameImport, targetNamePDB, configName);
1061 // Compute the link library and directory information.
1062 cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
1067 cmComputeLinkInformation& cli = *pcli;
1068 const char* linkLanguage = cli.GetLinkLanguage();
1070 // Compute the variable name to lookup standard libraries for this
1072 std::string standardLibsVar = "CMAKE_";
1073 standardLibsVar += linkLanguage;
1074 standardLibsVar += "_STANDARD_LIBRARIES";
1075 const char* tool = "VCLinkerTool";
1076 if(this->FortranProject)
1078 tool = "VFLinkerTool";
1080 fout << "\t\t\t<Tool\n"
1081 << "\t\t\t\tName=\"" << tool << "\"\n";
1082 if(!gg->NeedLinkLibraryDependencies(target))
1084 fout << "\t\t\t\tLinkLibraryDependencies=\"false\"\n";
1086 linkOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
1087 // Use the NOINHERIT macro to avoid getting VS project default
1088 // libraries which may be set by the user to something bad.
1089 fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
1090 << this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
1091 if(this->GetVersion() < VS8)
1093 this->Internal->OutputObjects(fout, &target, " ");
1096 this->Internal->OutputLibraries(fout, cli.GetItems());
1098 temp = target.GetDirectory(configName);
1100 temp += targetNameFull;
1101 fout << "\t\t\t\tOutputFile=\""
1102 << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
1103 this->WriteTargetVersionAttribute(fout, target);
1104 linkOptions.OutputFlagMap(fout, "\t\t\t\t");
1105 fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
1106 this->OutputLibraryDirectories(fout, cli.GetDirectories());
1108 temp = target.GetPDBDirectory(configName);
1110 temp += targetNamePDB;
1111 fout << "\t\t\t\tProgramDatabaseFile=\"" <<
1112 this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
1113 if(targetOptions.IsDebug())
1115 fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
1117 if(this->WindowsCEProject)
1119 if(this->GetVersion() < VS9)
1121 fout << "\t\t\t\tSubSystem=\"9\"\n";
1125 fout << "\t\t\t\tSubSystem=\"8\"\n";
1128 std::string stackVar = "CMAKE_";
1129 stackVar += linkLanguage;
1130 stackVar += "_STACK_SIZE";
1131 const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
1134 fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n";
1136 temp = target.GetDirectory(configName, true);
1138 temp += targetNameImport;
1139 fout << "\t\t\t\tImportLibrary=\""
1140 << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"";
1141 if(this->FortranProject)
1143 fout << "\n\t\t\t\tLinkDLL=\"true\"";
1148 case cmTarget::EXECUTABLE:
1150 std::string targetName;
1151 std::string targetNameFull;
1152 std::string targetNameImport;
1153 std::string targetNamePDB;
1154 target.GetExecutableNames(targetName, targetNameFull,
1155 targetNameImport, targetNamePDB, configName);
1157 // Compute the link library and directory information.
1158 cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
1163 cmComputeLinkInformation& cli = *pcli;
1164 const char* linkLanguage = cli.GetLinkLanguage();
1166 bool isWin32Executable = target.GetPropertyAsBool("WIN32_EXECUTABLE");
1168 // Compute the variable name to lookup standard libraries for this
1170 std::string standardLibsVar = "CMAKE_";
1171 standardLibsVar += linkLanguage;
1172 standardLibsVar += "_STANDARD_LIBRARIES";
1173 const char* tool = "VCLinkerTool";
1174 if(this->FortranProject)
1176 tool = "VFLinkerTool";
1178 fout << "\t\t\t<Tool\n"
1179 << "\t\t\t\tName=\"" << tool << "\"\n";
1180 if(!gg->NeedLinkLibraryDependencies(target))
1182 fout << "\t\t\t\tLinkLibraryDependencies=\"false\"\n";
1184 linkOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
1185 // Use the NOINHERIT macro to avoid getting VS project default
1186 // libraries which may be set by the user to something bad.
1187 fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
1188 << this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
1189 if(this->GetVersion() < VS8)
1191 this->Internal->OutputObjects(fout, &target, " ");
1194 this->Internal->OutputLibraries(fout, cli.GetItems());
1196 temp = target.GetDirectory(configName);
1198 temp += targetNameFull;
1199 fout << "\t\t\t\tOutputFile=\""
1200 << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
1201 this->WriteTargetVersionAttribute(fout, target);
1202 linkOptions.OutputFlagMap(fout, "\t\t\t\t");
1203 fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
1204 this->OutputLibraryDirectories(fout, cli.GetDirectories());
1206 std::string path = this->ConvertToXMLOutputPathSingle(
1207 target.GetPDBDirectory(configName).c_str());
1208 fout << "\t\t\t\tProgramDatabaseFile=\""
1209 << path << "/" << targetNamePDB
1211 if(targetOptions.IsDebug())
1213 fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
1215 if ( this->WindowsCEProject )
1217 if(this->GetVersion() < VS9)
1219 fout << "\t\t\t\tSubSystem=\"9\"\n";
1223 fout << "\t\t\t\tSubSystem=\"8\"\n";
1226 if(!linkOptions.GetFlag("EntryPointSymbol"))
1228 const char* entryPointSymbol = targetOptions.UsingUnicode() ?
1229 (isWin32Executable ? "wWinMainCRTStartup" : "mainWCRTStartup") :
1230 (isWin32Executable ? "WinMainCRTStartup" : "mainACRTStartup");
1231 fout << "\t\t\t\tEntryPointSymbol=\"" << entryPointSymbol << "\"\n";
1234 else if ( this->FortranProject )
1236 fout << "\t\t\t\tSubSystem=\""
1237 << (isWin32Executable ? "subSystemWindows" : "subSystemConsole")
1242 fout << "\t\t\t\tSubSystem=\""
1243 << (isWin32Executable ? "2" : "1")
1246 std::string stackVar = "CMAKE_";
1247 stackVar += linkLanguage;
1248 stackVar += "_STACK_SIZE";
1249 const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
1252 fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
1254 temp = target.GetDirectory(configName, true);
1256 temp += targetNameImport;
1257 fout << "\t\t\t\tImportLibrary=\""
1258 << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
1261 case cmTarget::UTILITY:
1262 case cmTarget::GLOBAL_TARGET:
1267 //----------------------------------------------------------------------------
1269 cmLocalVisualStudio7Generator
1270 ::WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target)
1274 target.GetTargetVersion(major, minor);
1275 fout << "\t\t\t\tVersion=\"" << major << "." << minor << "\"\n";
1278 //----------------------------------------------------------------------------
1280 cmLocalVisualStudio7GeneratorInternals
1281 ::OutputLibraries(std::ostream& fout, ItemVector const& libs)
1283 cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
1284 for(ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l)
1288 std::string rel = lg->Convert(l->Value.c_str(),
1289 cmLocalGenerator::START_OUTPUT,
1290 cmLocalGenerator::UNCHANGED);
1291 fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " ";
1295 fout << l->Value << " ";
1300 //----------------------------------------------------------------------------
1302 cmLocalVisualStudio7GeneratorInternals
1303 ::OutputObjects(std::ostream& fout, cmTarget* t, const char* isep)
1305 // VS < 8 does not support per-config source locations so we
1306 // list object library content on the link line instead.
1307 cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
1308 cmGeneratorTarget* gt =
1309 lg->GetGlobalGenerator()->GetGeneratorTarget(t);
1310 std::vector<std::string> objs;
1311 gt->UseObjectLibraries(objs);
1312 const char* sep = isep? isep : "";
1313 for(std::vector<std::string>::const_iterator
1314 oi = objs.begin(); oi != objs.end(); ++oi)
1316 std::string rel = lg->Convert(oi->c_str(),
1317 cmLocalGenerator::START_OUTPUT,
1318 cmLocalGenerator::UNCHANGED);
1319 fout << sep << lg->ConvertToXMLOutputPath(rel.c_str());
1324 //----------------------------------------------------------------------------
1326 cmLocalVisualStudio7Generator
1327 ::OutputLibraryDirectories(std::ostream& fout,
1328 std::vector<std::string> const& dirs)
1330 const char* comma = "";
1331 for(std::vector<std::string>::const_iterator d = dirs.begin();
1332 d != dirs.end(); ++d)
1334 // Remove any trailing slash and skip empty paths.
1335 std::string dir = *d;
1336 if(dir[dir.size()-1] == '/')
1338 dir = dir.substr(0, dir.size()-1);
1345 // Switch to a relative path specification if it is shorter.
1346 if(cmSystemTools::FileIsFullPath(dir.c_str()))
1348 std::string rel = this->Convert(dir.c_str(), START_OUTPUT, UNCHANGED);
1349 if(rel.size() < dir.size())
1355 // First search a configuration-specific subdirectory and then the
1356 // original directory.
1357 fout << comma << this->ConvertToXMLOutputPath((dir+"/$(OutDir)").c_str())
1358 << "," << this->ConvertToXMLOutputPath(dir.c_str());
1363 void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
1364 const char *libName,
1367 // get the configurations
1368 std::vector<std::string> *configs =
1369 static_cast<cmGlobalVisualStudio7Generator *>
1370 (this->GlobalGenerator)->GetConfigurations();
1372 // We may be modifying the source groups temporarily, so make a copy.
1373 std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
1375 // get the classes from the source lists then add them to the groups
1376 this->ModuleDefinitionFile = "";
1377 std::vector<cmSourceFile*>const & classes = target.GetSourceFiles();
1378 for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
1379 i != classes.end(); i++)
1381 // Add the file to the list of sources.
1382 std::string source = (*i)->GetFullPath();
1383 if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF")
1385 this->ModuleDefinitionFile = (*i)->GetFullPath();
1387 cmSourceGroup& sourceGroup =
1388 this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
1389 sourceGroup.AssignSource(*i);
1393 this->WriteProjectStart(fout, libName, target, sourceGroups);
1394 // write the configuration information
1395 this->WriteConfigurations(fout, libName, target);
1397 fout << "\t<Files>\n";
1400 // Loop through every source group.
1401 for(unsigned int i = 0; i < sourceGroups.size(); ++i)
1403 cmSourceGroup sg = sourceGroups[i];
1404 this->WriteGroup(&sg, target, fout, libName, configs);
1407 if(this->GetVersion() >= VS8)
1409 // VS >= 8 support per-config source locations so we
1410 // list object library content as external objects.
1411 cmGeneratorTarget* gt =
1412 this->GlobalGenerator->GetGeneratorTarget(&target);
1413 std::vector<std::string> objs;
1414 gt->UseObjectLibraries(objs);
1417 // TODO: Separate sub-filter for each object library used?
1418 fout << "\t\t<Filter Name=\"Object Libraries\">\n";
1419 for(std::vector<std::string>::const_iterator
1420 oi = objs.begin(); oi != objs.end(); ++oi)
1422 std::string o = this->ConvertToXMLOutputPathSingle(oi->c_str());
1423 fout << "\t\t\t<File RelativePath=\"" << o << "\" />\n";
1425 fout << "\t\t</Filter>\n";
1429 fout << "\t</Files>\n";
1431 // Write the VCProj file's footer.
1432 this->WriteVCProjFooter(fout, target);
1435 struct cmLVS7GFileConfig
1437 std::string ObjectName;
1438 std::string CompileFlags;
1439 std::string CompileDefs;
1440 std::string CompileDefsConfig;
1441 std::string AdditionalDeps;
1442 bool ExcludedFromBuild;
1445 class cmLocalVisualStudio7GeneratorFCInfo
1448 cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
1450 cmSourceFile const& sf,
1451 std::vector<std::string>* configs);
1452 std::map<cmStdString, cmLVS7GFileConfig> FileConfigMap;
1455 cmLocalVisualStudio7GeneratorFCInfo
1456 ::cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
1458 cmSourceFile const& sf,
1459 std::vector<std::string>* configs)
1461 cmGeneratorTarget* gt =
1462 lg->GetGlobalGenerator()->GetGeneratorTarget(&target);
1463 std::string objectName;
1464 if(gt->ExplicitObjectName.find(&sf) != gt->ExplicitObjectName.end())
1466 objectName = gt->Objects[&sf];
1469 // Compute per-source, per-config information.
1470 for(std::vector<std::string>::iterator i = configs->begin();
1471 i != configs->end(); ++i)
1473 std::string configUpper = cmSystemTools::UpperCase(*i);
1474 cmLVS7GFileConfig fc;
1475 bool needfc = false;
1476 if(!objectName.empty())
1478 fc.ObjectName = objectName;
1481 if(const char* cflags = sf.GetProperty("COMPILE_FLAGS"))
1483 fc.CompileFlags = cflags;
1486 if(lg->FortranProject)
1488 switch(lg->GetFortranFormat(sf.GetProperty("Fortran_FORMAT")))
1490 case cmLocalGenerator::FortranFormatFixed:
1491 fc.CompileFlags = "-fixed " + fc.CompileFlags;
1494 case cmLocalGenerator::FortranFormatFree:
1495 fc.CompileFlags = "-free " + fc.CompileFlags;
1501 if(const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS"))
1503 fc.CompileDefs = cdefs;
1506 std::string defPropName = "COMPILE_DEFINITIONS_";
1507 defPropName += configUpper;
1508 if(const char* ccdefs = sf.GetProperty(defPropName.c_str()))
1510 fc.CompileDefsConfig = ccdefs;
1514 // Check for extra object-file dependencies.
1515 if(const char* deps = sf.GetProperty("OBJECT_DEPENDS"))
1517 std::vector<std::string> depends;
1518 cmSystemTools::ExpandListArgument(deps, depends);
1519 const char* sep = "";
1520 for(std::vector<std::string>::iterator j = depends.begin();
1521 j != depends.end(); ++j)
1523 fc.AdditionalDeps += sep;
1524 fc.AdditionalDeps += lg->ConvertToXMLOutputPath(j->c_str());
1531 lg->GlobalGenerator->GetLanguageFromExtension
1532 (sf.GetExtension().c_str());
1533 const char* sourceLang = lg->GetSourceFileLanguage(sf);
1534 const char* linkLanguage = target.GetLinkerLanguage(i->c_str());
1535 bool needForceLang = false;
1536 // source file does not match its extension language
1537 if(lang && sourceLang && strcmp(lang, sourceLang) != 0)
1539 needForceLang = true;
1542 // If HEADER_FILE_ONLY is set, we must suppress this generation in
1544 fc.ExcludedFromBuild =
1545 (sf.GetPropertyAsBool("HEADER_FILE_ONLY"));
1546 if(fc.ExcludedFromBuild)
1551 // if the source file does not match the linker language
1552 // then force c or c++
1553 if(needForceLang || (linkLanguage && lang
1554 && strcmp(lang, linkLanguage) != 0))
1556 if(strcmp(lang, "CXX") == 0)
1558 // force a C++ file type
1559 fc.CompileFlags += " /TP ";
1562 else if(strcmp(lang, "C") == 0)
1565 fc.CompileFlags += " /TC ";
1572 this->FileConfigMap[*i] = fc;
1577 //----------------------------------------------------------------------------
1579 cmLocalVisualStudio7Generator
1580 ::ComputeLongestObjectDirectory(cmTarget& target) const
1582 std::vector<std::string> *configs =
1583 static_cast<cmGlobalVisualStudio7Generator *>
1584 (this->GlobalGenerator)->GetConfigurations();
1585 // Compute the maximum length configuration name.
1586 std::string config_max;
1587 for(std::vector<std::string>::iterator i = configs->begin();
1588 i != configs->end(); ++i)
1590 if(i->size() > config_max.size())
1596 // Compute the maximum length full path to the intermediate
1597 // files directory for any configuration. This is used to construct
1598 // object file names that do not produce paths that are too long.
1599 std::string dir_max;
1600 dir_max += this->Makefile->GetCurrentOutputDirectory();
1602 dir_max += this->GetTargetDirectory(target);
1604 dir_max += config_max;
1609 bool cmLocalVisualStudio7Generator
1610 ::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
1611 std::ostream &fout, const char *libName,
1612 std::vector<std::string> *configs)
1614 const std::vector<const cmSourceFile *> &sourceFiles =
1615 sg->GetSourceFiles();
1616 std::vector<cmSourceGroup> const& children = sg->GetGroupChildren();
1618 // Write the children to temporary output.
1619 bool hasChildrenWithSources = false;
1620 cmOStringStream tmpOut;
1621 for(unsigned int i=0;i<children.size();++i)
1623 if(this->WriteGroup(&children[i], target, tmpOut, libName, configs))
1625 hasChildrenWithSources = true;
1629 // If the group is empty, don't write it at all.
1630 if(sourceFiles.empty() && !hasChildrenWithSources)
1635 // If the group has a name, write the header.
1636 std::string name = sg->GetName();
1639 this->WriteVCProjBeginGroup(fout, name.c_str(), "");
1642 // Loop through each source in the source group.
1643 std::string objectName;
1644 for(std::vector<const cmSourceFile *>::const_iterator sf =
1645 sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
1647 std::string source = (*sf)->GetFullPath();
1648 FCInfo fcinfo(this, target, *(*sf), configs);
1650 if (source != libName || target.GetType() == cmTarget::UTILITY ||
1651 target.GetType() == cmTarget::GLOBAL_TARGET )
1653 fout << "\t\t\t<File\n";
1654 std::string d = this->ConvertToXMLOutputPathSingle(source.c_str());
1655 // Tell MS-Dev what the source is. If the compiler knows how to
1656 // build it, then it will.
1657 fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
1658 if(cmCustomCommand const* command = (*sf)->GetCustomCommand())
1660 this->WriteCustomRule(fout, source.c_str(), *command, fcinfo);
1662 else if(!fcinfo.FileConfigMap.empty())
1664 const char* aCompilerTool = "VCCLCompilerTool";
1665 const char* lang = "CXX";
1666 if(this->FortranProject)
1668 aCompilerTool = "VFFortranCompilerTool";
1670 std::string ext = (*sf)->GetExtension();
1671 ext = cmSystemTools::LowerCase(ext);
1674 aCompilerTool = "VCMIDLTool";
1675 if(this->FortranProject)
1677 aCompilerTool = "VFMIDLTool";
1682 aCompilerTool = "VCResourceCompilerTool";
1684 if(this->FortranProject)
1686 aCompilerTool = "VFResourceCompilerTool";
1691 aCompilerTool = "VCCustomBuildTool";
1692 if(this->FortranProject)
1694 aCompilerTool = "VFCustomBuildTool";
1697 for(std::map<cmStdString, cmLVS7GFileConfig>::const_iterator
1698 fci = fcinfo.FileConfigMap.begin();
1699 fci != fcinfo.FileConfigMap.end(); ++fci)
1701 cmLVS7GFileConfig const& fc = fci->second;
1702 fout << "\t\t\t\t<FileConfiguration\n"
1703 << "\t\t\t\t\tName=\"" << fci->first
1704 << "|" << this->PlatformName << "\"";
1705 if(fc.ExcludedFromBuild)
1707 fout << " ExcludedFromBuild=\"true\"";
1710 fout << "\t\t\t\t\t<Tool\n"
1711 << "\t\t\t\t\tName=\"" << aCompilerTool << "\"\n";
1712 if(!fc.CompileFlags.empty() ||
1713 !fc.CompileDefs.empty() ||
1714 !fc.CompileDefsConfig.empty())
1716 Options::Tool tool = Options::Compiler;
1717 cmVS7FlagTable const* table =
1718 cmLocalVisualStudio7GeneratorFlagTable;
1719 if(this->FortranProject)
1721 tool = Options::FortranCompiler;
1722 table = cmLocalVisualStudio7GeneratorFortranFlagTable;
1724 Options fileOptions(this, tool, table,
1725 this->ExtraFlagTable);
1726 fileOptions.Parse(fc.CompileFlags.c_str());
1727 fileOptions.AddDefines(fc.CompileDefs.c_str());
1728 fileOptions.AddDefines(fc.CompileDefsConfig.c_str());
1729 fileOptions.OutputAdditionalOptions(fout, "\t\t\t\t\t", "\n");
1730 fileOptions.OutputFlagMap(fout, "\t\t\t\t\t");
1731 fileOptions.OutputPreprocessorDefinitions(fout,
1735 if(!fc.AdditionalDeps.empty())
1737 fout << "\t\t\t\t\tAdditionalDependencies=\""
1738 << fc.AdditionalDeps.c_str() << "\"\n";
1740 if(!fc.ObjectName.empty())
1742 fout << "\t\t\t\t\tObjectFile=\"$(IntDir)/"
1743 << fc.ObjectName.c_str() << "\"\n";
1745 fout << "\t\t\t\t\t/>\n"
1746 << "\t\t\t\t</FileConfiguration>\n";
1749 fout << "\t\t\t</File>\n";
1753 // If the group has children with source files, write the children.
1754 if(hasChildrenWithSources)
1756 fout << tmpOut.str();
1759 // If the group has a name, write the footer.
1762 this->WriteVCProjEndGroup(fout);
1768 void cmLocalVisualStudio7Generator::
1769 WriteCustomRule(std::ostream& fout,
1771 const cmCustomCommand& command,
1774 std::string comment = this->ConstructComment(command);
1776 // Write the rule for each configuration.
1777 std::vector<std::string>::iterator i;
1778 std::vector<std::string> *configs =
1779 static_cast<cmGlobalVisualStudio7Generator *>
1780 (this->GlobalGenerator)->GetConfigurations();
1781 const char* compileTool = "VCCLCompilerTool";
1782 if(this->FortranProject)
1784 compileTool = "VFCLCompilerTool";
1786 const char* customTool = "VCCustomBuildTool";
1787 if(this->FortranProject)
1789 customTool = "VFCustomBuildTool";
1791 for(i = configs->begin(); i != configs->end(); ++i)
1793 cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[*i];
1794 fout << "\t\t\t\t<FileConfiguration\n";
1795 fout << "\t\t\t\t\tName=\"" << *i << "|" << this->PlatformName << "\">\n";
1796 if(!fc.CompileFlags.empty())
1798 fout << "\t\t\t\t\t<Tool\n"
1799 << "\t\t\t\t\tName=\"" << compileTool << "\"\n"
1800 << "\t\t\t\t\tAdditionalOptions=\""
1801 << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
1804 std::string script = this->ConstructScript(command, i->c_str());
1805 if(this->FortranProject)
1807 cmSystemTools::ReplaceString(script, "$(Configuration)", i->c_str());
1809 fout << "\t\t\t\t\t<Tool\n"
1810 << "\t\t\t\t\tName=\"" << customTool << "\"\n"
1811 << "\t\t\t\t\tDescription=\""
1812 << this->EscapeForXML(comment.c_str()) << "\"\n"
1813 << "\t\t\t\t\tCommandLine=\""
1814 << this->EscapeForXML(script.c_str()) << "\"\n"
1815 << "\t\t\t\t\tAdditionalDependencies=\"";
1816 if(command.GetDepends().empty())
1818 // There are no real dependencies. Produce an artificial one to
1819 // make sure the rule runs reliably.
1820 if(!cmSystemTools::FileExists(source))
1822 std::ofstream depout(source);
1823 depout << "Artificial dependency for a custom command.\n";
1825 fout << this->ConvertToXMLOutputPath(source);
1829 // Write out the dependencies for the rule.
1830 for(std::vector<std::string>::const_iterator d =
1831 command.GetDepends().begin();
1832 d != command.GetDepends().end();
1835 // Get the real name of the dependency in case it is a CMake target.
1837 if(this->GetRealDependency(d->c_str(), i->c_str(), dep))
1839 fout << this->ConvertToXMLOutputPath(dep.c_str())
1845 fout << "\t\t\t\t\tOutputs=\"";
1846 if(command.GetOutputs().empty())
1848 fout << source << "_force";
1852 // Write a rule for the output generated by this command.
1853 const char* sep = "";
1854 for(std::vector<std::string>::const_iterator o =
1855 command.GetOutputs().begin();
1856 o != command.GetOutputs().end();
1859 fout << sep << this->ConvertToXMLOutputPathSingle(o->c_str());
1864 fout << "\t\t\t\t</FileConfiguration>\n";
1869 void cmLocalVisualStudio7Generator::WriteVCProjBeginGroup(std::ostream& fout,
1873 fout << "\t\t<Filter\n"
1874 << "\t\t\tName=\"" << group << "\"\n"
1875 << "\t\t\tFilter=\"\">\n";
1879 void cmLocalVisualStudio7Generator::WriteVCProjEndGroup(std::ostream& fout)
1881 fout << "\t\t</Filter>\n";
1885 // look for custom rules on a target and collect them together
1886 void cmLocalVisualStudio7Generator
1887 ::OutputTargetRules(std::ostream& fout,
1888 const char* configName,
1890 const char * /*libName*/)
1892 if (target.GetType() > cmTarget::GLOBAL_TARGET)
1896 EventWriter event(this, configName, fout);
1898 // Add pre-build event.
1900 this->FortranProject? "VFPreBuildEventTool":"VCPreBuildEventTool";
1902 event.Write(target.GetPreBuildCommands());
1905 // Add pre-link event.
1906 tool = this->FortranProject? "VFPreLinkEventTool":"VCPreLinkEventTool";
1908 event.Write(target.GetPreLinkCommands());
1909 cmsys::auto_ptr<cmCustomCommand> pcc(
1910 this->MaybeCreateImplibDir(target, configName, this->FortranProject));
1917 // Add post-build event.
1918 tool = this->FortranProject? "VFPostBuildEventTool":"VCPostBuildEventTool";
1920 event.Write(target.GetPostBuildCommands());
1924 void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout,
1927 // if we have all the required Source code control tags
1928 // then add that to the project
1929 const char* vsProjectname = target.GetProperty("VS_SCC_PROJECTNAME");
1930 const char* vsLocalpath = target.GetProperty("VS_SCC_LOCALPATH");
1931 const char* vsProvider = target.GetProperty("VS_SCC_PROVIDER");
1933 if(vsProvider && vsLocalpath && vsProjectname)
1935 fout << "\tSccProjectName=\"" << vsProjectname << "\"\n"
1936 << "\tSccLocalPath=\"" << vsLocalpath << "\"\n"
1937 << "\tSccProvider=\"" << vsProvider << "\"\n";
1939 const char* vsAuxPath = target.GetProperty("VS_SCC_AUXPATH");
1942 fout << "\tSccAuxPath=\"" << vsAuxPath << "\"\n";
1948 cmLocalVisualStudio7Generator
1949 ::WriteProjectStartFortran(std::ostream& fout,
1950 const char *libName,
1954 cmGlobalVisualStudio7Generator* gg =
1955 static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
1957 // Compute the version of the Intel plugin to the VS IDE.
1958 // If the key does not exist then use a default guess.
1959 std::string intelVersion;
1960 std::string vskey = gg->GetRegistryBase();
1961 vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
1962 cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
1963 cmSystemTools::KeyWOW64_32);
1964 unsigned int intelVersionNumber = ~0u;
1965 sscanf(intelVersion.c_str(), "%u", &intelVersionNumber);
1966 if(intelVersionNumber >= 11)
1968 // Default to latest known project file version.
1969 intelVersion = "11.0";
1971 else if(intelVersionNumber == 10)
1973 // Version 10.x actually uses 9.10 in project files!
1974 intelVersion = "9.10";
1978 // Version <= 9: use ProductVersion from registry.
1981 fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
1982 << "<VisualStudioProject\n"
1983 << "\tProjectCreator=\"Intel Fortran\"\n"
1984 << "\tVersion=\"" << intelVersion << "\"\n";
1985 const char* keyword = target.GetProperty("VS_KEYWORD");
1988 keyword = "Console Application";
1990 const char* projectType = 0;
1991 switch(target.GetType())
1993 case cmTarget::STATIC_LIBRARY:
1994 projectType = "typeStaticLibrary";
1997 keyword = "Static Library";
2000 case cmTarget::SHARED_LIBRARY:
2001 case cmTarget::MODULE_LIBRARY:
2002 projectType = "typeDynamicLibrary";
2008 case cmTarget::EXECUTABLE:
2011 keyword = "Console Application";
2015 case cmTarget::UTILITY:
2016 case cmTarget::GLOBAL_TARGET:
2022 fout << "\tProjectType=\"" << projectType << "\"\n";
2024 this->WriteProjectSCC(fout, target);
2025 fout<< "\tKeyword=\"" << keyword << "\">\n"
2026 << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\">\n"
2027 << "\t<Platforms>\n"
2028 << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n"
2029 << "\t</Platforms>\n";
2034 cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout,
2035 const char *libName,
2037 std::vector<cmSourceGroup> &)
2039 if(this->FortranProject)
2041 this->WriteProjectStartFortran(fout, libName, target);
2044 fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
2045 << "<VisualStudioProject\n"
2046 << "\tProjectType=\"Visual C++\"\n";
2047 if(this->Version == VS71)
2049 fout << "\tVersion=\"7.10\"\n";
2053 fout << "\tVersion=\"" << (this->Version/10) << ".00\"\n";
2055 const char* projLabel = target.GetProperty("PROJECT_LABEL");
2058 projLabel = libName;
2060 const char* keyword = target.GetProperty("VS_KEYWORD");
2063 keyword = "Win32Proj";
2065 cmGlobalVisualStudio7Generator* gg =
2066 static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
2067 fout << "\tName=\"" << projLabel << "\"\n";
2068 if(this->Version >= VS8)
2070 fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n";
2072 this->WriteProjectSCC(fout, target);
2073 fout << "\tKeyword=\"" << keyword << "\">\n"
2074 << "\t<Platforms>\n"
2075 << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n"
2076 << "\t</Platforms>\n";
2080 void cmLocalVisualStudio7Generator::WriteVCProjFooter(std::ostream& fout,
2083 fout << "\t<Globals>\n";
2085 cmPropertyMap const& props = target.GetProperties();
2086 for(cmPropertyMap::const_iterator i = props.begin(); i != props.end(); ++i)
2088 if(i->first.find("VS_GLOBAL_") == 0)
2090 std::string name = i->first.substr(10);
2093 fout << "\t\t<Global\n"
2094 << "\t\t\tName=\"" << name << "\"\n"
2095 << "\t\t\tValue=\"" << i->second.GetValue() << "\"\n"
2101 fout << "\t</Globals>\n"
2102 << "</VisualStudioProject>\n";
2105 std::string cmLocalVisualStudio7GeneratorEscapeForXML(const char* s)
2107 std::string ret = s;
2108 cmSystemTools::ReplaceString(ret, "&", "&");
2109 cmSystemTools::ReplaceString(ret, "\"", """);
2110 cmSystemTools::ReplaceString(ret, "<", "<");
2111 cmSystemTools::ReplaceString(ret, ">", ">");
2112 cmSystemTools::ReplaceString(ret, "\n", "
");
2116 std::string cmLocalVisualStudio7Generator::EscapeForXML(const char* s)
2118 return cmLocalVisualStudio7GeneratorEscapeForXML(s);
2121 std::string cmLocalVisualStudio7Generator
2122 ::ConvertToXMLOutputPath(const char* path)
2124 std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
2125 cmSystemTools::ReplaceString(ret, "&", "&");
2126 cmSystemTools::ReplaceString(ret, "\"", """);
2127 cmSystemTools::ReplaceString(ret, "<", "<");
2128 cmSystemTools::ReplaceString(ret, ">", ">");
2132 std::string cmLocalVisualStudio7Generator
2133 ::ConvertToXMLOutputPathSingle(const char* path)
2135 std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
2136 cmSystemTools::ReplaceString(ret, "\"", "");
2137 cmSystemTools::ReplaceString(ret, "&", "&");
2138 cmSystemTools::ReplaceString(ret, "<", "<");
2139 cmSystemTools::ReplaceString(ret, ">", ">");
2144 // This class is used to parse an existing vs 7 project
2145 // and extract the GUID
2146 class cmVS7XMLParser : public cmXMLParser
2149 virtual void EndElement(const char* /* name */)
2152 virtual void StartElement(const char* name, const char** atts)
2154 // once the GUID is found do nothing
2155 if(this->GUID.size())
2160 if(strcmp("VisualStudioProject", name) == 0)
2164 if(strcmp(atts[i], "ProjectGUID") == 0)
2168 this->GUID = atts[i+1];
2169 this->GUID = this->GUID.substr(1, this->GUID.size()-2);
2181 int InitializeParser()
2183 int ret = cmXMLParser::InitializeParser();
2188 // visual studio projects have a strange encoding, but it is
2190 XML_SetEncoding(static_cast<XML_Parser>(this->Parser), "utf-8");
2196 void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
2200 cmVS7XMLParser parser;
2201 parser.ParseFile(path);
2202 // if we can not find a GUID then create one
2203 if(parser.GUID.size() == 0)
2205 cmGlobalVisualStudio7Generator* gg =
2206 static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
2207 gg->CreateGUID(name);
2210 std::string guidStoreName = name;
2211 guidStoreName += "_GUID_CMAKE";
2212 // save the GUID in the cache
2213 this->GlobalGenerator->GetCMakeInstance()->
2214 AddCacheEntry(guidStoreName.c_str(),
2215 parser.GUID.c_str(),
2217 cmCacheManager::INTERNAL);
2221 //----------------------------------------------------------------------------
2222 std::string cmLocalVisualStudio7Generator
2223 ::GetTargetDirectory(cmTarget const& target) const
2226 dir += target.GetName();
2231 //----------------------------------------------------------------------------
2232 #include <windows.h>
2233 static bool cmLVS6G_IsFAT(const char* dir)
2235 if(dir[0] && dir[1] == ':')
2237 char volRoot[4] = "_:/";
2238 volRoot[0] = dir[0];
2240 if(GetVolumeInformation(volRoot, 0, 0, 0, 0, 0, fsName, 16) &&
2241 strstr(fsName, "FAT") != 0)