| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 | /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying   file Copyright.txt or https://cmake.org/licensing for details.  */#include "cmAddExecutableCommand.h"#include <sstream>#include "cmExecutionStatus.h"#include "cmGeneratorExpression.h"#include "cmGlobalGenerator.h"#include "cmMakefile.h"#include "cmStateTypes.h"#include "cmTarget.h"bool cmAddExecutableCommand(std::vector<std::string> const& args,                            cmExecutionStatus& status){  if (args.empty()) {    status.SetError("called with incorrect number of arguments");    return false;  }  cmMakefile& mf = status.GetMakefile();  std::vector<std::string>::const_iterator s = args.begin();  std::string const& exename = *s;  ++s;  bool use_win32 = false;  bool use_macbundle = false;  bool excludeFromAll = false;  bool importTarget = false;  bool importGlobal = false;  bool isAlias = false;  while (s != args.end()) {    if (*s == "WIN32") {      ++s;      use_win32 = true;    } else if (*s == "MACOSX_BUNDLE") {      ++s;      use_macbundle = true;    } else if (*s == "EXCLUDE_FROM_ALL") {      ++s;      excludeFromAll = true;    } else if (*s == "IMPORTED") {      ++s;      importTarget = true;    } else if (importTarget && *s == "GLOBAL") {      ++s;      importGlobal = true;    } else if (*s == "ALIAS") {      ++s;      isAlias = true;    } else {      break;    }  }  bool nameOk = cmGeneratorExpression::IsValidTargetName(exename) &&    !cmGlobalGenerator::IsReservedTarget(exename);  if (nameOk && !importTarget && !isAlias) {    nameOk = exename.find(':') == std::string::npos;  }  if (!nameOk && !mf.CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) {    return false;  }  // Special modifiers are not allowed with IMPORTED signature.  if (importTarget && (use_win32 || use_macbundle || excludeFromAll)) {    if (use_win32) {      status.SetError("may not be given WIN32 for an IMPORTED target.");    } else if (use_macbundle) {      status.SetError(        "may not be given MACOSX_BUNDLE for an IMPORTED target.");    } else // if(excludeFromAll)    {      status.SetError(        "may not be given EXCLUDE_FROM_ALL for an IMPORTED target.");    }    return false;  }  if (isAlias) {    if (!cmGeneratorExpression::IsValidTargetName(exename)) {      status.SetError("Invalid name for ALIAS: " + exename);      return false;    }    if (excludeFromAll) {      status.SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");      return false;    }    if (importTarget || importGlobal) {      status.SetError("IMPORTED with ALIAS is not allowed.");      return false;    }    if (args.size() != 3) {      std::ostringstream e;      e << "ALIAS requires exactly one target argument.";      status.SetError(e.str());      return false;    }    std::string const& aliasedName = *s;    if (mf.IsAlias(aliasedName)) {      std::ostringstream e;      e << "cannot create ALIAS target \"" << exename << "\" because target \""        << aliasedName << "\" is itself an ALIAS.";      status.SetError(e.str());      return false;    }    cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true);    if (!aliasedTarget) {      std::ostringstream e;      e << "cannot create ALIAS target \"" << exename << "\" because target \""        << aliasedName << "\" does not already exist.";      status.SetError(e.str());      return false;    }    cmStateEnums::TargetType type = aliasedTarget->GetType();    if (type != cmStateEnums::EXECUTABLE) {      std::ostringstream e;      e << "cannot create ALIAS target \"" << exename << "\" because target \""        << aliasedName << "\" is not an executable.";      status.SetError(e.str());      return false;    }    if (aliasedTarget->IsImported() &&        !aliasedTarget->IsImportedGloballyVisible()) {      std::ostringstream e;      e << "cannot create ALIAS target \"" << exename << "\" because target \""        << aliasedName << "\" is imported but not globally visible.";      status.SetError(e.str());      return false;    }    mf.AddAlias(exename, aliasedName);    return true;  }  // Handle imported target creation.  if (importTarget) {    // Make sure the target does not already exist.    if (mf.FindTargetToUse(exename)) {      std::ostringstream e;      e << "cannot create imported target \"" << exename        << "\" because another target with the same name already exists.";      status.SetError(e.str());      return false;    }    // Create the imported target.    mf.AddImportedTarget(exename, cmStateEnums::EXECUTABLE, importGlobal);    return true;  }  // Enforce name uniqueness.  {    std::string msg;    if (!mf.EnforceUniqueName(exename, msg)) {      status.SetError(msg);      return false;    }  }  std::vector<std::string> srclists(s, args.end());  cmTarget* tgt = mf.AddExecutable(exename, srclists, excludeFromAll);  if (use_win32) {    tgt->SetProperty("WIN32_EXECUTABLE", "ON");  }  if (use_macbundle) {    tgt->SetProperty("MACOSX_BUNDLE", "ON");  }  return true;}
 |