/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmLocalVisualStudio7Generator.h"

#include <algorithm>
#include <cassert>
#include <cstring>
#include <functional>
#include <sstream>
#include <utility>

#include <cm/memory>
#include <cm/optional>
#include <cmext/algorithm>

#include <windows.h>

#include <cm3p/expat.h>

#include "cmsys/FStream.hxx"

#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalVisualStudio7Generator.h"
#include "cmGlobalVisualStudioGenerator.h"
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmSourceFile.h"
#include "cmSourceGroup.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
#include "cmValue.h"
#include "cmVsProjectType.h"
#include "cmXMLParser.h"
#include "cmake.h"

static bool cmLVS7G_IsFAT(char const* dir);

class cmLocalVisualStudio7GeneratorInternals
{
public:
  cmLocalVisualStudio7GeneratorInternals(cmLocalVisualStudio7Generator* e)
    : LocalGenerator(e)
  {
  }
  using ItemVector = cmComputeLinkInformation::ItemVector;
  void OutputLibraries(std::ostream& fout, ItemVector const& libs);
  void OutputObjects(std::ostream& fout, cmGeneratorTarget* t,
                     std::string const& config, char const* isep = nullptr);

private:
  cmLocalVisualStudio7Generator* LocalGenerator;
};

class cmLocalVisualStudio7Generator::AllConfigSources
{
public:
  std::vector<cmGeneratorTarget::AllConfigSource> Sources;
  std::map<cmSourceFile const*, size_t> Index;
};

extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];

cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator(
  cmGlobalGenerator* gg, cmMakefile* mf)
  : cmLocalVisualStudioGenerator(gg, mf)
  , Internal(cm::make_unique<cmLocalVisualStudio7GeneratorInternals>(this))
{
}

cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator() = default;

void cmLocalVisualStudio7Generator::AddHelperCommands()
{
  // Now create GUIDs for targets
  auto const& tgts = this->GetGeneratorTargets();
  for (auto const& l : tgts) {
    if (!l->IsInBuildSystem()) {
      continue;
    }
    cmValue path = l->GetProperty("EXTERNAL_MSPROJECT");
    if (path) {
      this->ReadAndStoreExternalGUID(l->GetName(), path->c_str());
    }
  }

  this->FixGlobalTargets();
}

void cmLocalVisualStudio7Generator::Generate()
{
  // Create the project file for each target.
  for (cmGeneratorTarget* gt :
       this->GlobalGenerator->GetLocalGeneratorTargetsInOrder(this)) {
    if (!gt->IsInBuildSystem() || gt->GetProperty("EXTERNAL_MSPROJECT")) {
      continue;
    }

    auto& gtVisited = this->GetSourcesVisited(gt);
    auto const& deps = this->GlobalGenerator->GetTargetDirectDepends(gt);
    for (auto const& d : deps) {
      // Take the union of visited source files of custom commands
      auto depVisited = this->GetSourcesVisited(d);
      gtVisited.insert(depVisited.begin(), depVisited.end());
    }

    this->GenerateTarget(gt);
  }

  this->WriteStampFiles();
}

void cmLocalVisualStudio7Generator::FixGlobalTargets()
{
  // Visual Studio .NET 2003 Service Pack 1 will not run post-build
  // commands for targets in which no sources are built.  Add dummy
  // rules to force these targets to build.
  auto const& tgts = this->GetGeneratorTargets();
  for (auto const& l : tgts) {
    if (l->GetType() == cmStateEnums::GLOBAL_TARGET) {
      cmCustomCommandLines force_commands =
        cmMakeSingleCommandLine({ "cd", "." });
      std::string force = cmStrCat(this->GetCurrentBinaryDirectory(),
                                   "/CMakeFiles/", l->GetName(), "_force");
      if (cmSourceFile* sf =
            this->Makefile->GetOrCreateGeneratedSource(force)) {
        sf->SetProperty("SYMBOLIC", "1");
      }
      auto cc = cm::make_unique<cmCustomCommand>();
      cc->SetOutputs(force);
      cc->SetCommandLines(force_commands);
      cc->SetComment(" ");
      if (cmSourceFile* file =
            this->AddCustomCommandToOutput(std::move(cc), true)) {
        l->AddSource(file->ResolveFullPath());
      }
    }
  }
}

void cmLocalVisualStudio7Generator::WriteStampFiles()
{
  // Touch a timestamp file used to determine when the project file is
  // out of date.
  std::string stampName =
    cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles");
  cmSystemTools::MakeDirectory(stampName);
  stampName += "/generate.stamp";
  cmsys::ofstream stamp(stampName.c_str());
  stamp << "# CMake generation timestamp file for this directory.\n";

  // Create a helper file so CMake can determine when it is run
  // through the rule created by CreateVCProjBuildRule whether it
  // really needs to regenerate the project.  This file lists its own
  // dependencies.  If any file listed in it is newer than itself then
  // CMake must rerun.  Otherwise the project files are up to date and
  // the stamp file can just be touched.
  std::string depName = cmStrCat(stampName, ".depend");
  cmsys::ofstream depFile(depName.c_str());
  depFile << "# CMake generation dependency list for this directory.\n";

  std::vector<std::string> listFiles(this->Makefile->GetListFiles());
  cmake* cm = this->GlobalGenerator->GetCMakeInstance();
  if (cm->DoWriteGlobVerifyTarget()) {
    listFiles.push_back(cm->GetGlobVerifyStamp());
  }

  // Sort the list of input files and remove duplicates.
  std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
  auto new_end = std::unique(listFiles.begin(), listFiles.end());
  listFiles.erase(new_end, listFiles.end());

  for (std::string const& lf : listFiles) {
    depFile << lf << '\n';
  }
}

void cmLocalVisualStudio7Generator::GenerateTarget(cmGeneratorTarget* target)
{
  std::string const& lname = target->GetName();
  cmGlobalVisualStudioGenerator* gg =
    static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
  this->FortranProject = gg->TargetIsFortranOnly(target);
  this->WindowsCEProject = gg->TargetsWindowsCE();

  // add to the list of projects
  target->Target->SetProperty("GENERATOR_FILE_NAME", lname);
  // create the dsp.cmake file
  std::string fname;
  fname = cmStrCat(this->GetCurrentBinaryDirectory(), '/', lname);
  if (this->FortranProject) {
    fname += ".vfproj";
  } else {
    fname += ".vcproj";
  }

  // Generate the project file and replace it atomically with
  // copy-if-different.  We use a separate timestamp so that the IDE
  // does not reload project files unnecessarily.
  cmGeneratedFileStream fout(fname);
  fout.SetCopyIfDifferent(true);
  this->WriteVCProjFile(fout, lname, target);
  if (fout.Close()) {
    this->GlobalGenerator->FileReplacedDuringGenerate(fname);
  }

  this->WindowsCEProject = false;
  this->FortranProject = false;
}

cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
{
  if (this->GlobalGenerator->GlobalSettingIsOn(
        "CMAKE_SUPPRESS_REGENERATION")) {
    return nullptr;
  }

  std::string makefileIn = this->GetCMakeInstance()->GetCMakeListFile(
    this->GetCurrentSourceDirectory());
  if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
    if (file->GetCustomCommand()) {
      return file;
    }
  }
  if (!cmSystemTools::FileExists(makefileIn)) {
    return nullptr;
  }

  std::vector<std::string> listFiles = this->Makefile->GetListFiles();
  cmake* cm = this->GlobalGenerator->GetCMakeInstance();
  if (cm->DoWriteGlobVerifyTarget()) {
    listFiles.push_back(cm->GetGlobVerifyStamp());
  }

  // Sort the list of input files and remove duplicates.
  std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
  auto new_end = std::unique(listFiles.begin(), listFiles.end());
  listFiles.erase(new_end, listFiles.end());

  std::string argS = cmStrCat("-S", this->GetSourceDirectory());
  std::string argB = cmStrCat("-B", this->GetBinaryDirectory());
  std::string stampName =
    cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/generate.stamp");
  cmCustomCommandLines commandLines =
    cmMakeSingleCommandLine({ cmSystemTools::GetCMakeCommand(), argS, argB,
                              "--check-stamp-file", stampName });

  if (cm->GetIgnoreCompileWarningAsError()) {
    commandLines[0].emplace_back("--compile-no-warning-as-error");
  }
  if (cm->GetIgnoreLinkWarningAsError()) {
    commandLines[0].emplace_back("--link-no-warning-as-error");
  }
  std::string comment = cmStrCat("Building Custom Rule ", makefileIn);
  auto cc = cm::make_unique<cmCustomCommand>();
  cc->SetOutputs(stampName);
  cc->SetMainDependency(makefileIn);
  cc->SetDepends(listFiles);
  cc->SetCommandLines(commandLines);
  cc->SetComment(comment.c_str());
  cc->SetEscapeOldStyle(false);
  cc->SetStdPipesUTF8(true);
  cc->SetUsesTerminal(true);
  this->AddCustomCommandToOutput(std::move(cc), true);
  if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
    // Finalize the source file path now since we're adding this after
    // the generator validated all project-named sources.
    file->ResolveFullPath();
    return file;
  }
  cmSystemTools::Error(cmStrCat("Error adding rule for ", makefileIn));
  return nullptr;
}

void cmLocalVisualStudio7Generator::WriteConfigurations(
  std::ostream& fout, std::vector<std::string> const& configs,
  std::string const& libName, cmGeneratorTarget* target)
{
  fout << "\t<Configurations>\n";
  for (std::string const& config : configs) {
    this->WriteConfiguration(fout, config, libName, target);
  }
  fout << "\t</Configurations>\n";
}
cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] = {
  { "Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0 },
  { "Preprocess", "nofpp", "Run Preprocessor on files", "preprocessNo", 0 },
  { "SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0 },
  { "SourceFileFormat", "fixed", "Use Fixed Format", "fileFormatFixed", 0 },
  { "SourceFileFormat", "free", "Use Free Format", "fileFormatFree", 0 },
  { "DebugInformationFormat", "debug:full", "full debug", "debugEnabled", 0 },
  { "DebugInformationFormat", "debug:minimal", "line numbers",
    "debugLineInfoOnly", 0 },
  { "Optimization", "Od", "disable optimization", "optimizeDisabled", 0 },
  { "Optimization", "O1", "min space", "optimizeMinSpace", 0 },
  { "Optimization", "O3", "full optimize", "optimizeFull", 0 },
  { "GlobalOptimizations", "Og", "global optimize", "true", 0 },
  { "InterproceduralOptimizations", "Qipo",
    "Interprocedural optimization across multiple files", "ipoMultiFile", 0 },
  { "InlineFunctionExpansion", "Ob0", "", "expandDisable", 0 },
  { "InlineFunctionExpansion", "Ob1", "", "expandOnlyInline", 0 },
  { "FavorSizeOrSpeed", "Os", "", "favorSize", 0 },
  { "OmitFramePointers", "Oy-", "", "false", 0 },
  { "OptimizeForProcessor", "GB", "", "procOptimizeBlended", 0 },
  { "OptimizeForProcessor", "G5", "", "procOptimizePentium", 0 },
  { "OptimizeForProcessor", "G6", "", "procOptimizePentiumProThruIII", 0 },
  { "UseProcessorExtensions", "QzxK", "", "codeForStreamingSIMD", 0 },
  { "OptimizeForProcessor", "QaxN", "", "codeForPentium4", 0 },
  { "OptimizeForProcessor", "QaxB", "", "codeForPentiumM", 0 },
  { "OptimizeForProcessor", "QaxP", "", "codeForCodeNamedPrescott", 0 },
  { "OptimizeForProcessor", "QaxT", "", "codeForCore2Duo", 0 },
  { "OptimizeForProcessor", "QxK", "", "codeExclusivelyStreamingSIMD", 0 },
  { "OptimizeForProcessor", "QxN", "", "codeExclusivelyPentium4", 0 },
  { "OptimizeForProcessor", "QxB", "", "codeExclusivelyPentiumM", 0 },
  { "OptimizeForProcessor", "QxP", "", "codeExclusivelyCodeNamedPrescott", 0 },
  { "OptimizeForProcessor", "QxT", "", "codeExclusivelyCore2Duo", 0 },
  { "OptimizeForProcessor", "QxO", "", "codeExclusivelyCore2StreamingSIMD",
    0 },
  { "OptimizeForProcessor", "QxS", "", "codeExclusivelyCore2StreamingSIMD4",
    0 },
  { "OpenMP", "Qopenmp", "", "OpenMPParallelCode", 0 },
  { "OpenMP", "Qopenmp-stubs", "", "OpenMPSequentialCode", 0 },
  { "Traceback", "traceback", "", "true", 0 },
  { "Traceback", "notraceback", "", "false", 0 },
  { "FloatingPointExceptionHandling", "fpe:0", "", "fpe0", 0 },
  { "FloatingPointExceptionHandling", "fpe:1", "", "fpe1", 0 },
  { "FloatingPointExceptionHandling", "fpe:3", "", "fpe3", 0 },

  { "MultiProcessorCompilation", "MP", "", "true",
    cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
  { "ProcessorNumber", "MP", "Multi-processor Compilation", "",
    cmVS7FlagTable::UserValueRequired },

  { "ModulePath", "module:", "", "", cmVS7FlagTable::UserValueRequired },
  { "LoopUnrolling", "Qunroll:", "", "", cmVS7FlagTable::UserValueRequired },
  { "AutoParallelThreshold", "Qpar-threshold:", "", "",
    cmVS7FlagTable::UserValueRequired },
  { "HeapArrays", "heap-arrays:", "", "", cmVS7FlagTable::UserValueRequired },
  { "ObjectText", "bintext:", "", "", cmVS7FlagTable::UserValueRequired },
  { "Parallelization", "Qparallel", "", "true", 0 },
  { "PrefetchInsertion", "Qprefetch-", "", "false", 0 },
  { "BufferedIO", "assume:buffered_io", "", "true", 0 },
  { "CallingConvention", "iface:stdcall", "", "callConventionStdCall", 0 },
  { "CallingConvention", "iface:cref", "", "callConventionCRef", 0 },
  { "CallingConvention", "iface:stdref", "", "callConventionStdRef", 0 },
  { "CallingConvention", "iface:stdcall", "", "callConventionStdCall", 0 },
  { "CallingConvention", "iface:cvf", "", "callConventionCVF", 0 },
  { "EnableRecursion", "recursive", "", "true", 0 },
  { "ReentrantCode", "reentrancy", "", "true", 0 },
  // done up to Language
  { "", "", "", "", 0 }
};
// fill the table here currently the comment field is not used for
// anything other than documentation NOTE: Make sure the longer
// commandFlag comes FIRST!
cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] = {
  // option flags (some flags map to the same option)
  { "BasicRuntimeChecks", "GZ", "Stack frame checks", "1", 0 },
  { "BasicRuntimeChecks", "RTCsu", "Both stack and uninitialized checks", "3",
    0 },
  { "BasicRuntimeChecks", "RTCs", "Stack frame checks", "1", 0 },
  { "BasicRuntimeChecks", "RTCu", "Uninitialized Variables ", "2", 0 },
  { "BasicRuntimeChecks", "RTC1", "Both stack and uninitialized checks", "3",
    0 },
  { "DebugInformationFormat", "Z7", "debug format", "1", 0 },
  { "DebugInformationFormat", "Zd", "debug format", "2", 0 },
  { "DebugInformationFormat", "Zi", "debug format", "3", 0 },
  { "DebugInformationFormat", "ZI", "debug format", "4", 0 },
  { "EnableEnhancedInstructionSet", "arch:SSE2", "Use sse2 instructions", "2",
    0 },
  { "EnableEnhancedInstructionSet", "arch:SSE", "Use sse instructions", "1",
    0 },
  { "FloatingPointModel", "fp:precise", "Use precise floating point model",
    "0", 0 },
  { "FloatingPointModel", "fp:strict", "Use strict floating point model", "1",
    0 },
  { "FloatingPointModel", "fp:fast", "Use fast floating point model", "2", 0 },
  // noqa: spellcheck off
  { "FavorSizeOrSpeed", "Ot", "Favor fast code", "1", 0 },
  // noqa: spellcheck on
  { "FavorSizeOrSpeed", "Os", "Favor small code", "2", 0 },
  { "CompileAs", "TC", "Compile as c code", "1", 0 },
  { "CompileAs", "TP", "Compile as c++ code", "2", 0 },
  { "Optimization", "Od", "Non Debug", "0", 0 },
  { "Optimization", "O1", "Min Size", "1", 0 },
  { "Optimization", "O2", "Max Speed", "2", 0 },
  { "Optimization", "Ox", "Max Optimization", "3", 0 },
  { "OptimizeForProcessor", "GB", "Blended processor mode", "0", 0 },
  { "OptimizeForProcessor", "G5", "Pentium", "1", 0 },
  { "OptimizeForProcessor", "G6", "PPro PII PIII", "2", 0 },
  { "OptimizeForProcessor", "G7", "Pentium 4 or Athlon", "3", 0 },
  { "InlineFunctionExpansion", "Ob0", "no inlines", "0", 0 },
  { "InlineFunctionExpansion", "Ob1", "when inline keyword", "1", 0 },
  { "InlineFunctionExpansion", "Ob2", "any time you can inline", "2", 0 },
  { "RuntimeLibrary", "MTd", "Multithreaded debug", "1", 0 },
  { "RuntimeLibrary", "MT", "Multithreaded", "0", 0 },
  { "RuntimeLibrary", "MDd", "Multithreaded dll debug", "3", 0 },
  { "RuntimeLibrary", "MD", "Multithreaded dll", "2", 0 },
  { "RuntimeLibrary", "MLd", "Single Thread debug", "5", 0 },
  { "RuntimeLibrary", "ML", "Single Thread", "4", 0 },
  { "StructMemberAlignment", "Zp16", "struct align 16 byte ", "5", 0 },
  { "StructMemberAlignment", "Zp1", "struct align 1 byte ", "1", 0 },
  { "StructMemberAlignment", "Zp2", "struct align 2 byte ", "2", 0 },
  { "StructMemberAlignment", "Zp4", "struct align 4 byte ", "3", 0 },
  { "StructMemberAlignment", "Zp8", "struct align 8 byte ", "4", 0 },
  { "WarningLevel", "W0", "Warning level", "0", 0 },
  { "WarningLevel", "W1", "Warning level", "1", 0 },
  { "WarningLevel", "W2", "Warning level", "2", 0 },
  { "WarningLevel", "W3", "Warning level", "3", 0 },
  { "WarningLevel", "W4", "Warning level", "4", 0 },
  { "DisableSpecificWarnings", "wd", "Disable specific warnings", "",
    cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable },

  // Precompiled header and related options.  Note that the
  // UsePrecompiledHeader entries are marked as "Continue" so that the
  // corresponding PrecompiledHeaderThrough entry can be found.
  { "UsePrecompiledHeader", "Yc", "Create Precompiled Header", "1",
    cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue },
  { "PrecompiledHeaderThrough", "Yc", "Precompiled Header Name", "",
    cmVS7FlagTable::UserValueRequired },
  { "UsePrecompiledHeader", "Y-", "Don't use precompiled header", "0", 0 },
  { "PrecompiledHeaderFile", "Fp", "Generated Precompiled Header", "",
    cmVS7FlagTable::UserValue },
  // The YX and Yu options are in a per-global-generator table because
  // their values differ based on the VS IDE version.
  { "ForcedIncludeFiles", "FI", "Forced include files", "",
    cmVS7FlagTable::UserValueRequired | cmVS7FlagTable::SemicolonAppendable },

  { "AssemblerListingLocation", "Fa", "ASM List Location", "",
    cmVS7FlagTable::UserValue },
  { "ProgramDataBaseFileName", "Fd", "Program Database File Name", "",
    cmVS7FlagTable::UserValue },

  // boolean flags
  { "BufferSecurityCheck", "GS", "Buffer security check", "true", 0 },
  { "BufferSecurityCheck", "GS-", "Turn off Buffer security check", "false",
    0 },
  { "Detect64BitPortabilityProblems", "Wp64",
    "Detect 64-bit Portability Problems", "true", 0 },
  { "EnableFiberSafeOptimizations", "GT", "Enable Fiber-safe Optimizations",
    "true", 0 },
  { "EnableFunctionLevelLinking", "Gy", "EnableFunctionLevelLinking", "true",
    0 },
  { "EnableIntrinsicFunctions", "Oi", "EnableIntrinsicFunctions", "true", 0 },
  { "GlobalOptimizations", "Og", "Global Optimize", "true", 0 },
  { "ImproveFloatingPointConsistency", "Op", "ImproveFloatingPointConsistency",
    "true", 0 },
  { "MinimalRebuild", "Gm", "minimal rebuild", "true", 0 },
  { "OmitFramePointers", "Oy", "OmitFramePointers", "true", 0 },
  { "OptimizeForWindowsApplication", "GA", "Optimize for windows", "true", 0 },
  { "RuntimeTypeInfo", "GR", "Turn on Run time type information for c++",
    "true", 0 },
  { "RuntimeTypeInfo", "GR-", "Turn off Run time type information for c++",
    "false", 0 },
  { "SmallerTypeCheck", "RTCc", "smaller type check", "true", 0 },
  { "SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0 },
  { "WholeProgramOptimization", "GL", "Enables whole program optimization",
    "true", 0 },
  { "WholeProgramOptimization", "GL-", "Disables whole program optimization",
    "false", 0 },
  { "WarnAsError", "WX", "Treat warnings as errors", "true", 0 },
  { "BrowseInformation", "FR", "Generate browse information", "1", 0 },
  { "StringPooling", "GF", "Enable StringPooling", "true", 0 },
  { "", "", "", "", 0 }
};

cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] = {
  // option flags (some flags map to the same option)
  { "GenerateManifest", "MANIFEST:NO", "disable manifest generation", "false",
    0 },
  { "GenerateManifest", "MANIFEST", "enable manifest generation", "true", 0 },
  { "LinkIncremental", "INCREMENTAL:NO", "link incremental", "1", 0 },
  { "LinkIncremental", "INCREMENTAL:YES", "link incremental", "2", 0 },
  { "CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0 },
  { "CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0 },
  { "DataExecutionPrevention", "NXCOMPAT:NO",
    "Not known to work with Windows Data Execution Prevention", "1", 0 },
  { "DataExecutionPrevention", "NXCOMPAT",
    "Known to work with Windows Data Execution Prevention", "2", 0 },
  { "DelaySign", "DELAYSIGN:NO", "", "false", 0 },
  { "DelaySign", "DELAYSIGN", "", "true", 0 },
  { "EntryPointSymbol", "ENTRY:", "sets the starting address", "",
    cmVS7FlagTable::UserValue },
  { "IgnoreDefaultLibraryNames", "NODEFAULTLIB:", "default libs to ignore", "",
    cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable },
  { "IgnoreAllDefaultLibraries", "NODEFAULTLIB", "ignore all default libs",
    "true", 0 },
  { "FixedBaseAddress", "FIXED:NO", "Generate a relocation section", "1", 0 },
  { "FixedBaseAddress", "FIXED", "Image must be loaded at a fixed address",
    "2", 0 },
  { "EnableCOMDATFolding", "OPT:NOICF", "Do not remove redundant COMDATs", "1",
    0 },
  { "EnableCOMDATFolding", "OPT:ICF", "Remove redundant COMDATs", "2", 0 },
  { "ResourceOnlyDLL", "NOENTRY", "Create DLL with no entry point", "true",
    0 },
  { "OptimizeReferences", "OPT:NOREF", "Keep unreferenced data", "1", 0 },
  { "OptimizeReferences", "OPT:REF", "Eliminate unreferenced data", "2", 0 },
  { "Profile", "PROFILE", "", "true", 0 },
  { "RandomizedBaseAddress", "DYNAMICBASE:NO",
    "Image may not be rebased at load-time", "1", 0 },
  { "RandomizedBaseAddress", "DYNAMICBASE",
    "Image may be rebased at load-time", "2", 0 },
  { "SetChecksum", "RELEASE", "Enable setting checksum in header", "true", 0 },
  { "SupportUnloadOfDelayLoadedDLL", "DELAY:UNLOAD", "", "true", 0 },
  { "TargetMachine", "MACHINE:I386", "Machine x86", "1", 0 },
  { "TargetMachine", "MACHINE:X86", "Machine x86", "1", 0 },
  { "TargetMachine", "MACHINE:AM33", "Machine AM33", "2", 0 },
  { "TargetMachine", "MACHINE:ARM", "Machine ARM", "3", 0 },
  { "TargetMachine", "MACHINE:EBC", "Machine EBC", "4", 0 },
  { "TargetMachine", "MACHINE:IA64", "Machine IA64", "5", 0 },
  { "TargetMachine", "MACHINE:M32R", "Machine M32R", "6", 0 },
  { "TargetMachine", "MACHINE:MIPS", "Machine MIPS", "7", 0 },
  { "TargetMachine", "MACHINE:MIPS16", "Machine MIPS16", "8", 0 },
  { "TargetMachine", "MACHINE:MIPSFPU)", "Machine MIPSFPU", "9", 0 },
  { "TargetMachine", "MACHINE:MIPSFPU16", "Machine MIPSFPU16", "10", 0 },
  { "TargetMachine", "MACHINE:MIPSR41XX", "Machine MIPSR41XX", "11", 0 },
  { "TargetMachine", "MACHINE:SH3", "Machine SH3", "12", 0 },
  { "TargetMachine", "MACHINE:SH3DSP", "Machine SH3DSP", "13", 0 },
  { "TargetMachine", "MACHINE:SH4", "Machine SH4", "14", 0 },
  { "TargetMachine", "MACHINE:SH5", "Machine SH5", "15", 0 },
  { "TargetMachine", "MACHINE:THUMB", "Machine THUMB", "16", 0 },
  { "TargetMachine", "MACHINE:X64", "Machine x64", "17", 0 },
  { "TargetMachine", "MACHINE:ARM64", "Machine ARM64", "18", 0 },
  { "TurnOffAssemblyGeneration", "NOASSEMBLY",
    "No assembly even if CLR information is present in objects.", "true", 0 },
  { "ModuleDefinitionFile", "DEF:", "add an export def file", "",
    cmVS7FlagTable::UserValue },
  { "GenerateMapFile", "MAP", "enable generation of map file", "true", 0 },
  { "", "", "", "", 0 }
};

cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranLinkFlagTable[] = {
  { "LinkIncremental", "INCREMENTAL:NO", "link incremental",
    "linkIncrementalNo", 0 },
  { "LinkIncremental", "INCREMENTAL:YES", "link incremental",
    "linkIncrementalYes", 0 },
  { "EnableCOMDATFolding", "OPT:NOICF", "Do not remove redundant COMDATs",
    "optNoFolding", 0 },
  { "EnableCOMDATFolding", "OPT:ICF", "Remove redundant COMDATs", "optFolding",
    0 },
  { "OptimizeReferences", "OPT:NOREF", "Keep unreferenced data",
    "optNoReferences", 0 },
  { "OptimizeReferences", "OPT:REF", "Eliminate unreferenced data",
    "optReferences", 0 },
  { "", "", "", "", 0 }
};

// Helper class to write build event <Tool .../> elements.
class cmLocalVisualStudio7Generator::EventWriter
{
public:
  EventWriter(cmLocalVisualStudio7Generator* lg, std::string config,
              std::ostream& os)
    : LG(lg)
    , Config(std::move(config))
    , Stream(os)
  {
  }
  void Start(char const* tool)
  {
    this->First = true;
    this->Stream << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << '"';
  }
  void Finish()
  {
    // If any commands were generated, finish constructing them.
    if (!this->First) {
      std::string finishScript =
        this->LG->FinishConstructScript(VsProjectType::vcxproj);
      this->Stream << this->LG->EscapeForXML(finishScript) << '"';
    }

    this->Stream << "/>\n";
  }
  void Write(std::vector<cmCustomCommand> const& ccs)
  {
    for (cmCustomCommand const& command : ccs) {
      this->Write(command);
    }
  }
  void Write(cmCustomCommand const& cc)
  {
    cmCustomCommandGenerator ccg(cc, this->Config, this->LG);
    if (this->First) {
      if (cm::optional<std::string> comment = ccg.GetComment()) {
        this->Stream << "\nDescription=\"" << this->LG->EscapeForXML(*comment)
                     << "\"";
      }
      this->Stream << "\nCommandLine=\"";
      this->First = false;
    } else {
      this->Stream << this->LG->EscapeForXML("\n");
    }
    std::string script = this->LG->ConstructScript(ccg);
    this->Stream << this->LG->EscapeForXML(script);
  }

private:
  cmLocalVisualStudio7Generator* LG;
  std::string Config;
  std::ostream& Stream;
  bool First = true;
};

void cmLocalVisualStudio7Generator::WriteConfiguration(
  std::ostream& fout, std::string const& configName,
  std::string const& libName, cmGeneratorTarget* target)
{
  std::string mfcFlag;
  if (cmValue p = this->Makefile->GetDefinition("CMAKE_MFC_FLAG")) {
    mfcFlag = cmGeneratorExpression::Evaluate(*p, this, configName);
  } else {
    mfcFlag = "0";
  }
  cmGlobalVisualStudio7Generator* gg =
    static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
  fout << "\t\t<Configuration\n"
          "\t\t\tName=\""
       << configName << '|' << gg->GetPlatformName() << "\"\n";
  // This is an internal type to Visual Studio, it seems that:
  // 4 == static library
  // 2 == dll
  // 1 == executable
  // 10 == utility
  char const* configType = "10";
  char const* projectType = nullptr;
  bool targetBuilds = true;

  switch (target->GetType()) {
    case cmStateEnums::OBJECT_LIBRARY:
      targetBuilds = false; // no manifest tool for object library
      CM_FALLTHROUGH;
    case cmStateEnums::STATIC_LIBRARY:
      projectType = "typeStaticLibrary";
      configType = "4";
      break;
    case cmStateEnums::SHARED_LIBRARY:
    case cmStateEnums::MODULE_LIBRARY:
      projectType = "typeDynamicLibrary";
      configType = "2";
      break;
    case cmStateEnums::EXECUTABLE:
      configType = "1";
      break;
    case cmStateEnums::UTILITY:
    case cmStateEnums::GLOBAL_TARGET:
    case cmStateEnums::INTERFACE_LIBRARY:
      configType = "10";
      CM_FALLTHROUGH;
    case cmStateEnums::UNKNOWN_LIBRARY:
      targetBuilds = false;
      break;
  }
  if (this->FortranProject && projectType) {
    configType = projectType;
  }
  std::string flags;
  std::string langForClCompile;
  std::string const& linkLanguage =
    (this->FortranProject ? std::string("Fortran")
                          : target->GetLinkerLanguage(configName));
  if (linkLanguage.empty()) {
    cmSystemTools::Error(
      cmStrCat("CMake can not determine linker language for target: ",
               target->GetName()));
    return;
  }
  if (target->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
    langForClCompile = linkLanguage;
    if (langForClCompile == "C" || langForClCompile == "CXX" ||
        langForClCompile == "Fortran") {
      this->AddLanguageFlags(flags, target, cmBuildStep::Compile,
                             langForClCompile, configName);
    }
    // set the correct language
    if (linkLanguage == "C") {
      flags += " /TC ";
    }
    if (linkLanguage == "CXX") {
      flags += " /TP ";
    }

    // Add the target-specific flags.
    this->AddCompileOptions(flags, target, langForClCompile, configName);

    // Check IPO related warning/error.
    if (target->IsIPOEnabled(linkLanguage, configName)) {
      if (this->FortranProject) {
        this->AppendCompileOptions(flags,
                                   this->Makefile->GetSafeDefinition(
                                     "CMAKE_Fortran_COMPILE_OPTIONS_IPO"));
      }
    }
  }

  if (this->FortranProject) {
    switch (cmOutputConverter::GetFortranFormat(
      target->GetSafeProperty("Fortran_FORMAT"))) {
      case cmOutputConverter::FortranFormatFixed:
        flags += " -fixed";
        break;
      case cmOutputConverter::FortranFormatFree:
        flags += " -free";
        break;
      default:
        break;
    }

    switch (cmOutputConverter::GetFortranPreprocess(
      target->GetSafeProperty("Fortran_PREPROCESS"))) {
      case cmOutputConverter::FortranPreprocess::Needed:
        flags += " -fpp";
        break;
      case cmOutputConverter::FortranPreprocess::NotNeeded:
        flags += " -nofpp";
        break;
      default:
        break;
    }
  }

  // Get preprocessor definitions for this directory.
  std::string defineFlags = this->Makefile->GetDefineFlags();
  Options::Tool t = Options::Compiler;
  cmVS7FlagTable const* table = cmLocalVisualStudio7GeneratorFlagTable;
  if (this->FortranProject) {
    t = Options::FortranCompiler;
    table = cmLocalVisualStudio7GeneratorFortranFlagTable;
  }
  Options targetOptions(this, t, table, gg->ExtraFlagTable);
  targetOptions.FixExceptionHandlingDefault();
  targetOptions.AddFlag("AssemblerListingLocation", "$(IntDir)\\");
  targetOptions.Parse(flags);
  targetOptions.Parse(defineFlags);
  targetOptions.ParseFinish();
  if (!langForClCompile.empty()) {
    std::vector<std::string> targetDefines;
    target->GetCompileDefinitions(targetDefines, configName, langForClCompile);
    targetOptions.AddDefines(targetDefines);

    std::vector<std::string> targetIncludes;
    this->GetIncludeDirectories(targetIncludes, target, langForClCompile,
                                configName);
    targetOptions.AddIncludes(targetIncludes);
  }
  targetOptions.SetVerboseMakefile(
    this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));

  // Add a definition for the configuration name.
  std::string configDefine = cmStrCat("CMAKE_INTDIR=\"", configName, '"');
  targetOptions.AddDefine(configDefine);

  // Add the export symbol definition for shared library objects.
  if (std::string const* exportMacro = target->GetExportMacro()) {
    targetOptions.AddDefine(*exportMacro);
  }

  // The intermediate directory name consists of a directory for the
  // target and a subdirectory for the configuration name.
  std::string intermediateDir =
    cmStrCat(this->GetTargetDirectory(target), '/', configName);

  if (target->GetType() < cmStateEnums::UTILITY) {
    std::string const& outDir =
      target->GetType() == cmStateEnums::OBJECT_LIBRARY
      ? intermediateDir
      : target->GetDirectory(configName);
    fout << "\t\t\tOutputDirectory=\""
         << this->ConvertToXMLOutputPathSingle(outDir) << "\"\n";
  }

  fout << "\t\t\tIntermediateDirectory=\""
       << this->ConvertToXMLOutputPath(intermediateDir)
       << "\"\n"
          "\t\t\tConfigurationType=\""
       << configType
       << "\"\n"
          "\t\t\tUseOfMFC=\""
       << mfcFlag
       << "\"\n"
          "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"false\"\n";

  if (this->FortranProject) {
    // Intel Fortran >= 15.0 uses TargetName property.
    std::string const targetNameFull = target->GetFullName(configName);
    std::string const targetName =
      cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
    std::string const targetExt =
      target->GetType() == cmStateEnums::OBJECT_LIBRARY
      ? ".lib"
      : cmSystemTools::GetFilenameLastExtension(targetNameFull);
    if (cm::optional<std::string> fortran = gg->GetPlatformToolsetFortran()) {
      fout << "\t\t\tUseCompiler=\"" << *fortran << "Compiler\"\n";
    }
    /* clang-format off */
    fout <<
      "\t\t\tTargetName=\"" << this->EscapeForXML(targetName) << "\"\n"
      "\t\t\tTargetExt=\"" << this->EscapeForXML(targetExt) << "\"\n"
      ;
    /* clang-format on */
  }

  // If unicode is enabled change the character set to unicode, if not
  // then default to MBCS.
  if (targetOptions.UsingUnicode()) {
    fout << "\t\t\tCharacterSet=\"1\">\n";
  } else if (targetOptions.UsingSBCS()) {
    fout << "\t\t\tCharacterSet=\"0\">\n";
  } else {
    fout << "\t\t\tCharacterSet=\"2\">\n";
  }
  char const* tool = "VCCLCompilerTool";
  if (this->FortranProject) {
    tool = "VFFortranCompilerTool";
  }
  fout << "\t\t\t<Tool\n"
          "\t\t\t\tName=\""
       << tool << "\"\n";
  if (this->FortranProject) {
    cmValue target_mod_dir = target->GetProperty("Fortran_MODULE_DIRECTORY");
    std::string modDir;
    if (target_mod_dir) {
      modDir = this->MaybeRelativeToCurBinDir(*target_mod_dir);
    } else {
      modDir = ".";
    }
    fout << "\t\t\t\tModulePath=\"" << this->ConvertToXMLOutputPath(modDir)
         << "\\$(ConfigurationName)\"\n";
  }
  targetOptions.OutputAdditionalIncludeDirectories(
    fout, 4, this->FortranProject ? "Fortran" : langForClCompile);
  targetOptions.OutputFlagMap(fout, 4);
  targetOptions.OutputPreprocessorDefinitions(fout, 4, langForClCompile);
  fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n";
  if (target->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
    // Specify the compiler program database file if configured.
    std::string pdb = target->GetCompilePDBPath(configName);
    if (!pdb.empty()) {
      fout << "\t\t\t\tProgramDataBaseFileName=\""
           << this->ConvertToXMLOutputPathSingle(pdb) << "\"\n";
    }
  }
  fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
  if (gg->IsMarmasmEnabled() && !this->FortranProject) {
    Options marmasmOptions(this, Options::MarmasmCompiler, nullptr, nullptr);
    fout << "\t\t\t<Tool\n"
            "\t\t\t\tName=\"MARMASM\"\n";
    targetOptions.OutputAdditionalIncludeDirectories(fout, 4, "ASM_MARMASM");
    // Use same preprocessor definitions as VCCLCompilerTool.
    targetOptions.OutputPreprocessorDefinitions(fout, 4, "ASM_MARMASM");
    marmasmOptions.OutputFlagMap(fout, 4);
    fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n"
            "\t\t\t/>\n";
  }
  if (gg->IsMasmEnabled() && !this->FortranProject) {
    Options masmOptions(this, Options::MasmCompiler, nullptr, nullptr);
    fout << "\t\t\t<Tool\n"
            "\t\t\t\tName=\"MASM\"\n";
    targetOptions.OutputAdditionalIncludeDirectories(fout, 4, "ASM_MASM");
    // Use same preprocessor definitions as VCCLCompilerTool.
    targetOptions.OutputPreprocessorDefinitions(fout, 4, "ASM_MASM");
    masmOptions.OutputFlagMap(fout, 4);
    fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n"
            "\t\t\t/>\n";
  }
  tool = "VCCustomBuildTool";
  if (this->FortranProject) {
    tool = "VFCustomBuildTool";
  }
  fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"/>\n";
  tool = "VCResourceCompilerTool";
  if (this->FortranProject) {
    tool = "VFResourceCompilerTool";
  }
  fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n";
  targetOptions.OutputAdditionalIncludeDirectories(fout, 4, "RC");
  // add the -D flags to the RC tool
  targetOptions.OutputPreprocessorDefinitions(fout, 4, "RC");
  fout << "\t\t\t/>\n";
  tool = "VCMIDLTool";
  if (this->FortranProject) {
    tool = "VFMIDLTool";
  }
  fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n";
  targetOptions.OutputAdditionalIncludeDirectories(fout, 4, "MIDL");
  fout << "\t\t\t\tMkTypLibCompatible=\"false\"\n";
  if (gg->GetPlatformName() == "x64") {
    fout << "\t\t\t\tTargetEnvironment=\"3\"\n";
  } else if (gg->GetPlatformName() == "ia64") {
    fout << "\t\t\t\tTargetEnvironment=\"2\"\n";
  } else {
    fout << "\t\t\t\tTargetEnvironment=\"1\"\n";
  }
  fout << "\t\t\t\tGenerateStublessProxies=\"true\"\n"
          "\t\t\t\tTypeLibraryName=\"$(InputName).tlb\"\n"
          "\t\t\t\tOutputDirectory=\"$(IntDir)\"\n"
          "\t\t\t\tHeaderFileName=\"$(InputName).h\"\n"
          "\t\t\t\tDLLDataFileName=\"\"\n"
          "\t\t\t\tInterfaceIdentifierFileName=\"$(InputName)_i.c\"\n"
          "\t\t\t\tProxyFileName=\"$(InputName)_p.c\"/>\n";
  // end of <Tool Name=VCMIDLTool

  // Add manifest tool settings.
  if (targetBuilds) {
    char const* manifestTool = "VCManifestTool";
    if (this->FortranProject) {
      manifestTool = "VFManifestTool";
    }
    fout << "\t\t\t<Tool\n"
            "\t\t\t\tName=\""
         << manifestTool << '"';

    std::vector<cmSourceFile const*> manifest_srcs;
    target->GetManifests(manifest_srcs, configName);
    if (!manifest_srcs.empty()) {
      fout << "\n\t\t\t\tAdditionalManifestFiles=\"";
      for (cmSourceFile const* manifest : manifest_srcs) {
        std::string m = manifest->GetFullPath();
        fout << this->ConvertToXMLOutputPath(m) << ';';
      }
      fout << '"';
    }

    // Check if we need the FAT32 workaround.
    // Check the filesystem type where the target will be written.
    if (cmLVS7G_IsFAT(target->GetDirectory(configName).c_str())) {
      // Add a flag telling the manifest tool to use a workaround
      // for FAT32 file systems, which can cause an empty manifest
      // to be embedded into the resulting executable.  See CMake
      // bug #2617.
      fout << "\n\t\t\t\tUseFAT32Workaround=\"true\"";
    }
    fout << "/>\n";
  }

  this->OutputTargetRules(fout, configName, target, libName);
  this->OutputBuildTool(fout, linkLanguage, configName, target, targetOptions);
  this->OutputDeploymentDebuggerTool(fout, configName, target);
  fout << "\t\t</Configuration>\n";
}

void cmLocalVisualStudio7Generator::OutputBuildTool(
  std::ostream& fout, std::string const& linkLanguage,
  std::string const& configName, cmGeneratorTarget* target,
  Options const& targetOptions)
{
  cmGlobalVisualStudio7Generator* gg =
    static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
  std::string temp;
  std::string extraLinkOptions;
  if (target->GetType() == cmStateEnums::EXECUTABLE) {
    this->AddConfigVariableFlags(extraLinkOptions, "CMAKE_EXE_LINKER_FLAGS",
                                 target, cmBuildStep::Link, linkLanguage,
                                 configName);
  }
  if (target->GetType() == cmStateEnums::SHARED_LIBRARY) {
    this->AddConfigVariableFlags(extraLinkOptions, "CMAKE_SHARED_LINKER_FLAGS",
                                 target, cmBuildStep::Link, linkLanguage,
                                 configName);
  }
  if (target->GetType() == cmStateEnums::MODULE_LIBRARY) {
    this->AddConfigVariableFlags(extraLinkOptions, "CMAKE_MODULE_LINKER_FLAGS",
                                 target, cmBuildStep::Link, linkLanguage,
                                 configName);
  }

  cmValue targetLinkFlags = target->GetProperty("LINK_FLAGS");
  if (targetLinkFlags) {
    extraLinkOptions += ' ';
    extraLinkOptions += *targetLinkFlags;
  }
  std::string configTypeUpper = cmSystemTools::UpperCase(configName);
  std::string linkFlagsConfig = cmStrCat("LINK_FLAGS_", configTypeUpper);
  targetLinkFlags = target->GetProperty(linkFlagsConfig);
  if (targetLinkFlags) {
    extraLinkOptions += ' ';
    extraLinkOptions += *targetLinkFlags;
  }

  std::vector<std::string> opts;
  target->GetLinkOptions(opts, configName,
                         target->GetLinkerLanguage(configName));
  // LINK_OPTIONS are escaped.
  this->AppendCompileOptions(extraLinkOptions, opts);

  this->AppendWarningAsErrorLinkerFlags(extraLinkOptions, target,
                                        linkLanguage);

  Options linkOptions(this, Options::Linker);
  if (this->FortranProject) {
    linkOptions.AddTable(cmLocalVisualStudio7GeneratorFortranLinkFlagTable);
  }
  linkOptions.AddTable(cmLocalVisualStudio7GeneratorLinkFlagTable);

  linkOptions.Parse(extraLinkOptions);
  cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
    target->GetModuleDefinitionInfo(configName);
  if (mdi && !mdi->DefFile.empty()) {
    std::string defFile =
      this->ConvertToOutputFormat(mdi->DefFile, cmOutputConverter::SHELL);
    linkOptions.AddFlag("ModuleDefinitionFile", defFile);
  }

  switch (target->GetType()) {
    case cmStateEnums::UNKNOWN_LIBRARY:
      break;
    case cmStateEnums::OBJECT_LIBRARY: {
      std::string libpath =
        cmStrCat(this->GetTargetDirectory(target), '/', configName, '/',
                 target->GetName(), ".lib");
      char const* tool =
        this->FortranProject ? "VFLibrarianTool" : "VCLibrarianTool";
      fout << "\t\t\t<Tool\n"
              "\t\t\t\tName=\""
           << tool
           << "\"\n"
              "\t\t\t\tOutputFile=\""
           << this->ConvertToXMLOutputPathSingle(libpath) << "\"/>\n";
      break;
    }
    case cmStateEnums::STATIC_LIBRARY: {
      std::string targetNameFull = target->GetFullName(configName);
      std::string libpath =
        cmStrCat(target->GetDirectory(configName), '/', targetNameFull);
      char const* tool = "VCLibrarianTool";
      if (this->FortranProject) {
        tool = "VFLibrarianTool";
      }
      fout << "\t\t\t<Tool\n"
              "\t\t\t\tName=\""
           << tool << "\"\n";

      if (this->FortranProject) {
        std::ostringstream libdeps;
        this->Internal->OutputObjects(libdeps, target, configName);
        if (!libdeps.str().empty()) {
          fout << "\t\t\t\tAdditionalDependencies=\"" << libdeps.str()
               << "\"\n";
        }
      }
      std::string libflags;
      this->GetStaticLibraryFlags(
        libflags, configName, target->GetLinkerLanguage(configName), target);
      if (!libflags.empty()) {
        fout << "\t\t\t\tAdditionalOptions=\"" << this->EscapeForXML(libflags)
             << "\"\n";
      }
      fout << "\t\t\t\tOutputFile=\""
           << this->ConvertToXMLOutputPathSingle(libpath) << "\"/>\n";
      break;
    }
    case cmStateEnums::SHARED_LIBRARY:
    case cmStateEnums::MODULE_LIBRARY: {
      cmGeneratorTarget::Names targetNames =
        target->GetLibraryNames(configName);

      // Compute the link library and directory information.
      cmComputeLinkInformation* pcli = target->GetLinkInformation(configName);
      if (!pcli) {
        return;
      }
      cmComputeLinkInformation& cli = *pcli;

      if (!target->GetLinkerTypeProperty(linkLanguage, configName).empty()) {
        // Visual Studio 10 or upper is required for this feature
        this->GetCMakeInstance()->IssueMessage(
          MessageType::FATAL_ERROR,
          cmStrCat("'LINKER_TYPE' property, specified on target '",
                   target->GetName(),
                   "', is not supported by this generator."),
          target->GetBacktrace());
      }

      // Compute the variable name to lookup standard libraries for this
      // language.
      std::string standardLibsVar =
        cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES");
      char const* tool = "VCLinkerTool";
      if (this->FortranProject) {
        tool = "VFLinkerTool";
      }
      fout << "\t\t\t<Tool\n"
              "\t\t\t\tName=\""
           << tool << "\"\n";
      if (!gg->NeedLinkLibraryDependencies(target)) {
        fout << "\t\t\t\tLinkLibraryDependencies=\"false\"\n";
      }
      // Use the NOINHERIT macro to avoid getting VS project default
      // libraries which may be set by the user to something bad.
      fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
           << this->Makefile->GetSafeDefinition(standardLibsVar);
      if (this->FortranProject) {
        this->Internal->OutputObjects(fout, target, configName, " ");
      }
      fout << ' ';
      this->Internal->OutputLibraries(fout, cli.GetItems());
      fout << "\"\n";
      temp =
        cmStrCat(target->GetDirectory(configName), '/', targetNames.Output);
      fout << "\t\t\t\tOutputFile=\""
           << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
      this->WriteTargetVersionAttribute(fout, target);
      linkOptions.OutputFlagMap(fout, 4);
      fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
      std::string const& linkDirsString = this->Makefile->GetSafeDefinition(
        cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LINK_DIRECTORIES"));
      this->OutputLibraryDirectories(fout, cmList(linkDirsString),
                                     cli.GetDirectories());
      fout << "\"\n";
      temp =
        cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB);
      fout << "\t\t\t\tProgramDatabaseFile=\""
           << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
      if (targetOptions.UsingDebugInfo()) {
        fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
      }
      if (this->WindowsCEProject) {
        fout << "\t\t\t\tSubSystem=\"8\"\n";
      }
      std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE");
      cmValue stackVal = this->Makefile->GetDefinition(stackVar);
      if (stackVal) {
        fout << "\t\t\t\tStackReserveSize=\"" << *stackVal << "\"\n";
      }
      if (!targetNames.ImportLibrary.empty()) {
        temp = cmStrCat(target->GetDirectory(
                          configName, cmStateEnums::ImportLibraryArtifact),
                        '/', targetNames.ImportLibrary);
        fout << "\t\t\t\tImportLibrary=\""
             << this->ConvertToXMLOutputPathSingle(temp) << "\"";
      }
      if (this->FortranProject) {
        fout << "\n\t\t\t\tLinkDLL=\"true\"";
      }
      fout << "/>\n";
    } break;
    case cmStateEnums::EXECUTABLE: {
      cmGeneratorTarget::Names targetNames =
        target->GetExecutableNames(configName);

      // Compute the link library and directory information.
      cmComputeLinkInformation* pcli = target->GetLinkInformation(configName);
      if (!pcli) {
        return;
      }
      cmComputeLinkInformation& cli = *pcli;

      if (!target->GetLinkerTypeProperty(linkLanguage, configName).empty()) {
        // Visual Studio 10 or upper is required for this feature
        this->GetCMakeInstance()->IssueMessage(
          MessageType::FATAL_ERROR,
          cmStrCat("'LINKER_TYPE' property, specified on target '",
                   target->GetName(),
                   "', is not supported by this generator."),
          target->GetBacktrace());
      }

      bool isWin32Executable = target->IsWin32Executable(configName);

      // Compute the variable name to lookup standard libraries for this
      // language.
      std::string standardLibsVar =
        cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES");
      char const* tool = "VCLinkerTool";
      if (this->FortranProject) {
        tool = "VFLinkerTool";
      }
      fout << "\t\t\t<Tool\n"
              "\t\t\t\tName=\""
           << tool << "\"\n";
      if (!gg->NeedLinkLibraryDependencies(target)) {
        fout << "\t\t\t\tLinkLibraryDependencies=\"false\"\n";
      }
      // Use the NOINHERIT macro to avoid getting VS project default
      // libraries which may be set by the user to something bad.
      fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
           << this->Makefile->GetSafeDefinition(standardLibsVar);
      if (this->FortranProject) {
        this->Internal->OutputObjects(fout, target, configName, " ");
      }
      fout << " ";
      this->Internal->OutputLibraries(fout, cli.GetItems());
      fout << "\"\n";
      temp =
        cmStrCat(target->GetDirectory(configName), '/', targetNames.Output);
      fout << "\t\t\t\tOutputFile=\""
           << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
      this->WriteTargetVersionAttribute(fout, target);
      linkOptions.OutputFlagMap(fout, 4);
      fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
      std::string const& linkDirsString = this->Makefile->GetSafeDefinition(
        cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LINK_DIRECTORIES"));
      this->OutputLibraryDirectories(fout, cmList(linkDirsString),
                                     cli.GetDirectories());
      fout << "\"\n";
      std::string path = this->ConvertToXMLOutputPathSingle(
        target->GetPDBDirectory(configName));
      fout << "\t\t\t\tProgramDatabaseFile=\"" << path << '/'
           << targetNames.PDB << "\"\n";
      if (targetOptions.UsingDebugInfo()) {
        fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
      }
      if (this->WindowsCEProject) {
        fout << "\t\t\t\tSubSystem=\"8\"\n";

        if (!linkOptions.GetFlag("EntryPointSymbol")) {
          char const* entryPointSymbol = targetOptions.UsingUnicode()
            ? (isWin32Executable ? "wWinMainCRTStartup" : "mainWCRTStartup")
            : (isWin32Executable ? "WinMainCRTStartup" : "mainACRTStartup");
          fout << "\t\t\t\tEntryPointSymbol=\"" << entryPointSymbol << "\"\n";
        }
      } else if (this->FortranProject) {
        fout << "\t\t\t\tSubSystem=\""
             << (isWin32Executable ? "subSystemWindows" : "subSystemConsole")
             << "\"\n";
      } else {
        fout << "\t\t\t\tSubSystem=\"" << (isWin32Executable ? "2" : "1")
             << "\"\n";
      }
      std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE");
      cmValue stackVal = this->Makefile->GetDefinition(stackVar);
      if (stackVal) {
        fout << "\t\t\t\tStackReserveSize=\"" << *stackVal << '"';
      }
      temp = cmStrCat(
        target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact),
        '/', targetNames.ImportLibrary);
      fout << "\t\t\t\tImportLibrary=\""
           << this->ConvertToXMLOutputPathSingle(temp) << "\"/>\n";
      break;
    }
    case cmStateEnums::UTILITY:
    case cmStateEnums::GLOBAL_TARGET:
    case cmStateEnums::INTERFACE_LIBRARY:
      break;
  }
}

static std::string cmLocalVisualStudio7GeneratorEscapeForXML(
  std::string const& s)
{
  std::string ret = s;
  cmSystemTools::ReplaceString(ret, "&", "&amp;");
  cmSystemTools::ReplaceString(ret, "\"", "&quot;");
  cmSystemTools::ReplaceString(ret, "<", "&lt;");
  cmSystemTools::ReplaceString(ret, ">", "&gt;");
  cmSystemTools::ReplaceString(ret, "\n", "&#x0D;&#x0A;");
  return ret;
}

static std::string GetEscapedPropertyIfValueNotNULL(char const* propertyValue)
{
  return propertyValue
    ? cmLocalVisualStudio7GeneratorEscapeForXML(propertyValue)
    : std::string();
}

void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool(
  std::ostream& fout, std::string const& config, cmGeneratorTarget* target)
{
  if (this->WindowsCEProject) {
    cmValue dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
    cmValue additionalFiles =
      target->GetProperty("DEPLOYMENT_ADDITIONAL_FILES");

    if (!dir && !additionalFiles) {
      return;
    }

    fout << "\t\t\t<DeploymentTool\n"
            "\t\t\t\tForceDirty=\"-1\"\n"
            "\t\t\t\tRemoteDirectory=\""
         << GetEscapedPropertyIfValueNotNULL(dir->c_str())
         << "\"\n"
            "\t\t\t\tRegisterOutput=\"0\"\n"
            "\t\t\t\tAdditionalFiles=\""
         << GetEscapedPropertyIfValueNotNULL(additionalFiles->c_str())
         << "\"/>\n";

    if (dir) {
      std::string const exe =
        cmStrCat(*dir, '\\', target->GetFullName(config));

      fout << "\t\t\t<DebuggerTool\n"
              "\t\t\t\tRemoteExecutable=\""
           << this->EscapeForXML(exe)
           << "\"\n"
              "\t\t\t\tArguments=\"\"\n"
              "\t\t\t/>\n";
    }
  }
}

void cmLocalVisualStudio7Generator::WriteTargetVersionAttribute(
  std::ostream& fout, cmGeneratorTarget* gt)
{
  int major;
  int minor;
  gt->GetTargetVersion(major, minor);
  fout << "\t\t\t\tVersion=\"" << major << "." << minor << "\"\n";
}

void cmLocalVisualStudio7GeneratorInternals::OutputLibraries(
  std::ostream& fout, ItemVector const& libs)
{
  cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
  for (auto const& lib : libs) {
    if (lib.IsPath == cmComputeLinkInformation::ItemIsPath::Yes) {
      std::string rel = lg->MaybeRelativeToCurBinDir(lib.Value.Value);
      rel = lg->ConvertToXMLOutputPath(rel);
      fout << (lib.HasFeature() ? lib.GetFormattedItem(rel).Value : rel)
           << " ";
    } else if (!lib.Target ||
               (lib.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
                lib.Target->GetType() != cmStateEnums::OBJECT_LIBRARY)) {
      fout << lib.Value.Value << " ";
    }
  }
}

void cmLocalVisualStudio7GeneratorInternals::OutputObjects(
  std::ostream& fout, cmGeneratorTarget* gt, std::string const& configName,
  char const* isep)
{
  // VS < 8 does not support per-config source locations so we
  // list object library content on the link line instead.
  cmLocalVisualStudio7Generator* lg = this->LocalGenerator;

  std::vector<cmSourceFile const*> objs;
  gt->GetExternalObjects(objs, configName);

  char const* sep = isep ? isep : "";
  for (cmSourceFile const* obj : objs) {
    if (!obj->GetObjectLibrary().empty()) {
      std::string const& objFile = obj->GetFullPath();
      std::string rel = lg->MaybeRelativeToCurBinDir(objFile);
      fout << sep << lg->ConvertToXMLOutputPath(rel);
      sep = " ";
    }
  }
}

void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
  std::ostream& fout, std::vector<std::string> const& stdlink,
  std::vector<std::string> const& dirs)
{
  char const* comma = "";

  for (std::string dir : dirs) {
    // Remove any trailing slash and skip empty paths.
    if (dir.back() == '/') {
      dir = dir.substr(0, dir.size() - 1);
    }
    if (dir.empty()) {
      continue;
    }

    // Switch to a relative path specification if it is shorter.
    if (cmSystemTools::FileIsFullPath(dir)) {
      std::string rel = this->MaybeRelativeToCurBinDir(dir);
      if (rel.size() < dir.size()) {
        dir = rel;
      }
    }

    // First search a configuration-specific subdirectory and then the
    // original directory.
    fout << comma
         << this->ConvertToXMLOutputPath(
              cmStrCat(dir, "/$(ConfigurationName)"))
         << ',' << this->ConvertToXMLOutputPath(dir);
    comma = ",";
  }

  // No special processing on toolchain-defined standard link directory paths
  for (auto const& dir : stdlink) {
    fout << comma << this->ConvertToXMLOutputPath(dir);
    comma = ",";
  }
}

void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
                                                    std::string const& libName,
                                                    cmGeneratorTarget* target)
{
  std::vector<std::string> configs =
    this->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);

  // We may be modifying the source groups temporarily, so make a copy.
  std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();

  AllConfigSources sources;
  sources.Sources = target->GetAllConfigSources();

  // Add CMakeLists.txt file with rule to re-run CMake for user convenience.
  if (target->GetType() != cmStateEnums::GLOBAL_TARGET &&
      target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
    if (cmSourceFile* sf = this->CreateVCProjBuildRule()) {
      cmGeneratorTarget::AllConfigSource acs;
      acs.Source = sf;
      acs.Kind = cmGeneratorTarget::SourceKindCustomCommand;
      for (size_t ci = 0; ci < configs.size(); ++ci) {
        acs.Configs.push_back(ci);
      }
      bool haveCMakeLists = false;
      for (cmGeneratorTarget::AllConfigSource& si : sources.Sources) {
        if (si.Source == sf) {
          haveCMakeLists = true;
          // Replace the explicit source reference with our generated one.
          si = acs;
          break;
        }
      }
      if (!haveCMakeLists) {
        sources.Sources.emplace_back(std::move(acs));
      }
    }
  }

  for (size_t si = 0; si < sources.Sources.size(); ++si) {
    cmSourceFile const* sf = sources.Sources[si].Source;
    sources.Index[sf] = si;
    if (!sf->GetObjectLibrary().empty()) {
      if (this->FortranProject) {
        // Intel Fortran does not support per-config source locations
        // so we list object library content on the link line instead.
        // See OutputObjects.
        continue;
      }
    }
    // Add the file to the list of sources.
    std::string const source = sf->GetFullPath();
    cmSourceGroup* sourceGroup =
      this->Makefile->FindSourceGroup(source, sourceGroups);
    sourceGroup->AssignSource(sf);
  }

  // open the project
  this->WriteProjectStart(fout, libName, target, sourceGroups);
  // write the configuration information
  this->WriteConfigurations(fout, configs, libName, target);

  fout << "\t<Files>\n";

  // Loop through every source group.
  for (auto const& sg : sourceGroups) {
    this->WriteGroup(&sg, target, fout, libName, configs, sources);
  }

  fout << "\t</Files>\n";

  // Write the VCProj file's footer.
  this->WriteVCProjFooter(fout, target);
}

struct cmLVS7GFileConfig
{
  std::string ObjectName;
  std::string CompileFlags;
  std::string CompileDefs;
  std::string CompileDefsConfig;
  std::string AdditionalDeps;
  std::string IncludeDirs;
  bool ExcludedFromBuild;
};

class cmLocalVisualStudio7GeneratorFCInfo
{
public:
  cmLocalVisualStudio7GeneratorFCInfo(
    cmLocalVisualStudio7Generator* lg, cmGeneratorTarget* target,
    cmGeneratorTarget::AllConfigSource const& acs,
    std::vector<std::string> const& configs);
  std::map<std::string, cmLVS7GFileConfig> FileConfigMap;
};

cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
  cmLocalVisualStudio7Generator* lg, cmGeneratorTarget* gt,
  cmGeneratorTarget::AllConfigSource const& acs,
  std::vector<std::string> const& configs)
{
  cmSourceFile const& sf = *acs.Source;
  std::string objectName;
  if (gt->HasExplicitObjectName(&sf)) {
    objectName = gt->GetObjectName(&sf);
  }

  // Compute per-source, per-config information.
  size_t ci = 0;
  for (std::string const& config : configs) {
    std::string configUpper = cmSystemTools::UpperCase(config);
    cmLVS7GFileConfig fc;

    std::string lang =
      lg->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str());
    std::string const& sourceLang = lg->GetSourceFileLanguage(sf);
    bool needForceLang = false;
    // source file does not match its extension language
    if (lang != sourceLang) {
      needForceLang = true;
      lang = sourceLang;
    }

    cmGeneratorExpressionInterpreter genexInterpreter(lg, config, gt, lang);

    bool needfc = false;
    if (!objectName.empty()) {
      fc.ObjectName = objectName;
      needfc = true;
    }
    std::string const COMPILE_FLAGS("COMPILE_FLAGS");
    if (cmValue cflags = sf.GetProperty(COMPILE_FLAGS)) {
      fc.CompileFlags = genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS);
      needfc = true;
    }
    std::string const COMPILE_OPTIONS("COMPILE_OPTIONS");
    if (cmValue coptions = sf.GetProperty(COMPILE_OPTIONS)) {
      lg->AppendCompileOptions(
        fc.CompileFlags,
        genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
      needfc = true;
    }
    // Add precompile headers compile options.
    std::string const pchSource = gt->GetPchSource(config, lang);
    if (!pchSource.empty() && !sf.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
      std::string pchOptions;
      if (sf.GetFullPath() == pchSource) {
        pchOptions = gt->GetPchCreateCompileOptions(config, lang);
      } else {
        pchOptions = gt->GetPchUseCompileOptions(config, lang);
      }

      lg->AppendCompileOptions(
        fc.CompileFlags,
        genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
      needfc = true;
    }

    if (lg->FortranProject) {
      switch (cmOutputConverter::GetFortranPreprocess(
        sf.GetSafeProperty("Fortran_PREPROCESS"))) {
        case cmOutputConverter::FortranPreprocess::Needed:
          fc.CompileFlags = cmStrCat("-fpp ", fc.CompileFlags);
          needfc = true;
          break;
        case cmOutputConverter::FortranPreprocess::NotNeeded:
          fc.CompileFlags = cmStrCat("-nofpp ", fc.CompileFlags);
          needfc = true;
          break;
        default:
          break;
      }

      switch (cmOutputConverter::GetFortranFormat(
        sf.GetSafeProperty("Fortran_FORMAT"))) {
        case cmOutputConverter::FortranFormatFixed:
          fc.CompileFlags = cmStrCat("-fixed ", fc.CompileFlags);
          needfc = true;
          break;
        case cmOutputConverter::FortranFormatFree:
          fc.CompileFlags = cmStrCat("-free ", fc.CompileFlags);
          needfc = true;
          break;
        default:
          break;
      }
    }
    std::string const COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
    if (cmValue cdefs = sf.GetProperty(COMPILE_DEFINITIONS)) {
      fc.CompileDefs = genexInterpreter.Evaluate(*cdefs, COMPILE_DEFINITIONS);
      needfc = true;
    }
    std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
    if (cmValue ccdefs = sf.GetProperty(defPropName)) {
      fc.CompileDefsConfig =
        genexInterpreter.Evaluate(*ccdefs, COMPILE_DEFINITIONS);
      needfc = true;
    }

    std::string const INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
    if (cmValue cincs = sf.GetProperty(INCLUDE_DIRECTORIES)) {
      fc.IncludeDirs = genexInterpreter.Evaluate(*cincs, INCLUDE_DIRECTORIES);
      needfc = true;
    }

    // Check for extra object-file dependencies.
    if (cmValue deps = sf.GetProperty("OBJECT_DEPENDS")) {
      cmList depends{ *deps };
      if (!depends.empty()) {
        for (std::string& d : depends) {
          d = lg->ConvertToXMLOutputPath(d);
        }
        fc.AdditionalDeps += depends.to_string();
        needfc = true;
      }
    }

    std::string const& linkLanguage = gt->GetLinkerLanguage(config);
    // If HEADER_FILE_ONLY is set, we must suppress this generation in
    // the project file
    fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
      !cm::contains(acs.Configs, ci) ||
      (gt->GetPropertyAsBool("UNITY_BUILD") &&
       sf.GetProperty("UNITY_SOURCE_FILE") &&
       !sf.GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION"));
    if (fc.ExcludedFromBuild) {
      needfc = true;
    }

    // if the source file does not match the linker language
    // then force c or c++
    if (needForceLang || (linkLanguage != lang)) {
      if (lang == "CXX") {
        // force a C++ file type
        fc.CompileFlags += " /TP ";
        needfc = true;
      } else if (lang == "C") {
        // force to c
        fc.CompileFlags += " /TC ";
        needfc = true;
      }
    }

    if (needfc) {
      this->FileConfigMap[config] = fc;
    }
    ++ci;
  }
}

std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
  cmGeneratorTarget const* target) const
{
  std::vector<std::string> configs =
    target->Target->GetMakefile()->GetGeneratorConfigs(
      cmMakefile::ExcludeEmptyConfig);

  // Compute the maximum length configuration name.
  std::string config_max;
  for (auto& config : configs) {
    if (config.size() > config_max.size()) {
      config_max = config;
    }
  }

  // Compute the maximum length full path to the intermediate
  // files directory for any configuration.  This is used to construct
  // object file names that do not produce paths that are too long.
  std::string dir_max =
    cmStrCat(this->GetCurrentBinaryDirectory(), '/',
             this->GetTargetDirectory(target), '/', config_max, '/');
  return dir_max;
}

bool cmLocalVisualStudio7Generator::WriteGroup(
  cmSourceGroup const* sg, cmGeneratorTarget* target, std::ostream& fout,
  std::string const& libName, std::vector<std::string> const& configs,
  AllConfigSources const& sources)
{
  cmGlobalVisualStudio7Generator* gg =
    static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
  std::vector<cmSourceFile const*> const& sourceFiles = sg->GetSourceFiles();
  std::vector<cmSourceGroup> const& children = sg->GetGroupChildren();

  // Write the children to temporary output.
  bool hasChildrenWithSources = false;
  std::ostringstream tmpOut;
  for (auto const& child : children) {
    if (this->WriteGroup(&child, target, tmpOut, libName, configs, sources)) {
      hasChildrenWithSources = true;
    }
  }

  // If the group is empty, don't write it at all.
  if (sourceFiles.empty() && !hasChildrenWithSources) {
    return false;
  }

  // If the group has a name, write the header.
  std::string const& name = sg->GetName();
  if (!name.empty()) {
    this->WriteVCProjBeginGroup(fout, name.c_str(), "");
  }

  auto& sourcesVisited = this->GetSourcesVisited(target);

  // Loop through each source in the source group.
  for (cmSourceFile const* sf : sourceFiles) {
    std::string source = sf->GetFullPath();

    if (source != libName || target->GetType() == cmStateEnums::UTILITY ||
        target->GetType() == cmStateEnums::GLOBAL_TARGET ||
        target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
      // Look up the source kind and configs.
      auto map_it = sources.Index.find(sf);
      // The map entry must exist because we populated it earlier.
      assert(map_it != sources.Index.end());
      cmGeneratorTarget::AllConfigSource const& acs =
        sources.Sources[map_it->second];

      FCInfo fcinfo(this, target, acs, configs);

      fout << "\t\t\t<File\n";
      std::string d = this->ConvertToXMLOutputPathSingle(source);
      // Tell MS-Dev what the source is.  If the compiler knows how to
      // build it, then it will.
      fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
      if (cmCustomCommand const* command = sf->GetCustomCommand()) {
        if (sourcesVisited.insert(sf).second) {
          this->WriteCustomRule(fout, configs, source.c_str(), *command,
                                fcinfo);
        }
      } else if (!fcinfo.FileConfigMap.empty()) {
        char const* aCompilerTool = "VCCLCompilerTool";
        std::string ppLang = "CXX";
        if (this->FortranProject) {
          aCompilerTool = "VFFortranCompilerTool";
        }
        std::string const& lang = sf->GetLanguage();
        std::string ext = sf->GetExtension();
        ext = cmSystemTools::LowerCase(ext);
        if (ext == "idl") {
          aCompilerTool = "VCMIDLTool";
          if (this->FortranProject) {
            aCompilerTool = "VFMIDLTool";
          }
        }
        if (ext == "rc") {
          aCompilerTool = "VCResourceCompilerTool";
          ppLang = "RC";
          if (this->FortranProject) {
            aCompilerTool = "VFResourceCompilerTool";
          }
        }
        if (ext == "def") {
          aCompilerTool = "VCCustomBuildTool";
          if (this->FortranProject) {
            aCompilerTool = "VFCustomBuildTool";
          }
        }
        if (gg->IsMarmasmEnabled() && !this->FortranProject &&
            lang == "ASM_MARMASM") {
          aCompilerTool = "MARMASM";
        }
        if (gg->IsMasmEnabled() && !this->FortranProject &&
            lang == "ASM_MASM") {
          aCompilerTool = "MASM";
        }
        if (acs.Kind == cmGeneratorTarget::SourceKindExternalObject) {
          aCompilerTool = "VCCustomBuildTool";
        }
        for (auto const& fci : fcinfo.FileConfigMap) {
          cmLVS7GFileConfig const& fc = fci.second;
          fout << "\t\t\t\t<FileConfiguration\n"
                  "\t\t\t\t\tName=\""
               << fci.first << '|' << gg->GetPlatformName() << '"';
          if (fc.ExcludedFromBuild) {
            fout << " ExcludedFromBuild=\"true\"";
          }
          fout << ">\n"
                  "\t\t\t\t\t<Tool\n"
                  "\t\t\t\t\tName=\""
               << aCompilerTool << "\"\n";
          if (!fc.CompileFlags.empty() || !fc.CompileDefs.empty() ||
              !fc.CompileDefsConfig.empty() || !fc.IncludeDirs.empty()) {
            Options::Tool tool = Options::Compiler;
            cmVS7FlagTable const* table =
              cmLocalVisualStudio7GeneratorFlagTable;
            if (this->FortranProject) {
              tool = Options::FortranCompiler;
              table = cmLocalVisualStudio7GeneratorFortranFlagTable;
            }
            Options fileOptions(this, tool, table, gg->ExtraFlagTable);
            fileOptions.Parse(fc.CompileFlags);
            fileOptions.AddDefines(fc.CompileDefs);
            fileOptions.AddDefines(fc.CompileDefsConfig);
            // validate source level include directories
            std::vector<std::string> includes;
            this->AppendIncludeDirectories(includes, fc.IncludeDirs, *sf);
            fileOptions.AddIncludes(includes);
            fileOptions.OutputFlagMap(fout, 5);
            fileOptions.OutputAdditionalIncludeDirectories(
              fout, 5,
              ppLang == "CXX" && this->FortranProject ? "Fortran" : ppLang);
            fileOptions.OutputPreprocessorDefinitions(fout, 5, ppLang);
          }
          if (!fc.AdditionalDeps.empty()) {
            fout << "\t\t\t\t\tAdditionalDependencies=\"" << fc.AdditionalDeps
                 << "\"\n";
          }
          if (!fc.ObjectName.empty()) {
            fout << "\t\t\t\t\tObjectFile=\"$(IntDir)/" << fc.ObjectName
                 << "\"\n";
          }
          fout << "\t\t\t\t\t/>\n"
                  "\t\t\t\t</FileConfiguration>\n";
        }
      }
      fout << "\t\t\t</File>\n";
    }
  }

  // If the group has children with source files, write the children.
  if (hasChildrenWithSources) {
    fout << tmpOut.str();
  }

  // If the group has a name, write the footer.
  if (!name.empty()) {
    this->WriteVCProjEndGroup(fout);
  }

  return true;
}

void cmLocalVisualStudio7Generator::WriteCustomRule(
  std::ostream& fout, std::vector<std::string> const& configs,
  char const* source, cmCustomCommand const& command, FCInfo& fcinfo)
{
  cmGlobalVisualStudio7Generator* gg =
    static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);

  // Write the rule for each configuration.
  char const* compileTool = "VCCLCompilerTool";
  if (this->FortranProject) {
    compileTool = "VFCLCompilerTool";
  }
  char const* customTool = "VCCustomBuildTool";
  if (this->FortranProject) {
    customTool = "VFCustomBuildTool";
  }
  for (std::string const& config : configs) {
    cmCustomCommandGenerator ccg(command, config, this);
    cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[config];
    fout << "\t\t\t\t<FileConfiguration\n"
            "\t\t\t\t\tName=\""
         << config << '|' << gg->GetPlatformName() << "\">\n";
    if (!fc.CompileFlags.empty()) {
      fout << "\t\t\t\t\t<Tool\n"
              "\t\t\t\t\tName=\""
           << compileTool
           << "\"\n"
              "\t\t\t\t\tAdditionalOptions=\""
           << this->EscapeForXML(fc.CompileFlags) << "\"/>\n";
    }

    std::string comment = this->ConstructComment(ccg);
    std::string script = this->ConstructScript(ccg);
    if (this->FortranProject) {
      cmSystemTools::ReplaceString(script, "$(Configuration)", config);
    }
    script += this->FinishConstructScript(VsProjectType::vcxproj);
    /* clang-format off */
    fout << "\t\t\t\t\t<Tool\n"
            "\t\t\t\t\tName=\"" << customTool << "\"\n"
         << "\t\t\t\t\tDescription=\""
         << this->EscapeForXML(comment) << "\"\n"
            "\t\t\t\t\tCommandLine=\""
         << this->EscapeForXML(script) << "\"\n"
            "\t\t\t\t\tAdditionalDependencies=\"";
    /* clang-format on */
    if (ccg.GetDepends().empty()) {
      // There are no real dependencies.  Produce an artificial one to
      // make sure the rule runs reliably.
      if (!cmSystemTools::FileExists(source)) {
        cmsys::ofstream depout(source);
        depout << "Artificial dependency for a custom command.\n";
      }
      fout << this->ConvertToXMLOutputPath(source);
    } else {
      // Write out the dependencies for the rule.
      for (std::string const& d : ccg.GetDepends()) {
        // Get the real name of the dependency in case it is a CMake target.
        std::string dep;
        if (this->GetRealDependency(d, config, dep)) {
          fout << this->ConvertToXMLOutputPath(dep) << ";";
        }
      }
    }
    fout << "\"\n"
            "\t\t\t\t\tOutputs=\"";
    if (ccg.GetOutputs().empty()) {
      fout << source << "_force";
    } else {
      // Write a rule for the output generated by this command.
      char const* sep = "";
      for (std::string const& output : ccg.GetOutputs()) {
        fout << sep << this->ConvertToXMLOutputPathSingle(output);
        sep = ";";
      }
    }
    fout << "\"/>\n"
            "\t\t\t\t</FileConfiguration>\n";
  }
}

void cmLocalVisualStudio7Generator::WriteVCProjBeginGroup(std::ostream& fout,
                                                          char const* group,
                                                          char const*)
{
  fout << "\t\t<Filter\n"
          "\t\t\tName=\""
       << group
       << "\"\n"
          "\t\t\tFilter=\"\">\n";
}

void cmLocalVisualStudio7Generator::WriteVCProjEndGroup(std::ostream& fout)
{
  fout << "\t\t</Filter>\n";
}

// look for custom rules on a target and collect them together
void cmLocalVisualStudio7Generator::OutputTargetRules(
  std::ostream& fout, std::string const& configName, cmGeneratorTarget* target,
  std::string const& /*libName*/)
{
  if (target->GetType() > cmStateEnums::GLOBAL_TARGET) {
    return;
  }
  EventWriter event(this, configName, fout);

  // Add pre-build event.
  char const* tool =
    this->FortranProject ? "VFPreBuildEventTool" : "VCPreBuildEventTool";
  event.Start(tool);
  event.Write(target->GetPreBuildCommands());
  event.Finish();

  // Add pre-link event.
  tool = this->FortranProject ? "VFPreLinkEventTool" : "VCPreLinkEventTool";
  event.Start(tool);
  bool addedPrelink = false;
  cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
    target->GetModuleDefinitionInfo(configName);
  if (mdi && mdi->DefFileGenerated) {
    addedPrelink = true;
    std::vector<cmCustomCommand> commands = target->GetPreLinkCommands();
    cmGlobalVisualStudioGenerator* gg =
      static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
    gg->AddSymbolExportCommand(target, commands, configName);
    event.Write(commands);
  }
  if (!addedPrelink) {
    event.Write(target->GetPreLinkCommands());
  }
  std::unique_ptr<cmCustomCommand> pcc(
    this->MaybeCreateImplibDir(target, configName, this->FortranProject));
  if (pcc) {
    event.Write(*pcc);
  }
  event.Finish();

  // Add post-build event.
  tool =
    this->FortranProject ? "VFPostBuildEventTool" : "VCPostBuildEventTool";
  event.Start(tool);
  event.Write(target->GetPostBuildCommands());
  event.Finish();
}

void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout,
                                                    cmGeneratorTarget* target)
{
  // if we have all the required Source code control tags
  // then add that to the project
  cmValue vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME");
  cmValue vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH");
  cmValue vsProvider = target->GetProperty("VS_SCC_PROVIDER");

  if (vsProvider && vsLocalpath && vsProjectname) {
    /* clang-format off */
    fout << "\tSccProjectName=\"" << *vsProjectname << "\"\n"
            "\tSccLocalPath=\"" << *vsLocalpath << "\"\n"
            "\tSccProvider=\"" << *vsProvider << "\"\n";
    /* clang-format on */

    cmValue vsAuxPath = target->GetProperty("VS_SCC_AUXPATH");
    if (vsAuxPath) {
      fout << "\tSccAuxPath=\"" << *vsAuxPath << "\"\n";
    }
  }
}

void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
  std::ostream& fout, std::string const& libName, cmGeneratorTarget* target)
{

  cmGlobalVisualStudio7Generator* gg =
    static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
  fout << R"(<?xml version="1.0" encoding = ")" << gg->Encoding()
       << "\"?>\n"
          "<VisualStudioProject\n"
          "\tProjectCreator=\"Intel Fortran\"\n"
          "\tVersion=\""
       << gg->GetIntelProjectVersion() << "\"\n";
  cmValue p = target->GetProperty("VS_KEYWORD");
  char const* keyword = p ? p->c_str() : "Console Application";
  char const* projectType = nullptr;
  switch (target->GetType()) {
    case cmStateEnums::OBJECT_LIBRARY:
    case cmStateEnums::STATIC_LIBRARY:
      projectType = "typeStaticLibrary";
      if (keyword) {
        keyword = "Static Library";
      }
      break;
    case cmStateEnums::SHARED_LIBRARY:
    case cmStateEnums::MODULE_LIBRARY:
      projectType = "typeDynamicLibrary";
      if (!keyword) {
        keyword = "Dll";
      }
      break;
    case cmStateEnums::EXECUTABLE:
      if (!keyword) {
        keyword = "Console Application";
      }
      projectType = nullptr;
      break;
    case cmStateEnums::UTILITY:
    case cmStateEnums::GLOBAL_TARGET:
    case cmStateEnums::INTERFACE_LIBRARY:
    case cmStateEnums::UNKNOWN_LIBRARY:
      break;
  }
  if (projectType) {
    fout << "\tProjectType=\"" << projectType << "\"\n";
  }
  this->WriteProjectSCC(fout, target);
  /* clang-format off */
  fout<< "\tKeyword=\"" << keyword << "\">\n"
         "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\">\n"
         "\t<Platforms>\n"
         "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
         "\t</Platforms>\n";
  /* clang-format on */
}

void cmLocalVisualStudio7Generator::WriteProjectStart(
  std::ostream& fout, std::string const& libName, cmGeneratorTarget* target,
  std::vector<cmSourceGroup>&)
{
  if (this->FortranProject) {
    this->WriteProjectStartFortran(fout, libName, target);
    return;
  }

  cmGlobalVisualStudio7Generator* gg =
    static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);

  fout << R"(<?xml version="1.0" encoding = ")" << gg->Encoding()
       << "\"?>\n"
          "<VisualStudioProject\n"
          "\tProjectType=\"Visual C++\"\n"
          "\tVersion=\""
       << (static_cast<uint16_t>(gg->GetVersion()) / 10) << ".00\"\n";
  cmValue p = target->GetProperty("PROJECT_LABEL");
  std::string const projLabel = p ? *p : libName;
  p = target->GetProperty("VS_KEYWORD");
  std::string const keyword = p ? *p : "Win32Proj";
  fout << "\tName=\"" << projLabel
       << "\"\n"
          "\tProjectGUID=\"{"
       << gg->GetGUID(libName) << "}\"\n";
  this->WriteProjectSCC(fout, target);
  if (cmValue targetFrameworkVersion =
        target->GetProperty("VS_DOTNET_TARGET_FRAMEWORK_VERSION")) {
    fout << "\tTargetFrameworkVersion=\"" << *targetFrameworkVersion << "\"\n";
  }
  /* clang-format off */
  fout << "\tKeyword=\"" << keyword << "\">\n"
          "\t<Platforms>\n"
          "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
          "\t</Platforms>\n";
  /* clang-format on */
  if (gg->IsMarmasmEnabled()) {
    fout << "\t<ToolFiles>\n"
            "\t\t<DefaultToolFile\n"
            "\t\t\tFileName=\"marmasm.rules\"\n"
            "\t\t/>\n"
            "\t</ToolFiles>\n";
  }
  if (gg->IsMasmEnabled()) {
    fout << "\t<ToolFiles>\n"
            "\t\t<DefaultToolFile\n"
            "\t\t\tFileName=\"masm.rules\"\n"
            "\t\t/>\n"
            "\t</ToolFiles>\n";
  }
}

void cmLocalVisualStudio7Generator::WriteVCProjFooter(
  std::ostream& fout, cmGeneratorTarget* target)
{
  fout << "\t<Globals>\n";

  for (std::string const& key : target->GetPropertyKeys()) {
    if (cmHasLiteralPrefix(key, "VS_GLOBAL_")) {
      std::string name = key.substr(10);
      if (!name.empty()) {
        fout << "\t\t<Global\n"
                "\t\t\tName=\""
             << name
             << "\"\n"
                "\t\t\tValue=\""
             << target->GetProperty(key)
             << "\"\n"
                "\t\t/>\n";
      }
    }
  }

  fout << "\t</Globals>\n"
          "</VisualStudioProject>\n";
}

std::string cmLocalVisualStudio7Generator::EscapeForXML(std::string const& s)
{
  return cmLocalVisualStudio7GeneratorEscapeForXML(s);
}

std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPath(
  std::string const& path)
{
  std::string ret =
    this->ConvertToOutputFormat(path, cmOutputConverter::SHELL);
  cmSystemTools::ReplaceString(ret, "&", "&amp;");
  cmSystemTools::ReplaceString(ret, "\"", "&quot;");
  cmSystemTools::ReplaceString(ret, "<", "&lt;");
  cmSystemTools::ReplaceString(ret, ">", "&gt;");
  return ret;
}

std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPathSingle(
  std::string const& path)
{
  std::string ret =
    this->ConvertToOutputFormat(path, cmOutputConverter::SHELL);
  cmSystemTools::ReplaceString(ret, "\"", "");
  cmSystemTools::ReplaceString(ret, "&", "&amp;");
  cmSystemTools::ReplaceString(ret, "<", "&lt;");
  cmSystemTools::ReplaceString(ret, ">", "&gt;");
  return ret;
}

void cmVS7GeneratorOptions::OutputFlag(std::ostream& fout, int indent,
                                       std::string const& flag,
                                       std::string const& content)
{
  fout.fill('\t');
  fout.width(indent);
  // write an empty string to get the fill level indent to print
  fout << "" << flag << "=\""
       << cmLocalVisualStudio7GeneratorEscapeForXML(content) << "\"\n";
}

// This class is used to parse an existing vs 7 project
// and extract the GUID
class cmVS7XMLParser : public cmXMLParser
{
public:
  void EndElement(std::string const& /* name */) override {}
  void StartElement(std::string const& name, char const** atts) override
  {
    // once the GUID is found do nothing
    if (!this->GUID.empty()) {
      return;
    }
    int i = 0;
    if ("VisualStudioProject" == name) {
      while (atts[i]) {
        if (strcmp(atts[i], "ProjectGUID") == 0) {
          if (atts[i + 1]) {
            this->GUID = atts[i + 1];
            if (this->GUID[0] == '{') {
              // remove surrounding curly brackets
              this->GUID = this->GUID.substr(1, this->GUID.size() - 2);
            }
          } else {
            this->GUID.clear();
          }
          return;
        }
        ++i;
      }
    }
  }
  int InitializeParser() override
  {
    int ret = cmXMLParser::InitializeParser();
    if (ret == 0) {
      return ret;
    }
    // visual studio projects have a strange encoding, but it is
    // really utf-8
    XML_SetEncoding(static_cast<XML_Parser>(this->Parser), "utf-8");
    return 1;
  }
  std::string GUID;
};

void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
  std::string const& name, char const* path)
{
  cmVS7XMLParser parser;
  parser.ParseFile(path);
  // if we can not find a GUID then we will generate one later
  if (parser.GUID.empty()) {
    return;
  }
  std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE");
  // save the GUID in the cache
  this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry(
    guidStoreName, parser.GUID, "Stored GUID", cmStateEnums::INTERNAL);
}

std::string cmLocalVisualStudio7Generator::GetTargetDirectory(
  cmGeneratorTarget const* target) const
{
  std::string dir = cmStrCat(target->GetName(), ".dir");
  return dir;
}

static bool cmLVS7G_IsFAT(char const* dir)
{
  if (dir[0] && dir[1] == ':') {
    char volRoot[4] = "_:/";
    volRoot[0] = dir[0];
    char fsName[16];
    if (GetVolumeInformationA(volRoot, 0, 0, 0, 0, 0, fsName, 16) &&
        strstr(fsName, "FAT") != nullptr) {
      return true;
    }
  }
  return false;
}
