1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmAddExecutableCommand.h"
5 #include "cmExecutionStatus.h"
6 #include "cmGeneratorExpression.h"
7 #include "cmGlobalGenerator.h"
8 #include "cmMakefile.h"
9 #include "cmStateTypes.h"
10 #include "cmStringAlgorithms.h"
13 bool cmAddExecutableCommand(std::vector<std::string> const& args,
14 cmExecutionStatus& status)
17 status.SetError("called with incorrect number of arguments");
21 cmMakefile& mf = status.GetMakefile();
22 auto s = args.begin();
24 std::string const& exename = *s;
27 bool use_win32 = false;
28 bool use_macbundle = false;
29 bool excludeFromAll = false;
30 bool importTarget = false;
31 bool importGlobal = false;
33 while (s != args.end()) {
37 } else if (*s == "MACOSX_BUNDLE") {
40 } else if (*s == "EXCLUDE_FROM_ALL") {
42 excludeFromAll = true;
43 } else if (*s == "IMPORTED") {
46 } else if (importTarget && *s == "GLOBAL") {
49 } else if (*s == "ALIAS") {
57 if (importTarget && !importGlobal) {
58 importGlobal = mf.IsImportedTargetGlobalScope();
61 bool nameOk = cmGeneratorExpression::IsValidTargetName(exename) &&
62 !cmGlobalGenerator::IsReservedTarget(exename);
64 if (nameOk && !importTarget && !isAlias) {
65 nameOk = exename.find(':') == std::string::npos;
67 if (!nameOk && !mf.CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) {
71 // Special modifiers are not allowed with IMPORTED signature.
72 if (importTarget && (use_win32 || use_macbundle || excludeFromAll)) {
74 status.SetError("may not be given WIN32 for an IMPORTED target.");
75 } else if (use_macbundle) {
77 "may not be given MACOSX_BUNDLE for an IMPORTED target.");
78 } else // if(excludeFromAll)
81 "may not be given EXCLUDE_FROM_ALL for an IMPORTED target.");
86 if (!cmGeneratorExpression::IsValidTargetName(exename)) {
87 status.SetError("Invalid name for ALIAS: " + exename);
91 status.SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
94 if (importTarget || importGlobal) {
95 status.SetError("IMPORTED with ALIAS is not allowed.");
98 if (args.size() != 3) {
99 status.SetError("ALIAS requires exactly one target argument.");
103 std::string const& aliasedName = *s;
104 if (mf.IsAlias(aliasedName)) {
105 status.SetError(cmStrCat("cannot create ALIAS target \"", exename,
106 "\" because target \"", aliasedName,
107 "\" is itself an ALIAS."));
110 cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true);
111 if (!aliasedTarget) {
112 status.SetError(cmStrCat("cannot create ALIAS target \"", exename,
113 "\" because target \"", aliasedName,
114 "\" does not already exist."));
117 cmStateEnums::TargetType type = aliasedTarget->GetType();
118 if (type != cmStateEnums::EXECUTABLE) {
119 status.SetError(cmStrCat("cannot create ALIAS target \"", exename,
120 "\" because target \"", aliasedName,
121 "\" is not an executable."));
124 mf.AddAlias(exename, aliasedName,
125 !aliasedTarget->IsImported() ||
126 aliasedTarget->IsImportedGloballyVisible());
130 // Handle imported target creation.
132 // Make sure the target does not already exist.
133 if (mf.FindTargetToUse(exename)) {
134 status.SetError(cmStrCat(
135 "cannot create imported target \"", exename,
136 "\" because another target with the same name already exists."));
140 // Create the imported target.
141 mf.AddImportedTarget(exename, cmStateEnums::EXECUTABLE, importGlobal);
145 // Enforce name uniqueness.
148 if (!mf.EnforceUniqueName(exename, msg)) {
149 status.SetError(msg);
154 std::vector<std::string> srclists(s, args.end());
155 cmTarget* tgt = mf.AddExecutable(exename, srclists, excludeFromAll);
157 tgt->SetProperty("WIN32_EXECUTABLE", "ON");
160 tgt->SetProperty("MACOSX_BUNDLE", "ON");