/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
  Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com>

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmNinjaNormalTargetGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmGlobalNinjaGenerator.h"
#include "cmSourceFile.h"
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmOSXBundleGenerator.h"

#include <assert.h>
#include <algorithm>

#ifndef _WIN32
#include <unistd.h>
#endif


cmNinjaNormalTargetGenerator::
cmNinjaNormalTargetGenerator(cmTarget* target)
  : cmNinjaTargetGenerator(target)
  , TargetNameOut()
  , TargetNameSO()
  , TargetNameReal()
  , TargetNameImport()
  , TargetNamePDB()
  , TargetLinkLanguage(0)
{
  cmOSXBundleGenerator::PrepareTargetProperties(target);

  this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
  if (target->GetType() == cmTarget::EXECUTABLE)
    target->GetExecutableNames(this->TargetNameOut,
                               this->TargetNameReal,
                               this->TargetNameImport,
                               this->TargetNamePDB,
                               GetLocalGenerator()->GetConfigName());
  else
    target->GetLibraryNames(this->TargetNameOut,
                            this->TargetNameSO,
                            this->TargetNameReal,
                            this->TargetNameImport,
                            this->TargetNamePDB,
                            GetLocalGenerator()->GetConfigName());

  if(target->GetType() != cmTarget::OBJECT_LIBRARY)
    {
    // on Windows the output dir is already needed at compile time
    // ensure the directory exists (OutDir test)
    EnsureDirectoryExists(target->GetDirectory(this->GetConfigName()));
    }

  this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
                                                      this->TargetNameOut,
                                                      this->GetConfigName());
  this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}

cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator()
{
  delete this->OSXBundleGenerator;
}

void cmNinjaNormalTargetGenerator::Generate()
{
  if (!this->TargetLinkLanguage) {
    cmSystemTools::Error("CMake can not determine linker language for target:",
                         this->GetTarget()->GetName());
    return;
  }

  // Write the rules for each language.
  this->WriteLanguagesRules();

  // Write the build statements
  this->WriteObjectBuildStatements();

  if(this->GetTarget()->GetType() == cmTarget::OBJECT_LIBRARY)
    {
    this->WriteObjectLibStatement();
    }
  else
    {
    this->WriteLinkRule(false); // write rule without rspfile support
    this->WriteLinkRule(true);  // write rule with rspfile support
    this->WriteLinkStatement();
    }
}

void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
{
#ifdef NINJA_GEN_VERBOSE_FILES
  cmGlobalNinjaGenerator::WriteDivider(this->GetRulesFileStream());
  this->GetRulesFileStream()
    << "# Rules for each languages for "
    << cmTarget::GetTargetTypeName(this->GetTarget()->GetType())
    << " target "
    << this->GetTargetName()
    << "\n\n";
#endif

  std::set<cmStdString> languages;
  this->GetTarget()->GetLanguages(languages);
  for(std::set<cmStdString>::const_iterator l = languages.begin();
      l != languages.end();
      ++l)
    this->WriteLanguageRules(*l);
}

const char *cmNinjaNormalTargetGenerator::GetVisibleTypeName() const
{
  switch (this->GetTarget()->GetType()) {
    case cmTarget::STATIC_LIBRARY:
      return "static library";
    case cmTarget::SHARED_LIBRARY:
      return "shared library";
    case cmTarget::MODULE_LIBRARY:
      if (this->GetTarget()->IsCFBundleOnApple())
        return "CFBundle shared module";
      else
        return "shared module";
    case cmTarget::EXECUTABLE:
      return "executable";
    default:
      return 0;
  }
}

std::string
cmNinjaNormalTargetGenerator
::LanguageLinkerRule() const
{
  return std::string(this->TargetLinkLanguage)
    + "_"
    + cmTarget::GetTargetTypeName(this->GetTarget()->GetType())
    + "_LINKER";
}

void
cmNinjaNormalTargetGenerator
::WriteLinkRule(bool useResponseFile)
{
  cmTarget::TargetType targetType = this->GetTarget()->GetType();
  std::string ruleName = this->LanguageLinkerRule();
  if (useResponseFile)
    ruleName += "_RSP_FILE";

  // Select whether to use a response file for objects.
  std::string rspfile;
  std::string rspcontent;

  if (!this->GetGlobalGenerator()->HasRule(ruleName)) {
    cmLocalGenerator::RuleVariables vars;
    vars.RuleLauncher = "RULE_LAUNCH_LINK";
    vars.CMTarget = this->GetTarget();
    vars.Language = this->TargetLinkLanguage;

    std::string responseFlag;
    if (!useResponseFile) {
      vars.Objects = "$in";
      vars.LinkLibraries = "$LINK_PATH $LINK_LIBRARIES";
    } else {
        std::string cmakeVarLang = "CMAKE_";
        cmakeVarLang += this->TargetLinkLanguage;

        // build response file name
        std::string cmakeLinkVar =  cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
        const char * flag = GetMakefile()->GetDefinition(cmakeLinkVar.c_str());
        if(flag) {
          responseFlag = flag;
        } else {
          responseFlag = "@";
        }
        rspfile = "$RSP_FILE";
        responseFlag += rspfile;

        // build response file content
        std::string linkOptionVar = cmakeVarLang;
        linkOptionVar += "_COMPILER_LINKER_OPTION_FLAG_";
        linkOptionVar += cmTarget::GetTargetTypeName(targetType);
        const std::string linkOption =
                GetMakefile()->GetSafeDefinition(linkOptionVar.c_str());
        rspcontent = "$in_newline "+linkOption+" $LINK_PATH $LINK_LIBRARIES";
        vars.Objects = responseFlag.c_str();
        vars.LinkLibraries = "";
    }

    vars.ObjectDir = "$OBJECT_DIR";

    // TODO:
    // Makefile generator expands <TARGET> to the plain target name
    // with suffix. $out expands to a relative path. This difference
    // could make trouble when switching to Ninja generator. Maybe
    // using TARGET_NAME and RuleVariables::TargetName is a fix.
    vars.Target = "$out";

    vars.SONameFlag = "$SONAME_FLAG";
    vars.TargetSOName = "$SONAME";
    vars.TargetInstallNameDir = "$INSTALLNAME_DIR";
    vars.TargetPDB = "$TARGET_PDB";

    // Setup the target version.
    std::string targetVersionMajor;
    std::string targetVersionMinor;
    {
    cmOStringStream majorStream;
    cmOStringStream minorStream;
    int major;
    int minor;
    this->GetTarget()->GetTargetVersion(major, minor);
    majorStream << major;
    minorStream << minor;
    targetVersionMajor = majorStream.str();
    targetVersionMinor = minorStream.str();
    }
    vars.TargetVersionMajor = targetVersionMajor.c_str();
    vars.TargetVersionMinor = targetVersionMinor.c_str();

    vars.Flags = "$FLAGS";
    vars.LinkFlags = "$LINK_FLAGS";

    std::string langFlags;
    if (targetType != cmTarget::EXECUTABLE) {
      this->GetLocalGenerator()->AddLanguageFlags(langFlags,
                                                  this->TargetLinkLanguage,
                                                  this->GetConfigName());
      langFlags += " $ARCH_FLAGS";
      vars.LanguageCompileFlags = langFlags.c_str();
    }

    // Rule for linking library/executable.
    std::vector<std::string> linkCmds = this->ComputeLinkCmd();
    for(std::vector<std::string>::iterator i = linkCmds.begin();
        i != linkCmds.end();
        ++i)
      {
      this->GetLocalGenerator()->ExpandRuleVariables(*i, vars);
      }
    linkCmds.insert(linkCmds.begin(), "$PRE_LINK");
    linkCmds.push_back("$POST_BUILD");
    std::string linkCmd =
      this->GetLocalGenerator()->BuildCommandLine(linkCmds);

    // Write the linker rule with response file if needed.
    cmOStringStream comment;
    comment << "Rule for linking " << this->TargetLinkLanguage << " "
            << this->GetVisibleTypeName() << ".";
    cmOStringStream description;
    description << "Linking " << this->TargetLinkLanguage << " "
                << this->GetVisibleTypeName() << " $out";
    this->GetGlobalGenerator()->AddRule(ruleName,
                                        linkCmd,
                                        description.str(),
                                        comment.str(),
                                        /*depfile*/ "",
                                        rspfile,
                                        rspcontent);
  }

  if (this->TargetNameOut != this->TargetNameReal) {
    std::string cmakeCommand =
      this->GetLocalGenerator()->ConvertToOutputFormat(
        this->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND"),
        cmLocalGenerator::SHELL);
    if (targetType == cmTarget::EXECUTABLE)
      this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_EXECUTABLE",
                                          cmakeCommand +
                                          " -E cmake_symlink_executable"
                                          " $in $out && $POST_BUILD",
                                          "Creating executable symlink $out",
                                      "Rule for creating executable symlink.");
    else
      this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_LIBRARY",
                                          cmakeCommand +
                                          " -E cmake_symlink_library"
                                          " $in $SONAME $out && $POST_BUILD",
                                          "Creating library symlink $out",
                                         "Rule for creating library symlink.");
  }
}

std::vector<std::string>
cmNinjaNormalTargetGenerator
::ComputeLinkCmd()
{
  std::vector<std::string> linkCmds;
  cmTarget::TargetType targetType = this->GetTarget()->GetType();
  switch (targetType) {
    case cmTarget::STATIC_LIBRARY: {
      // Check if you have a non archive way to create the static library.
      {
      std::string linkCmdVar = "CMAKE_";
      linkCmdVar += this->TargetLinkLanguage;
      linkCmdVar += "_CREATE_STATIC_LIBRARY";
      if (const char *linkCmd =
            this->GetMakefile()->GetDefinition(linkCmdVar.c_str()))
        {
        cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
        return linkCmds;
        }
      }

      // We have archive link commands set. First, delete the existing archive.
      std::string cmakeCommand =
        this->GetLocalGenerator()->ConvertToOutputFormat(
          this->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND"),
          cmLocalGenerator::SHELL);
      linkCmds.push_back(cmakeCommand + " -E remove $out");

      // TODO: Use ARCHIVE_APPEND for archives over a certain size.
      {
      std::string linkCmdVar = "CMAKE_";
      linkCmdVar += this->TargetLinkLanguage;
      linkCmdVar += "_ARCHIVE_CREATE";
      const char *linkCmd =
        this->GetMakefile()->GetRequiredDefinition(linkCmdVar.c_str());
      cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
      }
      {
      std::string linkCmdVar = "CMAKE_";
      linkCmdVar += this->TargetLinkLanguage;
      linkCmdVar += "_ARCHIVE_FINISH";
      const char *linkCmd =
        this->GetMakefile()->GetRequiredDefinition(linkCmdVar.c_str());
      cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
      }
      return linkCmds;
    }
    case cmTarget::SHARED_LIBRARY:
    case cmTarget::MODULE_LIBRARY:
    case cmTarget::EXECUTABLE: {
      std::string linkCmdVar = "CMAKE_";
      linkCmdVar += this->TargetLinkLanguage;
      switch (targetType) {
      case cmTarget::SHARED_LIBRARY:
        linkCmdVar += "_CREATE_SHARED_LIBRARY";
        break;
      case cmTarget::MODULE_LIBRARY:
        linkCmdVar += "_CREATE_SHARED_MODULE";
        break;
      case cmTarget::EXECUTABLE:
        linkCmdVar += "_LINK_EXECUTABLE";
        break;
      default:
        assert(0 && "Unexpected target type");
      }

      const char *linkCmd =
        this->GetMakefile()->GetRequiredDefinition(linkCmdVar.c_str());
      cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
      return linkCmds;
    }
    default:
      assert(0 && "Unexpected target type");
  }
  return std::vector<std::string>();
}

void cmNinjaNormalTargetGenerator::WriteLinkStatement()
{
  cmTarget::TargetType targetType = this->GetTarget()->GetType();

  std::string targetOutput = ConvertToNinjaPath(
    this->GetTarget()->GetFullPath(this->GetConfigName()).c_str());
  std::string targetOutputReal = ConvertToNinjaPath(
    this->GetTarget()->GetFullPath(this->GetConfigName(),
                                   /*implib=*/false,
                                   /*realpath=*/true).c_str());
  std::string targetOutputImplib = ConvertToNinjaPath(
    this->GetTarget()->GetFullPath(this->GetConfigName(),
                                   /*implib=*/true).c_str());

  if (this->GetTarget()->IsAppBundleOnApple())
    {
    // Create the app bundle
    std::string outpath;
    this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath);

    // Calculate the output path
    targetOutput = outpath + this->TargetNameOut;
    targetOutput = this->ConvertToNinjaPath(targetOutput.c_str());
    targetOutputReal = outpath + this->TargetNameReal;
    targetOutputReal = this->ConvertToNinjaPath(targetOutputReal.c_str());
    }
  else if (this->GetTarget()->IsFrameworkOnApple())
    {
    // Create the library framework.
    this->OSXBundleGenerator->CreateFramework(this->TargetNameOut);
    }
  else if(this->GetTarget()->IsCFBundleOnApple())
    {
    // Create the core foundation bundle.
    std::string outpath;
    this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut, outpath);
    }

  // Write comments.
  cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
  this->GetBuildFileStream()
    << "# Link build statements for "
    << cmTarget::GetTargetTypeName(targetType)
    << " target "
    << this->GetTargetName()
    << "\n\n";

  cmNinjaDeps emptyDeps;
  cmNinjaVars vars;

  // Compute the comment.
  cmOStringStream comment;
  comment << "Link the " << this->GetVisibleTypeName() << " "
          << targetOutputReal;

  // Compute outputs.
  cmNinjaDeps outputs;
  outputs.push_back(targetOutputReal);

  // Compute specific libraries to link with.
  cmNinjaDeps explicitDeps = this->GetObjects();
  cmNinjaDeps implicitDeps = this->ComputeLinkDeps();

  std::string frameworkPath;
  std::string linkPath;
  this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"],
                                            vars["FLAGS"],
                                            vars["LINK_FLAGS"],
                                            frameworkPath,
                                            linkPath,
                                            this->GetGeneratorTarget());

  this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]);
  vars["LINK_FLAGS"] = cmGlobalNinjaGenerator
                        ::EncodeLiteral(vars["LINK_FLAGS"]);

  vars["LINK_PATH"] = frameworkPath + linkPath;

  // Compute architecture specific link flags.  Yes, these go into a different
  // variable for executables, probably due to a mistake made when duplicating
  // code between the Makefile executable and library generators.
  std::string flags = (targetType == cmTarget::EXECUTABLE
                               ? vars["FLAGS"]
                               : vars["ARCH_FLAGS"]);
  this->GetLocalGenerator()->AddArchitectureFlags(flags,
                             this->GetGeneratorTarget(),
                             this->TargetLinkLanguage,
                             this->GetConfigName());
  if (targetType == cmTarget::EXECUTABLE) {
    vars["FLAGS"] = flags;
  } else {
    vars["ARCH_FLAGS"] = flags;
  }
  if (this->GetTarget()->HasSOName(this->GetConfigName())) {
    vars["SONAME_FLAG"] =
      this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage);
    vars["SONAME"] = this->TargetNameSO;
    if (targetType == cmTarget::SHARED_LIBRARY) {
      std::string install_name_dir = this->GetTarget()
        ->GetInstallNameDirForBuildTree(this->GetConfigName());

      if (!install_name_dir.empty()) {
        vars["INSTALLNAME_DIR"] =
          this->GetLocalGenerator()->Convert(install_name_dir.c_str(),
              cmLocalGenerator::NONE,
              cmLocalGenerator::SHELL, false);
      }
    }
  }

  if (!this->TargetNameImport.empty()) {
    const std::string impLibPath = this->GetLocalGenerator()
      ->ConvertToOutputFormat(targetOutputImplib.c_str(),
                              cmLocalGenerator::SHELL);
    vars["TARGET_IMPLIB"] = impLibPath;
    EnsureParentDirectoryExists(impLibPath);
  }

  cmMakefile* mf = this->GetMakefile();
  if (!this->SetMsvcTargetPdbVariable(vars))
    {
    // It is common to place debug symbols at a specific place,
    // so we need a plain target name in the rule available.
    std::string prefix;
    std::string base;
    std::string suffix;
    this->GetTarget()->GetFullNameComponents(prefix, base, suffix);
    std::string dbg_suffix = ".dbg";
    // TODO: Where to document?
    if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX"))
      dbg_suffix = mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX");
    vars["TARGET_PDB"] = base + suffix + dbg_suffix;
    }

  if (mf->IsOn("CMAKE_COMPILER_IS_MINGW"))
    {
    const std::string objPath = GetTarget()->GetSupportDirectory();
    vars["OBJECT_DIR"] = ConvertToNinjaPath(objPath.c_str());
    EnsureDirectoryExists(objPath);
    // ar.exe can't handle backslashes in rsp files (implictly used by gcc)
    std::string& linkLibraries = vars["LINK_LIBRARIES"];
    std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
    }

  std::vector<cmCustomCommand> *cmdLists[3] = {
    &this->GetTarget()->GetPreBuildCommands(),
    &this->GetTarget()->GetPreLinkCommands(),
    &this->GetTarget()->GetPostBuildCommands()
  };

  std::vector<std::string> preLinkCmdLines, postBuildCmdLines;
  std::vector<std::string> *cmdLineLists[3] = {
    &preLinkCmdLines,
    &preLinkCmdLines,
    &postBuildCmdLines
  };

  for (unsigned i = 0; i != 3; ++i) {
    for (std::vector<cmCustomCommand>::const_iterator
         ci = cmdLists[i]->begin();
         ci != cmdLists[i]->end(); ++ci) {
      this->GetLocalGenerator()->AppendCustomCommandLines(&*ci,
                                                          *cmdLineLists[i]);
    }
  }

  // If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for
  // the link commands.
  if (!preLinkCmdLines.empty()) {
    const std::string homeOutDir = this->GetLocalGenerator()
      ->ConvertToOutputFormat(this->GetMakefile()->GetHomeOutputDirectory(),
                              cmLocalGenerator::SHELL);
    preLinkCmdLines.push_back("cd " + homeOutDir);
  }

  vars["PRE_LINK"] =
    this->GetLocalGenerator()->BuildCommandLine(preLinkCmdLines);
  std::string postBuildCmdLine =
    this->GetLocalGenerator()->BuildCommandLine(postBuildCmdLines);

  cmNinjaVars symlinkVars;
  if (targetOutput == targetOutputReal) {
    vars["POST_BUILD"] = postBuildCmdLine;
  } else {
    vars["POST_BUILD"] = ":";
    symlinkVars["POST_BUILD"] = postBuildCmdLine;
  }

  int linkRuleLength = this->GetGlobalGenerator()->
                                 GetRuleCmdLength(this->LanguageLinkerRule());

  int commandLineLengthLimit = 1;
  const char* forceRspFile = "CMAKE_NINJA_FORCE_RESPONSE_FILE";
  if (!this->GetMakefile()->IsDefinitionSet(forceRspFile) &&
      cmSystemTools::GetEnv(forceRspFile) == 0) {
#ifdef _WIN32
    commandLineLengthLimit = 8000 - linkRuleLength;
#elif defined(__linux) || defined(__APPLE__)
    // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac
    commandLineLengthLimit = ((int)sysconf(_SC_ARG_MAX))-linkRuleLength-1000;
#else
    (void)linkRuleLength;
    commandLineLengthLimit = -1;
#endif
  }

  const std::string rspfile = std::string
                              (cmake::GetCMakeFilesDirectoryPostSlash()) +
                              this->GetTarget()->GetName() + ".rsp";

  // Write the build statement for this target.
  cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(),
                                     comment.str(),
                                     this->LanguageLinkerRule(),
                                     outputs,
                                     explicitDeps,
                                     implicitDeps,
                                     emptyDeps,
                                     vars,
                                     rspfile,
                                     commandLineLengthLimit);

  if (targetOutput != targetOutputReal) {
    if (targetType == cmTarget::EXECUTABLE) {
      cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(),
                                  "Create executable symlink " + targetOutput,
                                         "CMAKE_SYMLINK_EXECUTABLE",
                                         cmNinjaDeps(1, targetOutput),
                                         cmNinjaDeps(1, targetOutputReal),
                                         emptyDeps,
                                         emptyDeps,
                                         symlinkVars);
    } else {
      cmNinjaDeps symlinks;
      const std::string soName = this->GetTargetFilePath(this->TargetNameSO);
      // If one link has to be created.
      if (targetOutputReal == soName || targetOutput == soName) {
        symlinkVars["SONAME"] = soName;
      } else {
        symlinkVars["SONAME"] = "";
        symlinks.push_back(soName);
      }
      symlinks.push_back(targetOutput);
      cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(),
                                      "Create library symlink " + targetOutput,
                                         "CMAKE_SYMLINK_LIBRARY",
                                         symlinks,
                                         cmNinjaDeps(1, targetOutputReal),
                                         emptyDeps,
                                         emptyDeps,
                                         symlinkVars);
    }
  }

  if (!this->TargetNameImport.empty()) {
    // Since using multiple outputs would mess up the $out variable, use an
    // alias for the import library.
    cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
                                            "Alias for import library.",
                                            cmNinjaDeps(1, targetOutputImplib),
                                            cmNinjaDeps(1, targetOutputReal));
  }

  // Add aliases for the file name and the target name.
  this->GetGlobalGenerator()->AddTargetAlias(this->TargetNameOut,
                                             this->GetTarget());
  this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
                                             this->GetTarget());
}

//----------------------------------------------------------------------------
void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
{
  // Write a phony output that depends on all object files.
  cmNinjaDeps outputs;
  this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs);
  cmNinjaDeps depends = this->GetObjects();
  cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
                                          "Object library "
                                          + this->GetTargetName(),
                                          outputs,
                                          depends);

  // Add aliases for the target name.
  this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
                                             this->GetTarget());
}
