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

#include <cmext/algorithm>

#include <cm3p/uv.h>
#include <fcntl.h>

#include "cmConsoleBuf.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmQtAutoMocUic.h"
#include "cmQtAutoRcc.h"
#include "cmRange.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTransformDepfile.h"
#include "cmUVProcessChain.h"
#include "cmUtils.hxx"
#include "cmVersion.h"
#include "cmake.h"

#if !defined(CMAKE_BOOTSTRAP)
#  include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
#  include "cmFileTime.h"

#  include "bindexplib.h"
#endif

#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
#  include "cmVisualStudioWCEPlatformParser.h"
#endif

#include <array>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <memory>
#include <sstream>
#include <utility>

#ifdef _WIN32
#  include <fcntl.h> // for _O_BINARY
#  include <io.h>    // for _setmode
#  include <stdio.h> // for std{out,err} and fileno
#endif

#include <cm/string_view>

#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
#include "cmsys/Terminal.h"

int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
                              std::vector<std::string>::const_iterator argEnd);
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
                             std::vector<std::string>::const_iterator argEnd);

void CMakeCommandUsage(const char* program)
{
  std::ostringstream errorStream;

#ifndef CMAKE_BOOTSTRAP
  /* clang-format off */
  errorStream
    << "cmake version " << cmVersion::GetCMakeVersion() << "\n";
/* clang-format on */
#else
  /* clang-format off */
  errorStream
    << "cmake bootstrap\n";
/* clang-format on */
#endif
  // If you add new commands, change here,
  // and in cmakemain.cxx in the options table
  /* clang-format off */
  errorStream
    << "Usage: " << program << " -E <command> [arguments...]\n"
    << "Available commands: \n"
    << "  capabilities              - Report capabilities built into cmake "
       "in JSON format\n"
    << "  cat <files>...            - concat the files and print them to the standard output\n"
    << "  chdir dir cmd [args...]   - run command in a given directory\n"
    << "  compare_files [--ignore-eol] file1 file2\n"
    << "                              - check if file1 is same as file2\n"
    << "  copy <file>... destination  - copy files to destination "
       "(either file or directory)\n"
    << "  copy_directory <dir>... destination   - copy content of <dir>... "
       "directories to 'destination' directory\n"
    << "  copy_if_different <file>... destination  - copy files if it has "
       "changed\n"
    << "  echo [<string>...]        - displays arguments as text\n"
    << "  echo_append [<string>...] - displays arguments as text but no new "
       "line\n"
    << "  env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...\n"
    << "                            - run command in a modified environment\n"
    << "  environment               - display the current environment\n"
    << "  make_directory <dir>...   - create parent and <dir> directories\n"
    << "  md5sum <file>...          - create MD5 checksum of files\n"
    << "  sha1sum <file>...         - create SHA1 checksum of files\n"
    << "  sha224sum <file>...       - create SHA224 checksum of files\n"
    << "  sha256sum <file>...       - create SHA256 checksum of files\n"
    << "  sha384sum <file>...       - create SHA384 checksum of files\n"
    << "  sha512sum <file>...       - create SHA512 checksum of files\n"
    << "  remove [-f] <file>...     - remove the file(s), use -f to force "
       "it (deprecated: use rm instead)\n"
    << "  remove_directory <dir>... - remove directories and their contents (deprecated: use rm instead)\n"
    << "  rename oldname newname    - rename a file or directory "
       "(on one volume)\n"
    << "  rm [-rRf] <file/dir>...    - remove files or directories, use -f to "
       "force it, r or R to remove directories and their contents recursively\n"
    << "  sleep <number>...         - sleep for given number of seconds\n"
    << "  tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n"
    << "                            - create or extract a tar or zip archive\n"
    << "  time command [args...]    - run command and display elapsed time\n"
    << "  touch <file>...           - touch a <file>.\n"
    << "  touch_nocreate <file>...  - touch a <file> but do not create it.\n"
    << "  create_symlink old new    - create a symbolic link new -> old\n"
    << "  create_hardlink old new   - create a hard link new -> old\n"
    << "  true                      - do nothing with an exit code of 0\n"
    << "  false                     - do nothing with an exit code of 1\n"
#if defined(_WIN32) && !defined(__CYGWIN__)
    << "Available on Windows only:\n"
    << "  delete_regv key           - delete registry value\n"
    << "  env_vs8_wince sdkname     - displays a batch file which sets the "
       "environment for the provided Windows CE SDK installed in VS2005\n"
    << "  env_vs9_wince sdkname     - displays a batch file which sets the "
       "environment for the provided Windows CE SDK installed in VS2008\n"
    << "  write_regv key value      - write registry value\n"
#endif
    ;
  /* clang-format on */

  cmSystemTools::Error(errorStream.str());
}

static bool cmTarFilesFrom(std::string const& file,
                           std::vector<std::string>& files)
{
  if (cmSystemTools::FileIsDirectory(file)) {
    std::ostringstream e;
    e << "-E tar --files-from= file '" << file << "' is a directory";
    cmSystemTools::Error(e.str());
    return false;
  }
  cmsys::ifstream fin(file.c_str());
  if (!fin) {
    std::ostringstream e;
    e << "-E tar --files-from= file '" << file << "' not found";
    cmSystemTools::Error(e.str());
    return false;
  }
  std::string line;
  while (cmSystemTools::GetLineFromStream(fin, line)) {
    if (line.empty()) {
      continue;
    }
    if (cmHasLiteralPrefix(line, "--add-file=")) {
      files.push_back(line.substr(11));
    } else if (cmHasLiteralPrefix(line, "-")) {
      std::ostringstream e;
      e << "-E tar --files-from='" << file << "' file invalid line:\n"
        << line << "\n";
      cmSystemTools::Error(e.str());
      return false;
    } else {
      files.push_back(line);
    }
  }
  return true;
}

static void cmCatFile(const std::string& fileToAppend)
{
#ifdef _WIN32
  _setmode(fileno(stdout), _O_BINARY);
#endif
  cmsys::ifstream source(fileToAppend.c_str(),
                         (std::ios::binary | std::ios::in));
  std::cout << source.rdbuf();
}

static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
{
  if (cmSystemTools::FileIsSymlink(dir)) {
    if (!cmSystemTools::RemoveFile(dir)) {
      std::cerr << "Error removing directory symlink \"" << dir << "\".\n";
      return false;
    }
  } else if (!recursive) {
    std::cerr << "Error removing directory \"" << dir
              << "\" without recursive option.\n";
    return false;
  } else if (!cmSystemTools::RemoveADirectory(dir)) {
    std::cerr << "Error removing directory \"" << dir << "\".\n";
    return false;
  }
  return true;
}

static int HandleIWYU(const std::string& runCmd,
                      const std::string& /* sourceFile */,
                      const std::vector<std::string>& orig_cmd)
{
  // Construct the iwyu command line by taking what was given
  // and adding all the arguments we give to the compiler.
  std::vector<std::string> iwyu_cmd = cmExpandedList(runCmd, true);
  cm::append(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end());
  // Run the iwyu command line.  Capture its stderr and hide its stdout.
  // Ignore its return code because the tool always returns non-zero.
  std::string stdErr;
  int ret;
  if (!cmSystemTools::RunSingleCommand(iwyu_cmd, nullptr, &stdErr, &ret,
                                       nullptr, cmSystemTools::OUTPUT_NONE)) {
    std::cerr << "Error running '" << iwyu_cmd[0] << "': " << stdErr << "\n";
    return 1;
  }
  // Warn if iwyu reported anything.
  if (stdErr.find("should remove these lines:") != std::string::npos ||
      stdErr.find("should add these lines:") != std::string::npos) {
    std::cerr << "Warning: include-what-you-use reported diagnostics:\n"
              << stdErr << "\n";
  }
  // always return 0 we don't want to break the compile
  return 0;
}

static int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
                      const std::vector<std::string>& orig_cmd)
{
  // Construct the clang-tidy command line by taking what was given
  // and adding our compiler command line.  The clang-tidy tool will
  // automatically skip over the compiler itself and extract the
  // options.
  int ret;
  std::vector<std::string> tidy_cmd = cmExpandedList(runCmd, true);
  tidy_cmd.push_back(sourceFile);
  tidy_cmd.emplace_back("--");
  cm::append(tidy_cmd, orig_cmd);

  // Run the tidy command line.  Capture its stdout and hide its stderr.
  std::string stdOut;
  std::string stdErr;
  if (!cmSystemTools::RunSingleCommand(tidy_cmd, &stdOut, &stdErr, &ret,
                                       nullptr, cmSystemTools::OUTPUT_NONE)) {
    std::cerr << "Error running '" << tidy_cmd[0] << "': " << stdErr << "\n";
    return 1;
  }
  // Output the stdout from clang-tidy to stderr
  std::cerr << stdOut;
  // If clang-tidy exited with an error do the same.
  if (ret != 0) {
    std::cerr << stdErr;
  }
  return ret;
}

static int HandleLWYU(const std::string& runCmd,
                      const std::string& /* sourceFile */,
                      const std::vector<std::string>&)
{
  // Construct the ldd -r -u (link what you use lwyu) command line
  // ldd -u -r lwuy target
  std::vector<std::string> lwyu_cmd;
  lwyu_cmd.emplace_back("ldd");
  lwyu_cmd.emplace_back("-u");
  lwyu_cmd.emplace_back("-r");
  lwyu_cmd.push_back(runCmd);

  // Run the ldd -u -r command line.
  // Capture its stdout and hide its stderr.
  // Ignore its return code because the tool always returns non-zero
  // if there are any warnings, but we just want to warn.
  std::string stdOut;
  std::string stdErr;
  int ret;
  if (!cmSystemTools::RunSingleCommand(lwyu_cmd, &stdOut, &stdErr, &ret,
                                       nullptr, cmSystemTools::OUTPUT_NONE)) {
    std::cerr << "Error running '" << lwyu_cmd[0] << "': " << stdErr << "\n";
    return 1;
  }

  // Output the stdout from ldd -r -u to stderr
  // Warn if lwyu reported anything.
  if (stdOut.find("Unused direct dependencies:") != std::string::npos) {
    std::cerr << "Warning: " << stdOut;
  }
  return 0;
}

static int HandleCppLint(const std::string& runCmd,
                         const std::string& sourceFile,
                         const std::vector<std::string>&)
{
  // Construct the cpplint command line.
  std::vector<std::string> cpplint_cmd = cmExpandedList(runCmd, true);
  cpplint_cmd.push_back(sourceFile);

  // Run the cpplint command line.  Capture its output.
  std::string stdOut;
  int ret;
  if (!cmSystemTools::RunSingleCommand(cpplint_cmd, &stdOut, &stdOut, &ret,
                                       nullptr, cmSystemTools::OUTPUT_NONE)) {
    std::cerr << "Error running '" << cpplint_cmd[0] << "': " << stdOut
              << "\n";
    return 1;
  }
  if (!stdOut.empty()) {
    std::cerr << "Warning: cpplint diagnostics:\n";
    // Output the output from cpplint to stderr
    std::cerr << stdOut;
  }

  // always return 0 so the build can continue as cpplint returns non-zero
  // for any warning
  return 0;
}

static int HandleCppCheck(const std::string& runCmd,
                          const std::string& sourceFile,
                          const std::vector<std::string>& orig_cmd)
{
  // Construct the cpplint command line.
  std::vector<std::string> cppcheck_cmd = cmExpandedList(runCmd, true);
  // extract all the -D, -U, and -I options from the compile line
  for (auto const& opt : orig_cmd) {
    if (opt.size() > 2) {
      if ((opt[0] == '-') &&
          ((opt[1] == 'D') || (opt[1] == 'I') || (opt[1] == 'U'))) {
        cppcheck_cmd.push_back(opt);
// convert cl / options to - options if needed
#if defined(_WIN32)
      } else if ((opt[0] == '/') &&
                 ((opt[1] == 'D') || (opt[1] == 'I') || (opt[1] == 'U'))) {
        std::string optcopy = opt;
        optcopy[0] = '-';
        cppcheck_cmd.push_back(optcopy);
#endif
      }
    }
  }
  // add the source file
  cppcheck_cmd.push_back(sourceFile);

  // Run the cpplint command line.  Capture its output.
  std::string stdOut;
  std::string stdErr;
  int ret;
  if (!cmSystemTools::RunSingleCommand(cppcheck_cmd, &stdOut, &stdErr, &ret,
                                       nullptr, cmSystemTools::OUTPUT_NONE)) {
    std::cerr << "Error running '" << cppcheck_cmd[0] << "': " << stdOut
              << "\n";
    return 1;
  }
  std::cerr << stdOut;
  // Output the output from cpplint to stderr
  if (stdErr.find("(error)") != std::string::npos ||
      stdErr.find("(warning)") != std::string::npos ||
      stdErr.find("(style)") != std::string::npos ||
      stdErr.find("(performance)") != std::string::npos ||
      stdErr.find("(portability)") != std::string::npos ||
      stdErr.find("(information)") != std::string::npos) {
    if (ret == 0) {
      std::cerr << "Warning: cppcheck reported diagnostics:\n";
    } else {
      std::cerr << "Error: cppcheck reported failure:\n";
    }
  }
  std::cerr << stdErr;

  return ret;
}

using CoCompileHandler = int (*)(const std::string&, const std::string&,
                                 const std::vector<std::string>&);

struct CoCompiler
{
  const char* Option;
  CoCompileHandler Handler;
  bool NoOriginalCommand;
};

static const std::array<CoCompiler, 5> CoCompilers = {
  { // Table of options and handlers.
    { "--cppcheck=", HandleCppCheck, false },
    { "--cpplint=", HandleCppLint, false },
    { "--iwyu=", HandleIWYU, false },
    { "--lwyu=", HandleLWYU, true },
    { "--tidy=", HandleTidy, false } }
};

struct CoCompileJob
{
  std::string Command;
  CoCompileHandler Handler;
};

// called when args[0] == "__run_co_compile"
int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args)
{
  std::vector<CoCompileJob> jobs;
  std::string sourceFile;             // store --source=
  std::vector<std::string> launchers; // store --launcher=

  // Default is to run the original command found after -- if the option
  // does not need to do that, it should be specified here, currently only
  // lwyu does that.
  bool runOriginalCmd = true;

  std::vector<std::string> orig_cmd;
  bool doing_options = true;
  for (std::string const& arg : cmMakeRange(args).advance(2)) {
    // if the arg is -- then the rest of the args after
    // go into orig_cmd
    if (arg == "--") {
      doing_options = false;
    } else if (doing_options) {
      bool optionFound = false;
      for (CoCompiler const& cc : CoCompilers) {
        size_t optionLen = strlen(cc.Option);
        if (arg.compare(0, optionLen, cc.Option) == 0) {
          optionFound = true;
          CoCompileJob job;
          job.Command = arg.substr(optionLen);
          job.Handler = cc.Handler;
          jobs.push_back(std::move(job));
          if (cc.NoOriginalCommand) {
            runOriginalCmd = false;
          }
        }
      }
      if (!optionFound) {
        if (cmHasLiteralPrefix(arg, "--source=")) {
          sourceFile = arg.substr(9);
        } else if (cmHasLiteralPrefix(arg, "--launcher=")) {
          cmExpandList(arg.substr(11), launchers, true);
        } else {
          // if it was not a co-compiler or --source/--launcher then error
          std::cerr << "__run_co_compile given unknown argument: " << arg
                    << "\n";
          return 1;
        }
      }
    } else { // if not doing_options then push to orig_cmd
      orig_cmd.push_back(arg);
    }
  }
  if (jobs.empty()) {
    std::cerr << "__run_co_compile missing command to run. "
                 "Looking for one or more of the following:\n";
    for (CoCompiler const& cc : CoCompilers) {
      std::cerr << cc.Option << "\n";
    }
    return 1;
  }

  if (runOriginalCmd && orig_cmd.empty()) {
    std::cerr << "__run_co_compile missing compile command after --\n";
    return 1;
  }

  for (CoCompileJob const& job : jobs) {
    // call the command handler here
    int ret = job.Handler(job.Command, sourceFile, orig_cmd);

    // if the command returns non-zero then return and fail.
    // for commands that do not want to break the build, they should return
    // 0 no matter what.
    if (ret != 0) {
      return ret;
    }
  }

  // if there is no original command to run return now
  if (!runOriginalCmd) {
    return 0;
  }

  // Prepend launcher argument(s), if any
  if (!launchers.empty()) {
    orig_cmd.insert(orig_cmd.begin(), launchers.begin(), launchers.end());
  }

  // Now run the real compiler command and return its result value
  int ret;
  if (!cmSystemTools::RunSingleCommand(orig_cmd, nullptr, nullptr, &ret,
                                       nullptr,
                                       cmSystemTools::OUTPUT_PASSTHROUGH)) {
    std::cerr << "Error running '" << orig_cmd[0] << "'\n";
    return 1;
  }
  // return the return value from the original compiler command
  return ret;
}

int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
                               std::unique_ptr<cmConsoleBuf> consoleBuf)
{
  // IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx
  if (args.size() > 1) {
    // Copy file
    if (args[1] == "copy" && args.size() > 3) {
      // If multiple source files specified,
      // then destination must be directory
      if ((args.size() > 4) &&
          (!cmSystemTools::FileIsDirectory(args.back()))) {
        std::cerr << "Error: Target (for copy command) \"" << args.back()
                  << "\" is not a directory.\n";
        return 1;
      }
      // If error occurs we want to continue copying next files.
      bool return_value = false;
      for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
        if (!cmsys::SystemTools::CopyFileAlways(arg, args.back())) {
          std::cerr << "Error copying file \"" << arg << "\" to \""
                    << args.back() << "\".\n";
          return_value = true;
        }
      }
      return return_value;
    }

    // Copy file if different.
    if (args[1] == "copy_if_different" && args.size() > 3) {
      // If multiple source files specified,
      // then destination must be directory
      if ((args.size() > 4) &&
          (!cmSystemTools::FileIsDirectory(args.back()))) {
        std::cerr << "Error: Target (for copy_if_different command) \""
                  << args.back() << "\" is not a directory.\n";
        return 1;
      }
      // If error occurs we want to continue copying next files.
      bool return_value = false;
      for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
        if (!cmSystemTools::CopyFileIfDifferent(arg, args.back())) {
          std::cerr << "Error copying file (if different) from \"" << arg
                    << "\" to \"" << args.back() << "\".\n";
          return_value = true;
        }
      }
      return return_value;
    }

    // Copy directory content
    if (args[1] == "copy_directory" && args.size() > 3) {
      // If error occurs we want to continue copying next files.
      bool return_value = false;
      for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
        if (!cmSystemTools::CopyADirectory(arg, args.back())) {
          std::cerr << "Error copying directory from \"" << arg << "\" to \""
                    << args.back() << "\".\n";
          return_value = true;
        }
      }
      return return_value;
    }

    // Rename a file or directory
    if (args[1] == "rename" && args.size() == 4) {
      if (!cmSystemTools::RenameFile(args[2], args[3])) {
        std::string e = cmSystemTools::GetLastSystemError();
        std::cerr << "Error renaming from \"" << args[2] << "\" to \""
                  << args[3] << "\": " << e << "\n";
        return 1;
      }
      return 0;
    }

    // Compare files
    if (args[1] == "compare_files" && (args.size() == 4 || args.size() == 5)) {
      bool filesDiffer;
      if (args.size() == 4) {
        filesDiffer = cmSystemTools::FilesDiffer(args[2], args[3]);
      } else if (args[2] == "--ignore-eol") {
        filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]);
      } else {
        ::CMakeCommandUsage(args[0].c_str());
        return 2;
      }

      if (filesDiffer) {
        return 1;
      }
      return 0;
    }

#if !defined(CMAKE_BOOTSTRAP)
    if (args[1] == "__create_def") {
      if (args.size() < 4) {
        std::cerr << "__create_def Usage: -E __create_def outfile.def "
                     "objlistfile [--nm=nm-path]\n";
        return 1;
      }
      cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary);
      if (!fin) {
        std::cerr << "could not open object list file: " << args[3] << "\n";
        return 1;
      }
      std::vector<std::string> files;
      {
        std::string file;
        cmFileTime outTime;
        bool outValid = outTime.Load(args[2]);
        while (cmSystemTools::GetLineFromStream(fin, file)) {
          files.push_back(file);
          if (outValid) {
            cmFileTime inTime;
            outValid = inTime.Load(file) && inTime.Older(outTime);
          }
        }
        if (outValid) {
          // The def file already exists and all input files are older than the
          // existing def file.
          return 0;
        }
      }
      FILE* fout = cmsys::SystemTools::Fopen(args[2], "w+");
      if (!fout) {
        std::cerr << "could not open output .def file: " << args[2] << "\n";
        return 1;
      }
      bindexplib deffile;
      if (args.size() >= 5) {
        std::string const& a = args[4];
        if (cmHasLiteralPrefix(a, "--nm=")) {
          deffile.SetNmPath(a.substr(5));
          std::cerr << a.substr(5) << "\n";
        } else {
          std::cerr << "unknown argument: " << a << "\n";
        }
      }
      for (std::string const& file : files) {
        std::string const& ext = cmSystemTools::GetFilenameLastExtension(file);
        if (cmSystemTools::LowerCase(ext) == ".def") {
          if (!deffile.AddDefinitionFile(file.c_str())) {
            return 1;
          }
        } else {
          if (!deffile.AddObjectFile(file.c_str())) {
            return 1;
          }
        }
      }
      deffile.WriteFile(fout);
      fclose(fout);
      return 0;
    }
#endif
    if (args[1] == "__run_co_compile") {
      return cmcmd::HandleCoCompileCommands(args);
    }

    // Echo string
    if (args[1] == "echo") {
      std::cout << cmJoin(cmMakeRange(args).advance(2), " ") << std::endl;
      return 0;
    }

    // Echo string no new line
    if (args[1] == "echo_append") {
      std::cout << cmJoin(cmMakeRange(args).advance(2), " ");
      return 0;
    }

    if (args[1] == "env") {
      auto ai = args.cbegin() + 2;
      auto ae = args.cend();
      for (; ai != ae; ++ai) {
        std::string const& a = *ai;
        if (cmHasLiteralPrefix(a, "--unset=")) {
          // Unset environment variable.
          cmSystemTools::UnPutEnv(a.substr(8));
        } else if (!a.empty() && a[0] == '-') {
          // Environment variable and command names cannot start in '-',
          // so this must be an unknown option.
          std::cerr << "cmake -E env: unknown option '" << a << '\''
                    << std::endl;
          return 1;
        } else if (a.find('=') != std::string::npos) {
          // Set environment variable.
          cmSystemTools::PutEnv(a);
        } else {
          // This is the beginning of the command.
          break;
        }
      }

      if (ai == ae) {
        std::cerr << "cmake -E env: no command given" << std::endl;
        return 1;
      }

      // Execute command from remaining arguments.
      std::vector<std::string> cmd(ai, ae);
      int retval;
      if (cmSystemTools::RunSingleCommand(cmd, nullptr, nullptr, &retval,
                                          nullptr,
                                          cmSystemTools::OUTPUT_PASSTHROUGH)) {
        return retval;
      }
      return 1;
    }

#if !defined(CMAKE_BOOTSTRAP)
    if (args[1] == "environment") {
      for (auto const& env : cmSystemTools::GetEnvironmentVariables()) {
        std::cout << env << std::endl;
      }
      return 0;
    }
#endif

    if (args[1] == "make_directory" && args.size() > 2) {
      // If an error occurs, we want to continue making directories.
      bool return_value = false;
      for (auto const& arg : cmMakeRange(args).advance(2)) {
        if (!cmSystemTools::MakeDirectory(arg)) {
          std::cerr << "Error creating directory \"" << arg << "\".\n";
          return_value = true;
        }
      }
      return return_value;
    }

    if (args[1] == "remove_directory" && args.size() > 2) {
      // If an error occurs, we want to continue removing directories.
      bool return_value = false;
      for (auto const& arg : cmMakeRange(args).advance(2)) {
        if (cmSystemTools::FileIsDirectory(arg)) {
          if (!cmRemoveDirectory(arg)) {
            return_value = true;
          }
        }
      }
      return return_value;
    }

    // Remove file
    if (args[1] == "remove" && args.size() > 2) {
      bool force = false;
      for (auto const& arg : cmMakeRange(args).advance(2)) {
        if (arg == "\\-f" || arg == "-f") {
          force = true;
        } else {
          // Complain if the file could not be removed, still exists,
          // and the -f option was not given.
          if (!cmSystemTools::RemoveFile(arg) && !force &&
              cmSystemTools::FileExists(arg)) {
            return 1;
          }
        }
      }
      return 0;
    }

    // Remove directories or files with rm
    if (args[1] == "rm" && args.size() > 2) {
      // If an error occurs, we want to continue removing the remaining
      // files/directories.
      int return_value = 0;
      bool force = false;
      bool recursive = false;
      bool doing_options = true;
      bool at_least_one_file = false;
      for (auto const& arg : cmMakeRange(args).advance(2)) {
        if (doing_options && cmHasLiteralPrefix(arg, "-")) {
          if (arg == "--") {
            doing_options = false;
          }
          if (arg.find('f') != std::string::npos) {
            force = true;
          }
          if (arg.find_first_of("rR") != std::string::npos) {
            recursive = true;
          }
          if (arg.find_first_not_of("-frR") != std::string::npos) {
            cmSystemTools::Error("Unknown -E rm argument: " + arg);
            return 1;
          }
        } else {
          if (arg.empty()) {
            continue;
          }
          at_least_one_file = true;
          // Complain if the -f option was not given and
          // either file does not exist or
          // file could not be removed and still exists
          bool file_exists_or_forced_remove = cmSystemTools::FileExists(arg) ||
            cmSystemTools::FileIsSymlink(arg) || force;
          if (cmSystemTools::FileIsDirectory(arg)) {
            if (!cmRemoveDirectory(arg, recursive)) {
              return_value = 1;
            }
          } else if ((!file_exists_or_forced_remove) ||
                     (!cmSystemTools::RemoveFile(arg) &&
                      cmSystemTools::FileExists(arg))) {
            if (!file_exists_or_forced_remove) {
              cmSystemTools::Error(
                "File to remove does not exist and force is not set: " + arg);
            } else {
              cmSystemTools::Error("File can't be removed and still exist: " +
                                   arg);
            }
            return_value = 1;
          }
        }
      }
      if (!at_least_one_file) {
        cmSystemTools::Error("Missing file/directory to remove");
        return 1;
      }
      return return_value;
    }

    // Touch file
    if (args[1] == "touch" && args.size() > 2) {
      for (auto const& arg : cmMakeRange(args).advance(2)) {
        if (!cmSystemTools::Touch(arg, true)) {
          std::cerr << "cmake -E touch: failed to update \"";
          std::cerr << arg << "\".\n";
          return 1;
        }
      }
      return 0;
    }

    // Touch file
    if (args[1] == "touch_nocreate" && args.size() > 2) {
      for (auto const& arg : cmMakeRange(args).advance(2)) {
        if (!cmSystemTools::Touch(arg, false)) {
          std::cerr << "cmake -E touch_nocreate: failed to update \"";
          std::cerr << arg << "\".\n";
          return 1;
        }
      }
      return 0;
    }

    // capabilities
    if (args[1] == "capabilities") {
      if (args.size() > 2) {
        std::cerr << "-E capabilities accepts no additional arguments\n";
        return 1;
      }
      cmake cm(cmake::RoleInternal, cmState::Unknown);
      std::cout << cm.ReportCapabilities();
      return 0;
    }

    // Sleep command
    if (args[1] == "sleep" && args.size() > 2) {
      double total = 0;
      for (auto const& arg : cmMakeRange(args).advance(2)) {
        double num = 0.0;
        char unit;
        char extra;
        int n = sscanf(arg.c_str(), "%lg%c%c", &num, &unit, &extra);
        if ((n == 1 || (n == 2 && unit == 's')) && num >= 0) {
          total += num;
        } else {
          std::cerr << "Unknown sleep time format \"" << arg << "\".\n";
          return 1;
        }
      }
      if (total > 0) {
        cmSystemTools::Delay(static_cast<unsigned int>(total * 1000));
      }
      return 0;
    }

    // Clock command
    if (args[1] == "time" && args.size() > 2) {
      std::vector<std::string> command(args.begin() + 2, args.end());

      clock_t clock_start;
      clock_t clock_finish;
      time_t time_start;
      time_t time_finish;

      time(&time_start);
      clock_start = clock();
      int ret = 0;
      cmSystemTools::RunSingleCommand(command, nullptr, nullptr, &ret);

      clock_finish = clock();
      time(&time_finish);

      double clocks_per_sec = static_cast<double>(CLOCKS_PER_SEC);
      std::cout << "Elapsed time: "
                << static_cast<long>(time_finish - time_start) << " s. (time)"
                << ", "
                << static_cast<double>(clock_finish - clock_start) /
          clocks_per_sec
                << " s. (clock)"
                << "\n";
      return ret;
    }

    // Command to calculate the md5sum of a file
    if (args[1] == "md5sum" && args.size() >= 3) {
      return HashSumFile(args, cmCryptoHash::AlgoMD5);
    }

    // Command to calculate the sha1sum of a file
    if (args[1] == "sha1sum" && args.size() >= 3) {
      return HashSumFile(args, cmCryptoHash::AlgoSHA1);
    }

    if (args[1] == "sha224sum" && args.size() >= 3) {
      return HashSumFile(args, cmCryptoHash::AlgoSHA224);
    }

    if (args[1] == "sha256sum" && args.size() >= 3) {
      return HashSumFile(args, cmCryptoHash::AlgoSHA256);
    }

    if (args[1] == "sha384sum" && args.size() >= 3) {
      return HashSumFile(args, cmCryptoHash::AlgoSHA384);
    }

    if (args[1] == "sha512sum" && args.size() >= 3) {
      return HashSumFile(args, cmCryptoHash::AlgoSHA512);
    }

    // Command to concat files into one
    if (args[1] == "cat" && args.size() >= 3) {
      int return_value = 0;
      for (auto const& arg : cmMakeRange(args).advance(2)) {
        if (cmHasLiteralPrefix(arg, "-")) {
          if (arg != "--") {
            cmSystemTools::Error(arg + ": option not handled");
            return_value = 1;
          }
        } else if (!cmSystemTools::TestFileAccess(arg,
                                                  cmsys::TEST_FILE_READ) &&
                   cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_OK)) {
          cmSystemTools::Error(arg + ": permission denied (ignoring)");
          return_value = 1;
        } else if (cmSystemTools::FileIsDirectory(arg)) {
          cmSystemTools::Error(arg + ": is a directory (ignoring)");
          return_value = 1;
        } else if (!cmSystemTools::FileExists(arg)) {
          cmSystemTools::Error(arg + ": no such file or directory (ignoring)");
          return_value = 1;
        } else {
          // Destroy console buffers to drop cout/cerr encoding transform.
          consoleBuf.reset();
          cmCatFile(arg);
        }
      }
      return return_value;
    }

    // Command to change directory and run a program.
    if (args[1] == "chdir" && args.size() >= 4) {
      std::string const& directory = args[2];
      if (!cmSystemTools::FileExists(directory)) {
        cmSystemTools::Error("Directory does not exist for chdir command: " +
                             args[2]);
        return 1;
      }

      std::string command =
        cmWrap('"', cmMakeRange(args).advance(3), '"', " ");
      int retval = 0;
      if (cmSystemTools::RunSingleCommand(
            command, nullptr, nullptr, &retval, directory.c_str(),
            cmSystemTools::OUTPUT_PASSTHROUGH, cmDuration::zero())) {
        return retval;
      }

      return 1;
    }

    // Command to start progress for a build
    if (args[1] == "cmake_progress_start" && args.size() == 4) {
      // basically remove the directory
      std::string dirName = cmStrCat(args[2], "/Progress");
      cmSystemTools::RemoveADirectory(dirName);

      // is the last argument a filename that exists?
      FILE* countFile = cmsys::SystemTools::Fopen(args[3], "r");
      int count;
      if (countFile) {
        if (1 != fscanf(countFile, "%i", &count)) {
          cmSystemTools::Message("Could not read from count file.");
        }
        fclose(countFile);
      } else {
        count = atoi(args[3].c_str());
      }
      if (count) {
        cmSystemTools::MakeDirectory(dirName);
        // write the count into the directory
        std::string fName = cmStrCat(dirName, "/count.txt");
        FILE* progFile = cmsys::SystemTools::Fopen(fName, "w");
        if (progFile) {
          fprintf(progFile, "%i\n", count);
          fclose(progFile);
        }
      }
      return 0;
    }

    // Command to report progress for a build
    if (args[1] == "cmake_progress_report" && args.size() >= 3) {
      // This has been superseded by cmake_echo_color --progress-*
      // options.  We leave it here to avoid errors if somehow this
      // is invoked by an existing makefile without regenerating.
      return 0;
    }

    // Command to create a symbolic link.  Fails on platforms not
    // supporting them.
    if (args[1] == "create_symlink" && args.size() == 4) {
      std::string const& destinationFileName = args[3];
      if ((cmSystemTools::FileExists(destinationFileName) ||
           cmSystemTools::FileIsSymlink(destinationFileName)) &&
          !cmSystemTools::RemoveFile(destinationFileName)) {
        std::string emsg = cmSystemTools::GetLastSystemError();
        std::cerr << "failed to create symbolic link '" << destinationFileName
                  << "' because existing path cannot be removed: " << emsg
                  << "\n";
        return 1;
      }
      if (!cmSystemTools::CreateSymlink(args[2], args[3])) {
        return 1;
      }
      return 0;
    }

    // Command to create a hard link.  Fails on platforms not
    // supporting them.
    if (args[1] == "create_hardlink" && args.size() == 4) {
      const char* SouceFileName = args[2].c_str();
      const char* destinationFileName = args[3].c_str();

      if (!cmSystemTools::FileExists(SouceFileName)) {
        std::cerr << "failed to create hard link because source path '"
                  << SouceFileName << "' does not exist \n";
        return 1;
      }

      if ((cmSystemTools::FileExists(destinationFileName) ||
           cmSystemTools::FileIsSymlink(destinationFileName)) &&
          !cmSystemTools::RemoveFile(destinationFileName)) {
        std::string emsg = cmSystemTools::GetLastSystemError();
        std::cerr << "failed to create hard link '" << destinationFileName
                  << "' because existing path cannot be removed: " << emsg
                  << "\n";
        return 1;
      }

      if (!cmSystemTools::CreateLink(args[2], args[3])) {
        return 1;
      }
      return 0;
    }

    // Command to do nothing with an exit code of 0.
    if (args[1] == "true") {
      return 0;
    }

    // Command to do nothing with an exit code of 1.
    if (args[1] == "false") {
      return 1;
    }

    // Internal CMake shared library support.
    if (args[1] == "cmake_symlink_library" && args.size() == 5) {
      return cmcmd::SymlinkLibrary(args);
    }

    // Internal CMake versioned executable support.
    if (args[1] == "cmake_symlink_executable" && args.size() == 4) {
      return cmcmd::SymlinkExecutable(args);
    }

    // Internal CMake dependency scanning support.
    if (args[1] == "cmake_depends" && args.size() >= 6) {
      const bool verbose = isCMakeVerbose();

      // Create a cmake object instance to process dependencies.
      // All we need is the `set` command.
      cmake cm(cmake::RoleScript, cmState::Unknown);
      std::string gen;
      std::string homeDir;
      std::string startDir;
      std::string homeOutDir;
      std::string startOutDir;
      std::string depInfo;
      bool color = false;
      if (args.size() >= 8) {
        // Full signature:
        //
        //   -E cmake_depends <generator>
        //                    <home-src-dir> <start-src-dir>
        //                    <home-out-dir> <start-out-dir>
        //                    <dep-info> [--color=$(COLOR)]
        //
        // All paths are provided.
        gen = args[2];
        homeDir = args[3];
        startDir = args[4];
        homeOutDir = args[5];
        startOutDir = args[6];
        depInfo = args[7];
        if (args.size() >= 9 && cmHasLiteralPrefix(args[8], "--color=")) {
          // Enable or disable color based on the switch value.
          color = (args[8].size() == 8 || cmIsOn(args[8].substr(8)));
        }
      } else {
        // Support older signature for existing makefiles:
        //
        //   -E cmake_depends <generator>
        //                    <home-out-dir> <start-out-dir>
        //                    <dep-info>
        //
        // Just pretend the source directories are the same as the
        // binary directories so at least scanning will work.
        gen = args[2];
        homeDir = args[3];
        startDir = args[4];
        homeOutDir = args[3];
        startOutDir = args[3];
        depInfo = args[5];
      }

      // Create a local generator configured for the directory in
      // which dependencies will be scanned.
      homeDir = cmSystemTools::CollapseFullPath(homeDir);
      startDir = cmSystemTools::CollapseFullPath(startDir);
      homeOutDir = cmSystemTools::CollapseFullPath(homeOutDir);
      startOutDir = cmSystemTools::CollapseFullPath(startOutDir);
      cm.SetHomeDirectory(homeDir);
      cm.SetHomeOutputDirectory(homeOutDir);
      cm.GetCurrentSnapshot().SetDefaultDefinitions();
      if (auto ggd = cm.CreateGlobalGenerator(gen)) {
        cm.SetGlobalGenerator(std::move(ggd));
        cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
        snapshot.GetDirectory().SetCurrentBinary(startOutDir);
        snapshot.GetDirectory().SetCurrentSource(startDir);
        cmMakefile mf(cm.GetGlobalGenerator(), snapshot);
        auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf);

        // Actually scan dependencies.
        return lgd->UpdateDependencies(depInfo, verbose, color) ? 0 : 2;
      }
      return 1;
    }

    // Internal CMake link script support.
    if (args[1] == "cmake_link_script" && args.size() >= 3) {
      return cmcmd::ExecuteLinkScript(args);
    }

#if !defined(CMAKE_BOOTSTRAP)
    // Internal CMake ninja dependency scanning support.
    if (args[1] == "cmake_ninja_depends") {
      return cmcmd_cmake_ninja_depends(args.begin() + 2, args.end());
    }

    // Internal CMake ninja dyndep support.
    if (args[1] == "cmake_ninja_dyndep") {
      return cmcmd_cmake_ninja_dyndep(args.begin() + 2, args.end());
    }
#endif

    // Internal CMake unimplemented feature notification.
    if (args[1] == "cmake_unimplemented_variable") {
      std::cerr << "Feature not implemented for this platform.";
      if (args.size() == 3) {
        std::cerr << "  Variable " << args[2] << " is not set.";
      }
      std::cerr << std::endl;
      return 1;
    }

    if (args[1] == "vs_link_exe") {
      return cmcmd::VisualStudioLink(args, 1);
    }

    if (args[1] == "vs_link_dll") {
      return cmcmd::VisualStudioLink(args, 2);
    }

    if (args[1] == "cmake_llvm_rc") {
      return cmcmd::RunLLVMRC(args);
    }

    // Internal CMake color makefile support.
    if (args[1] == "cmake_echo_color") {
      return cmcmd::ExecuteEchoColor(args);
    }

#ifndef CMAKE_BOOTSTRAP
    if ((args[1] == "cmake_autogen") && (args.size() >= 4)) {
      cm::string_view const infoFile = args[2];
      cm::string_view const config = args[3];
      return cmQtAutoMocUic(infoFile, config) ? 0 : 1;
    }
    if ((args[1] == "cmake_autorcc") && (args.size() >= 3)) {
      cm::string_view const infoFile = args[2];
      cm::string_view const config =
        (args.size() > 3) ? cm::string_view(args[3]) : cm::string_view();
      return cmQtAutoRcc(infoFile, config) ? 0 : 1;
    }
#endif

    // Tar files
    if (args[1] == "tar" && args.size() > 3) {
      const char* knownFormats[] = { "7zip", "gnutar", "pax", "paxr", "zip" };

      std::string const& flags = args[2];
      std::string const& outFile = args[3];
      std::vector<std::string> files;
      std::string mtime;
      std::string format;
      cmSystemTools::cmTarCompression compress =
        cmSystemTools::TarCompressNone;
      int nCompress = 0;
      bool doing_options = true;
      for (auto const& arg : cmMakeRange(args).advance(4)) {
        if (doing_options && cmHasLiteralPrefix(arg, "--")) {
          if (arg == "--") {
            doing_options = false;
          } else if (arg == "--zstd") {
            compress = cmSystemTools::TarCompressZstd;
            ++nCompress;
          } else if (cmHasLiteralPrefix(arg, "--mtime=")) {
            mtime = arg.substr(8);
          } else if (cmHasLiteralPrefix(arg, "--files-from=")) {
            std::string const& files_from = arg.substr(13);
            if (!cmTarFilesFrom(files_from, files)) {
              return 1;
            }
          } else if (cmHasLiteralPrefix(arg, "--format=")) {
            format = arg.substr(9);
            if (!cm::contains(knownFormats, format)) {
              cmSystemTools::Error("Unknown -E tar --format= argument: " +
                                   format);
              return 1;
            }
          } else {
            cmSystemTools::Error("Unknown option to -E tar: " + arg);
            return 1;
          }
        } else {
          files.push_back(arg);
        }
      }
      cmSystemTools::cmTarAction action = cmSystemTools::TarActionNone;
      bool verbose = false;

      for (auto flag : flags) {
        switch (flag) {
          case '-':
          case 'f': {
            // Keep for backward compatibility. Ignored
          } break;
          case 'j': {
            compress = cmSystemTools::TarCompressBZip2;
            ++nCompress;
          } break;
          case 'J': {
            compress = cmSystemTools::TarCompressXZ;
            ++nCompress;
          } break;
          case 'z': {
            compress = cmSystemTools::TarCompressGZip;
            ++nCompress;
          } break;
          case 'v': {
            verbose = true;
          } break;
          case 't': {
            action = cmSystemTools::TarActionList;
          } break;
          case 'c': {
            action = cmSystemTools::TarActionCreate;
          } break;
          case 'x': {
            action = cmSystemTools::TarActionExtract;
          } break;
          default: {
            cmSystemTools::Message(
              std::string("tar: Unknown argument: ") + flag, "Warning");
          }
        }
      }
      if ((format == "7zip" || format == "zip") && nCompress > 0) {
        cmSystemTools::Error("Can not use compression flags with format: " +
                             format);
        return 1;
      }
      if (nCompress > 1) {
        cmSystemTools::Error("Can only compress a tar file one way; "
                             "at most one flag of z, j, or J may be used");
        return 1;
      }
      if (action == cmSystemTools::TarActionList) {
        if (!cmSystemTools::ListTar(outFile, files, verbose)) {
          cmSystemTools::Error("Problem listing tar: " + outFile);
          return 1;
        }
      } else if (action == cmSystemTools::TarActionCreate) {
        if (files.empty()) {
          cmSystemTools::Message("tar: No files or directories specified",
                                 "Warning");
        }
        if (!cmSystemTools::CreateTar(outFile, files, compress, verbose, mtime,
                                      format)) {
          cmSystemTools::Error("Problem creating tar: " + outFile);
          return 1;
        }
      } else if (action == cmSystemTools::TarActionExtract) {
        if (!cmSystemTools::ExtractTar(outFile, files, verbose)) {
          cmSystemTools::Error("Problem extracting tar: " + outFile);
          return 1;
        }
#ifdef WIN32
        // OK, on windows 7 after we untar some files,
        // sometimes we can not rename the directory after
        // the untar is done. This breaks the external project
        // untar and rename code.  So, by default we will wait
        // 1/10th of a second after the untar.  If CMAKE_UNTAR_DELAY
        // is set in the env, its value will be used instead of 100.
        int delay = 100;
        std::string delayVar;
        if (cmSystemTools::GetEnv("CMAKE_UNTAR_DELAY", delayVar)) {
          delay = atoi(delayVar.c_str());
        }
        if (delay) {
          cmSystemTools::Delay(delay);
        }
#endif
      } else {
        cmSystemTools::Error("tar: No action specified. Please choose: 't' "
                             "(list), 'c' (create) or 'x' (extract)");
        return 1;
      }
      return 0;
    }

    if (args[1] == "server") {
      cmSystemTools::Error(
        "CMake server mode has been removed in favor of the file-api.");
      return 1;
    }

#if !defined(CMAKE_BOOTSTRAP)
    // Internal CMake Fortran module support.
    if (args[1] == "cmake_copy_f90_mod" && args.size() >= 4) {
      return cmDependsFortran::CopyModule(args) ? 0 : 1;
    }
#endif

#if defined(_WIN32) && !defined(__CYGWIN__)
    // Write registry value
    if (args[1] == "write_regv" && args.size() > 3) {
      return cmSystemTools::WriteRegistryValue(args[2], args[3]) ? 0 : 1;
    }

    // Delete registry value
    if (args[1] == "delete_regv" && args.size() > 2) {
      return cmSystemTools::DeleteRegistryValue(args[2]) ? 0 : 1;
    }

    // Remove file
    if (args[1] == "comspec" && args.size() > 2) {
      std::cerr << "Win9x helper \"cmake -E comspec\" no longer supported\n";
      return 1;
    }

    if (args[1] == "env_vs8_wince" && args.size() == 3) {
      return cmcmd::WindowsCEEnvironment("8.0", args[2]);
    }

    if (args[1] == "env_vs9_wince" && args.size() == 3) {
      return cmcmd::WindowsCEEnvironment("9.0", args[2]);
    }
#endif

    // Internal depfile transformation
    if (args[1] == "cmake_transform_depfile" && args.size() == 6) {
      auto format = cmDepfileFormat::GccDepfile;
      if (args[2] == "gccdepfile") {
        format = cmDepfileFormat::GccDepfile;
      } else if (args[2] == "vstlog") {
        format = cmDepfileFormat::VsTlog;
      } else {
        return 1;
      }
      std::string prefix = args[3];
      if (prefix == "./") {
        prefix.clear();
      }
      return cmTransformDepfile(format, prefix, args[4], args[5]) ? 0 : 1;
    }
  }

  ::CMakeCommandUsage(args[0].c_str());
  return 1;
}

int cmcmd::HashSumFile(std::vector<std::string> const& args,
                       cmCryptoHash::Algo algo)
{
  if (args.size() < 3) {
    return -1;
  }
  int retval = 0;

  for (auto const& filename : cmMakeRange(args).advance(2)) {
    // Cannot compute sum of a directory
    if (cmSystemTools::FileIsDirectory(filename)) {
      std::cerr << "Error: " << filename << " is a directory" << std::endl;
      retval++;
    } else {
      std::string value = cmSystemTools::ComputeFileHash(filename, algo);
      if (value.empty()) {
        // To mimic "md5sum/shasum" behavior in a shell:
        std::cerr << filename << ": No such file or directory" << std::endl;
        retval++;
      } else {
        std::cout << value << "  " << filename << std::endl;
      }
    }
  }
  return retval;
}

int cmcmd::SymlinkLibrary(std::vector<std::string> const& args)
{
  int result = 0;
  std::string realName = args[2];
  std::string soName = args[3];
  std::string name = args[4];
  cmSystemTools::ConvertToUnixSlashes(realName);
  cmSystemTools::ConvertToUnixSlashes(soName);
  cmSystemTools::ConvertToUnixSlashes(name);
  if (soName != realName) {
    if (!cmcmd::SymlinkInternal(realName, soName)) {
      cmSystemTools::ReportLastSystemError("cmake_symlink_library");
      result = 1;
    }
  }
  if (name != soName) {
    if (!cmcmd::SymlinkInternal(soName, name)) {
      cmSystemTools::ReportLastSystemError("cmake_symlink_library");
      result = 1;
    }
  }
  return result;
}

int cmcmd::SymlinkExecutable(std::vector<std::string> const& args)
{
  int result = 0;
  std::string const& realName = args[2];
  std::string const& name = args[3];
  if (name != realName) {
    if (!cmcmd::SymlinkInternal(realName, name)) {
      cmSystemTools::ReportLastSystemError("cmake_symlink_executable");
      result = 1;
    }
  }
  return result;
}

bool cmcmd::SymlinkInternal(std::string const& file, std::string const& link)
{
  if (cmSystemTools::FileExists(link) || cmSystemTools::FileIsSymlink(link)) {
    cmSystemTools::RemoveFile(link);
  }
#if defined(_WIN32) && !defined(__CYGWIN__)
  return cmSystemTools::CopyFileAlways(file, link);
#else
  std::string linktext = cmSystemTools::GetFilenameName(file);
  return cmSystemTools::CreateSymlink(linktext, link);
#endif
}

static void cmcmdProgressReport(std::string const& dir, std::string const& num)
{
  std::string dirName = cmStrCat(dir, "/Progress");
  std::string fName;
  FILE* progFile;

  // read the count
  fName = cmStrCat(dirName, "/count.txt");
  progFile = cmsys::SystemTools::Fopen(fName, "r");
  int count = 0;
  if (!progFile) {
    return;
  }
  if (1 != fscanf(progFile, "%i", &count)) {
    cmSystemTools::Message("Could not read from progress file.");
  }
  fclose(progFile);

  const char* last = num.c_str();
  for (const char* c = last;; ++c) {
    if (*c == ',' || *c == '\0') {
      if (c != last) {
        fName = cmStrCat(dirName, '/');
        fName.append(last, c - last);
        progFile = cmsys::SystemTools::Fopen(fName, "w");
        if (progFile) {
          fprintf(progFile, "empty");
          fclose(progFile);
        }
      }
      if (*c == '\0') {
        break;
      }
      last = c + 1;
    }
  }
  int fileNum =
    static_cast<int>(cmsys::Directory::GetNumberOfFilesInDirectory(dirName));
  if (count > 0) {
    // print the progress
    fprintf(stdout, "[%3i%%] ", ((fileNum - 3) * 100) / count);
  }
}

int cmcmd::ExecuteEchoColor(std::vector<std::string> const& args)
{
  // The arguments are
  //   args[0] == <cmake-executable>
  //   args[1] == cmake_echo_color

  bool enabled = true;
  int color = cmsysTerminal_Color_Normal;
  bool newline = true;
  std::string progressDir;
  for (auto const& arg : cmMakeRange(args).advance(2)) {
    if (cmHasLiteralPrefix(arg, "--switch=")) {
      // Enable or disable color based on the switch value.
      std::string value = arg.substr(9);
      if (!value.empty()) {
        enabled = cmIsOn(value);
      }
    } else if (cmHasLiteralPrefix(arg, "--progress-dir=")) {
      progressDir = arg.substr(15);
    } else if (cmHasLiteralPrefix(arg, "--progress-num=")) {
      if (!progressDir.empty()) {
        std::string const& progressNum = arg.substr(15);
        cmcmdProgressReport(progressDir, progressNum);
      }
    } else if (arg == "--normal") {
      color = cmsysTerminal_Color_Normal;
    } else if (arg == "--black") {
      color = cmsysTerminal_Color_ForegroundBlack;
    } else if (arg == "--red") {
      color = cmsysTerminal_Color_ForegroundRed;
    } else if (arg == "--green") {
      color = cmsysTerminal_Color_ForegroundGreen;
    } else if (arg == "--yellow") {
      color = cmsysTerminal_Color_ForegroundYellow;
    } else if (arg == "--blue") {
      color = cmsysTerminal_Color_ForegroundBlue;
    } else if (arg == "--magenta") {
      color = cmsysTerminal_Color_ForegroundMagenta;
    } else if (arg == "--cyan") {
      color = cmsysTerminal_Color_ForegroundCyan;
    } else if (arg == "--white") {
      color = cmsysTerminal_Color_ForegroundWhite;
    } else if (arg == "--bold") {
      color |= cmsysTerminal_Color_ForegroundBold;
    } else if (arg == "--no-newline") {
      newline = false;
    } else if (arg == "--newline") {
      newline = true;
    } else {
      // Color is enabled.  Print with the current color.
      cmSystemTools::MakefileColorEcho(color, arg.c_str(), newline, enabled);
    }
  }

  return 0;
}

int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args)
{
  // The arguments are
  //   args[0] == <cmake-executable>
  //   args[1] == cmake_link_script
  //   args[2] == <link-script-name>
  //   args[3] == --verbose=?
  bool verbose = false;
  if (args.size() >= 4) {
    if (cmHasLiteralPrefix(args[3], "--verbose=")) {
      if (!cmIsOff(args[3].substr(10))) {
        verbose = true;
      }
    }
  }

  // Allocate a process instance.
  cmsysProcess* cp = cmsysProcess_New();
  if (!cp) {
    std::cerr << "Error allocating process instance in link script."
              << std::endl;
    return 1;
  }

  // Children should share stdout and stderr with this process.
  cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1);
  cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);

  // Run the command lines verbatim.
  cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1);

  // Read command lines from the script.
  cmsys::ifstream fin(args[2].c_str());
  if (!fin) {
    std::cerr << "Error opening link script \"" << args[2] << "\""
              << std::endl;
    return 1;
  }

  // Run one command at a time.
  std::string command;
  int result = 0;
  while (result == 0 && cmSystemTools::GetLineFromStream(fin, command)) {
    // Skip empty command lines.
    if (command.find_first_not_of(" \t") == std::string::npos) {
      continue;
    }

    // Setup this command line.
    const char* cmd[2] = { command.c_str(), nullptr };
    cmsysProcess_SetCommand(cp, cmd);

    // Report the command if verbose output is enabled.
    if (verbose) {
      std::cout << command << std::endl;
    }

    // Run the command and wait for it to exit.
    cmsysProcess_Execute(cp);
    cmsysProcess_WaitForExit(cp, nullptr);

    // Report failure if any.
    switch (cmsysProcess_GetState(cp)) {
      case cmsysProcess_State_Exited: {
        int value = cmsysProcess_GetExitValue(cp);
        if (value != 0) {
          result = value;
        }
      } break;
      case cmsysProcess_State_Exception:
        std::cerr << "Error running link command: "
                  << cmsysProcess_GetExceptionString(cp) << std::endl;
        result = 1;
        break;
      case cmsysProcess_State_Error:
        std::cerr << "Error running link command: "
                  << cmsysProcess_GetErrorString(cp) << std::endl;
        result = 2;
        break;
      default:
        break;
    }
  }

  // Free the process instance.
  cmsysProcess_Delete(cp);

  // Return the final resulting return value.
  return result;
}

int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
{
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
  cmVisualStudioWCEPlatformParser parser(name.c_str());
  parser.ParseVersion(version);
  if (parser.Found()) {
    /* clang-format off */
    std::cout << "@echo off\n"
                 "echo Environment Selection: " << name << "\n"
                 "set PATH=" << parser.GetPathDirectories() << "\n"
                 "set INCLUDE=" << parser.GetIncludeDirectories() << "\n"
                 "set LIB=" << parser.GetLibraryDirectories() << std::endl;
    /* clang-format on */
    return 0;
  }
#else
  (void)version;
#endif

  std::cerr << "Could not find " << name;
  return -1;
}

int cmcmd::RunPreprocessor(const std::vector<std::string>& command,
                           const std::string& intermediate_file)
{
  cmUVProcessChainBuilder builder;

  uv_fs_t fs_req;
  int preprocessedFile =
    uv_fs_open(nullptr, &fs_req, intermediate_file.c_str(), O_CREAT | O_RDWR,
               0644, nullptr);
  uv_fs_req_cleanup(&fs_req);

  builder
    .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
                       preprocessedFile)
    .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR)
    .AddCommand(command);
  auto process = builder.Start();
  if (!process.Valid()) {
    std::cerr << "Failed to start preprocessor.";
    return 1;
  }
  if (!process.Wait()) {
    std::cerr << "Failed to wait for preprocessor";
    return 1;
  }
  auto status = process.GetStatus();
  if (!status[0] || status[0]->ExitStatus != 0) {
    auto errorStream = process.ErrorStream();
    if (errorStream) {
      std::cerr << errorStream->rdbuf();
    }

    return 1;
  }
  return 0;
}

int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
{
  // The arguments are
  //   args[0] == <cmake-executable>
  //   args[1] == cmake_llvm_rc
  //   args[2] == source_file_path
  //   args[3] == intermediate_file
  //   args[4..n] == preprocess+args
  //   args[n+1] == ++
  //   args[n+2...] == llvm-rc+args
  if (args.size() < 3) {
    std::cerr << "Invalid cmake_llvm_rc arguments";
    return 1;
  }

  const std::string& intermediate_file = args[3];
  const std::string& source_file = args[2];
  std::vector<std::string> preprocess;
  std::vector<std::string> resource_compile;
  std::vector<std::string>* pArgTgt = &preprocess;

  static const cmsys::RegularExpression llvm_rc_only_single_arg("^[-/](N|Y)");
  static const cmsys::RegularExpression llvm_rc_only_double_arg(
    "^[-/](C|LN|L)(.)?");
  static const cmsys::RegularExpression common_double_arg(
    "^[-/](D|U|I|FO|fo|Fo)(.)?");
  bool acceptNextArg = false;
  bool skipNextArg = false;
  for (std::string const& arg : cmMakeRange(args).advance(4)) {
    if (skipNextArg) {
      skipNextArg = false;
      continue;
    }
    // We use ++ as seperator between the preprocessing step definition and the
    // rc compilation step becase we need to prepend a -- to seperate the
    // source file properly from other options when using clang-cl for
    // preprocessing.
    if (arg == "++") {
      pArgTgt = &resource_compile;
      skipNextArg = false;
      acceptNextArg = true;
    } else {
      cmsys::RegularExpressionMatch match;
      if (!acceptNextArg) {
        if (common_double_arg.find(arg.c_str(), match)) {
          acceptNextArg = match.match(2).empty();
        } else {
          if (llvm_rc_only_single_arg.find(arg.c_str(), match)) {
            if (pArgTgt == &preprocess) {
              continue;
            }
          } else if (llvm_rc_only_double_arg.find(arg.c_str(), match)) {
            if (pArgTgt == &preprocess) {
              skipNextArg = match.match(2).empty();
              continue;
            }
            acceptNextArg = match.match(2).empty();
          } else if (pArgTgt == &resource_compile) {
            continue;
          }
        }
      } else {
        acceptNextArg = false;
      }
      if (arg.find("SOURCE_DIR") != std::string::npos) {
        std::string sourceDirArg = arg;
        cmSystemTools::ReplaceString(
          sourceDirArg, "SOURCE_DIR",
          cmSystemTools::GetFilenamePath(source_file));
        pArgTgt->push_back(sourceDirArg);
      } else {
        pArgTgt->push_back(arg);
      }
    }
  }
  if (preprocess.empty()) {
    std::cerr << "Empty preprocessing command";
    return 1;
  }
  if (resource_compile.empty()) {
    std::cerr << "Empty resource compilation command";
    return 1;
  }
  // Since we might have skipped the last argument to llvm-rc
  // we need to make sure the llvm-rc source file is present in the commandline
  if (resource_compile.back() != intermediate_file) {
    resource_compile.push_back(intermediate_file);
  }

  auto result = RunPreprocessor(preprocess, intermediate_file);
  if (result != 0) {
    cmSystemTools::RemoveFile(intermediate_file);
    return result;
  }
  cmUVProcessChainBuilder builder;

  builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
    .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR)
    .AddCommand(resource_compile);
  auto process = builder.Start();
  result = 0;
  if (!process.Valid()) {
    std::cerr << "Failed to start resource compiler.";
    result = 1;
  } else {
    if (!process.Wait()) {
      std::cerr << "Failed to wait for resource compiler";
      result = 1;
    }
  }

  cmSystemTools::RemoveFile(intermediate_file);
  if (result != 0) {
    return result;
  }
  auto status = process.GetStatus();
  if (!status[0] || status[0]->ExitStatus != 0) {
    auto errorStream = process.ErrorStream();
    if (errorStream) {
      std::cerr << errorStream->rdbuf();
    }
    return 1;
  }

  return 0;
}

class cmVSLink
{
  int Type;
  bool Verbose;
  bool Incremental;
  bool LinkGeneratesManifest;
  std::vector<std::string> LinkCommand;
  std::vector<std::string> UserManifests;
  std::string LinkerManifestFile;
  std::string ManifestFile;
  std::string ManifestFileRC;
  std::string ManifestFileRes;
  std::string TargetFile;
  std::string MtPath;
  std::string RcPath;

public:
  cmVSLink(int type, bool verbose)
    : Type(type)
    , Verbose(verbose)
    , Incremental(false)
    , LinkGeneratesManifest(true)
  {
  }
  bool Parse(std::vector<std::string>::const_iterator argBeg,
             std::vector<std::string>::const_iterator argEnd);
  int Link();

private:
  int LinkIncremental();
  int LinkNonIncremental();
  int RunMT(std::string const& out, bool notify);
};

// For visual studio 2005 and newer manifest files need to be embedded into
// exe and dll's.  This code does that in such a way that incremental linking
// still works.
int cmcmd::VisualStudioLink(std::vector<std::string> const& args, int type)
{
  // Replace streambuf so we output in the system codepage. CMake is set up
  // to output in Unicode (see SetUTF8Pipes) but the Visual Studio linker
  // outputs using the system codepage so we need to change behavior when
  // we run the link command.
  cmConsoleBuf consoleBuf;

  if (args.size() < 2) {
    return -1;
  }
  const bool verbose = cmSystemTools::HasEnv("VERBOSE");
  std::vector<std::string> expandedArgs;
  for (std::string const& i : args) {
    // check for nmake temporary files
    if (i[0] == '@' && !cmHasLiteralPrefix(i, "@CMakeFiles")) {
      cmsys::ifstream fin(i.substr(1).c_str());
      std::string line;
      while (cmSystemTools::GetLineFromStream(fin, line)) {
        cmSystemTools::ParseWindowsCommandLine(line.c_str(), expandedArgs);
      }
    } else {
      expandedArgs.push_back(i);
    }
  }

  cmVSLink vsLink(type, verbose);
  if (!vsLink.Parse(expandedArgs.begin() + 2, expandedArgs.end())) {
    return -1;
  }
  return vsLink.Link();
}

enum NumberFormat
{
  FORMAT_DECIMAL,
  FORMAT_HEX
};
struct NumberFormatter
{
  NumberFormat Format;
  int Value;
  NumberFormatter(NumberFormat format, int value)
    : Format(format)
    , Value(value)
  {
  }
};
std::ostream& operator<<(std::ostream& stream,
                         NumberFormatter const& formatter)
{
  auto const& flags = stream.flags();
  if (formatter.Format == FORMAT_DECIMAL) {
    stream << std::dec << formatter.Value;
  } else {
    stream << "0x" << std::hex << formatter.Value;
  }
  stream.flags(flags);
  return stream;
}

static bool RunCommand(const char* comment,
                       std::vector<std::string> const& command, bool verbose,
                       NumberFormat exitFormat, int* retCodeOut = nullptr,
                       bool (*retCodeOkay)(int) = nullptr)
{
  if (verbose) {
    std::cout << comment << ":\n";
    std::cout << cmJoin(command, " ") << "\n";
  }
  std::string output;
  int retCode = 0;
  bool commandResult = cmSystemTools::RunSingleCommand(
    command, &output, &output, &retCode, nullptr, cmSystemTools::OUTPUT_NONE);
  bool const retCodeSuccess =
    retCode == 0 || (retCodeOkay && retCodeOkay(retCode));
  bool const success = commandResult && retCodeSuccess;
  if (retCodeOut) {
    if (commandResult || !retCodeSuccess) {
      *retCodeOut = retCode;
    } else {
      *retCodeOut = -1;
    }
  }
  if (!success) {
    std::cout << comment << ": command \"" << cmJoin(command, " ")
              << "\" failed (exit code "
              << NumberFormatter(exitFormat, retCode)
              << ") with the following output:\n"
              << output;
  } else if (verbose) {
    // always print the output of the command, unless
    // it is the dumb rc command banner
    if (output.find("Resource Compiler Version") == std::string::npos) {
      std::cout << output;
    }
  }
  return success;
}

bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
                     std::vector<std::string>::const_iterator argEnd)
{
  // Parse our own arguments.
  std::string intDir;
  auto arg = argBeg;
  while (arg != argEnd && cmHasLiteralPrefix(*arg, "-")) {
    if (*arg == "--") {
      ++arg;
      break;
    }
    if (*arg == "--manifests") {
      for (++arg; arg != argEnd && !cmHasLiteralPrefix(*arg, "-"); ++arg) {
        this->UserManifests.push_back(*arg);
      }
    } else if (cmHasLiteralPrefix(*arg, "--intdir=")) {
      intDir = arg->substr(9);
      ++arg;
    } else if (cmHasLiteralPrefix(*arg, "--rc=")) {
      this->RcPath = arg->substr(5);
      ++arg;
    } else if (cmHasLiteralPrefix(*arg, "--mt=")) {
      this->MtPath = arg->substr(5);
      ++arg;
    } else {
      std::cerr << "unknown argument '" << *arg << "'\n";
      return false;
    }
  }
  if (intDir.empty()) {
    return false;
  }

  // The rest of the arguments form the link command.
  if (arg == argEnd) {
    return false;
  }
  this->LinkCommand.insert(this->LinkCommand.begin(), arg, argEnd);

  // Parse the link command to extract information we need.
  for (; arg != argEnd; ++arg) {
    if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0 ||
        cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0) {
      this->Incremental = true;
    } else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0) {
      this->LinkGeneratesManifest = false;
    } else if (cmHasLiteralPrefix(*arg, "/Fe")) {
      this->TargetFile = arg->substr(3);
    } else if (cmHasLiteralPrefix(*arg, "/out:")) {
      this->TargetFile = arg->substr(5);
    }
  }

  if (this->TargetFile.empty()) {
    return false;
  }

  this->ManifestFile = intDir + "/embed.manifest";
  this->LinkerManifestFile = intDir + "/intermediate.manifest";

  if (this->Incremental) {
    // We will compile a resource containing the manifest and
    // pass it to the link command.
    this->ManifestFileRC = intDir + "/manifest.rc";
    this->ManifestFileRes = intDir + "/manifest.res";
  } else if (this->UserManifests.empty()) {
    // Prior to support for user-specified manifests CMake placed the
    // linker-generated manifest next to the binary (as if it were not to be
    // embedded) when not linking incrementally.  Preserve this behavior.
    this->ManifestFile = this->TargetFile + ".manifest";
    this->LinkerManifestFile = this->ManifestFile;
  }

  if (this->LinkGeneratesManifest) {
    this->LinkCommand.emplace_back("/MANIFEST");
    this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
  }

  return true;
}

int cmVSLink::Link()
{
  if (this->Incremental &&
      (this->LinkGeneratesManifest || !this->UserManifests.empty())) {
    if (this->Verbose) {
      std::cout << "Visual Studio Incremental Link with embedded manifests\n";
    }
    return LinkIncremental();
  }
  if (this->Verbose) {
    if (!this->Incremental) {
      std::cout << "Visual Studio Non-Incremental Link\n";
    } else {
      std::cout << "Visual Studio Incremental Link without manifests\n";
    }
  }
  return LinkNonIncremental();
}

static bool mtRetIsUpdate(int mtRet)
{
  // 'mt /notify_update' returns a special value (differing between
  // Windows and POSIX hosts) when it updated the manifest file.
  return mtRet == 0x41020001 || mtRet == 0xbb;
}

int cmVSLink::LinkIncremental()
{
  // This follows the steps listed here:
  // http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx

  //    1.  Compiler compiles the application and generates the *.obj files.
  //    2.  An empty manifest file is generated if this is a clean build and if
  //    not the previous one is reused.
  //    3.  The resource compiler (rc.exe) compiles the *.manifest file to a
  //    *.res file.
  //    4.  Linker generates the binary (EXE or DLL) with the /incremental
  //    switch and embeds the dummy manifest file. The linker also generates
  //    the real manifest file based on the binaries that your binary depends
  //    on.
  //    5.  The manifest tool (mt.exe) is then used to generate the final
  //    manifest.

  // If the final manifest is changed, then 6 and 7 are run, if not
  // they are skipped, and it is done.

  //    6.  The resource compiler is invoked one more time.
  //    7.  Finally, the Linker does another incremental link, but since the
  //    only thing that has changed is the *.res file that contains the
  //    manifest it is a short link.

  // Create a resource file referencing the manifest.
  std::string absManifestFile =
    cmSystemTools::CollapseFullPath(this->ManifestFile);
  if (this->Verbose) {
    std::cout << "Create " << this->ManifestFileRC << "\n";
  }
  {
    cmsys::ofstream fout(this->ManifestFileRC.c_str());
    if (!fout) {
      return -1;
    }
    // Insert a pragma statement to specify utf-8 encoding.
    fout << "#pragma code_page(65001)\n";
    fout << this->Type
         << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ "
            "24 /* RT_MANIFEST */ \""
         << absManifestFile << "\"";
  }

  // If we have not previously generated a manifest file,
  // generate a manifest file so the resource compiler succeeds.
  if (!cmSystemTools::FileExists(this->ManifestFile)) {
    if (this->Verbose) {
      std::cout << "Create empty: " << this->ManifestFile << "\n";
    }
    if (this->UserManifests.empty()) {
      // generate an empty manifest because there are no user provided
      // manifest files.
      cmsys::ofstream foutTmp(this->ManifestFile.c_str());
    } else {
      this->RunMT("/out:" + this->ManifestFile, false);
    }
  }

  // Compile the resource file.
  std::vector<std::string> rcCommand;
  rcCommand.push_back(this->RcPath.empty() ? "rc" : this->RcPath);
  rcCommand.emplace_back("/fo");
  rcCommand.push_back(this->ManifestFileRes);
  rcCommand.push_back(this->ManifestFileRC);
  if (!RunCommand("RC Pass 1", rcCommand, this->Verbose, FORMAT_DECIMAL)) {
    return -1;
  }

  // Tell the linker to use our manifest compiled into a resource.
  this->LinkCommand.push_back(this->ManifestFileRes);

  // Run the link command (possibly generates intermediate manifest).
  if (!RunCommand("LINK Pass 1", this->LinkCommand, this->Verbose,
                  FORMAT_DECIMAL)) {
    return -1;
  }

  // Run the manifest tool to create the final manifest.
  int mtRet = this->RunMT("/out:" + this->ManifestFile, true);

  // If mt returns a special value then it updated the manifest file so
  // we need to embed it again.  Otherwise we are done.
  if (!mtRetIsUpdate(mtRet)) {
    return mtRet;
  }

  // Compile the resource file again.
  if (!RunCommand("RC Pass 2", rcCommand, this->Verbose, FORMAT_DECIMAL)) {
    return -1;
  }

  // Link incrementally again to use the updated resource.
  if (!RunCommand("FINAL LINK", this->LinkCommand, this->Verbose,
                  FORMAT_DECIMAL)) {
    return -1;
  }
  return 0;
}

int cmVSLink::LinkNonIncremental()
{
  // Run the link command (possibly generates intermediate manifest).
  if (!RunCommand("LINK", this->LinkCommand, this->Verbose, FORMAT_DECIMAL)) {
    return -1;
  }

  // If we have no manifest files we are done.
  if (!this->LinkGeneratesManifest && this->UserManifests.empty()) {
    return 0;
  }

  // Run the manifest tool to embed the final manifest in the binary.
  std::string mtOut =
    "/outputresource:" + this->TargetFile + (this->Type == 1 ? ";#1" : ";#2");
  return this->RunMT(mtOut, false);
}

int cmVSLink::RunMT(std::string const& out, bool notify)
{
  std::vector<std::string> mtCommand;
  mtCommand.push_back(this->MtPath.empty() ? "mt" : this->MtPath);
  mtCommand.emplace_back("/nologo");
  mtCommand.emplace_back("/manifest");

  // add the linker generated manifest if the file exists.
  if (this->LinkGeneratesManifest &&
      cmSystemTools::FileExists(this->LinkerManifestFile)) {
    mtCommand.push_back(this->LinkerManifestFile);
  }
  cm::append(mtCommand, this->UserManifests);
  mtCommand.push_back(out);
  if (notify) {
    // Add an undocumented option that enables a special return
    // code to notify us when the manifest is modified.
    mtCommand.emplace_back("/notify_update");
  }
  int mtRet = 0;
  if (!RunCommand("MT", mtCommand, this->Verbose, FORMAT_HEX, &mtRet,
                  mtRetIsUpdate)) {
    return -1;
  }
  return mtRet;
}
