Resync (forgot to add new files?)
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmPolicies.cxx
blobc4b51b5618e5cef104b35fa6b7e83978e4b5c949
1 #include "cmPolicies.h"
2 #include "cmake.h"
3 #include "cmMakefile.h"
4 #include "cmSourceFile.h"
5 #include "cmVersion.h"
6 #include <map>
7 #include <set>
8 #include <queue>
9 #include <assert.h>
11 const char* cmPolicies::PolicyStatusNames[] = {
12 "OLD", "WARN", "NEW", "REQUIRED_IF_USED", "REQUIRED_ALWAYS"
15 class cmPolicy
17 public:
18 cmPolicy(cmPolicies::PolicyID iD,
19 const char *idString,
20 const char *shortDescription,
21 const char *longDescription,
22 unsigned int majorVersionIntroduced,
23 unsigned int minorVersionIntroduced,
24 unsigned int patchVersionIntroduced,
25 cmPolicies::PolicyStatus status)
27 if (!idString || !shortDescription || ! longDescription)
29 cmSystemTools::Error("Attempt to define a policy without "
30 "all parameters being specified!");
31 return;
33 this->ID = iD;
34 this->IDString = idString;
35 this->ShortDescription = shortDescription;
36 this->LongDescription = longDescription;
37 this->MajorVersionIntroduced = majorVersionIntroduced;
38 this->MinorVersionIntroduced = minorVersionIntroduced;
39 this->PatchVersionIntroduced = patchVersionIntroduced;
40 this->Status = status;
43 std::string GetVersionString()
45 cmOStringStream error;
46 error << this->MajorVersionIntroduced << "." <<
47 this->MinorVersionIntroduced << "." <<
48 this->PatchVersionIntroduced;
49 return error.str();
52 bool IsPolicyNewerThan(unsigned int majorV,
53 unsigned int minorV,
54 unsigned int patchV)
56 if (majorV < this->MajorVersionIntroduced)
58 return true;
60 if (majorV > this->MajorVersionIntroduced)
62 return false;
64 if (minorV < this->MinorVersionIntroduced)
66 return true;
68 if (minorV > this->MinorVersionIntroduced)
70 return false;
72 return (patchV < this->PatchVersionIntroduced);
75 cmPolicies::PolicyID ID;
76 std::string IDString;
77 std::string ShortDescription;
78 std::string LongDescription;
79 unsigned int MajorVersionIntroduced;
80 unsigned int MinorVersionIntroduced;
81 unsigned int PatchVersionIntroduced;
82 cmPolicies::PolicyStatus Status;
85 cmPolicies::cmPolicies()
87 // define all the policies
88 this->DefinePolicy(
89 CMP0000, "CMP0000",
90 "A policy version number must be specified.",
91 "CMake requires that projects specify the version of CMake to which "
92 "they have been written. "
93 "This policy has been put in place to help existing projects build with "
94 "new CMake versions as it evolves. "
95 "The easiest way to specify a policy version number is to "
96 "call the cmake_minimum_required command at the top of "
97 "your CMakeLists.txt file:\n"
98 " cmake_minimum_required(VERSION <major>.<minor>)\n"
99 "where \"<major>.<minor>\" is the version of CMake you want to support "
100 "(such as \"2.6\"). "
101 "The command will ensure that at least the given version of CMake is "
102 "running and set the policy version. "
103 "See documentation of cmake_minimum_required for details. "
104 "The cmake_policy command may be used at any time to set the "
105 "policy version:\n"
106 " cmake_policy(VERSION <major>.<minor>)\n"
107 "This is the recommended way to set the policy version except at "
108 "the very top of a project.",
109 2,6,0, cmPolicies::WARN
112 this->DefinePolicy(
113 CMP0001, "CMP0001",
114 "CMAKE_BACKWARDS_COMPATIBILITY should no longer be used.",
115 "The OLD behavior is to check CMAKE_BACKWARDS_COMPATIBILITY and present "
116 "it to the user. "
117 "The NEW behavior is to ignore CMAKE_BACKWARDS_COMPATIBILITY "
118 "completely.\n"
119 "In CMake 2.4 and below the variable CMAKE_BACKWARDS_COMPATIBILITY was "
120 "used to request compatibility with earlier versions of CMake. "
121 "In CMake 2.6 and above all compatibility issues are handled by policies "
122 "and the cmake_policy command. "
123 "However, CMake must still check CMAKE_BACKWARDS_COMPATIBILITY for "
124 "projects written for CMake 2.4 and below.",
125 2,6,0, cmPolicies::WARN
128 this->DefinePolicy(
129 CMP0002, "CMP0002",
130 "Logical target names must be globally unique.",
131 "Targets names created with "
132 "add_executable, add_library, or add_custom_target "
133 "are logical build target names. "
134 "Logical target names must be globally unique because:\n"
135 " - Unique names may be referenced unambiguously both in CMake\n"
136 " code and on make tool command lines.\n"
137 " - Logical names are used by Xcode and VS IDE generators\n"
138 " to produce meaningful project names for the targets.\n"
139 "The logical name of executable and library targets does not "
140 "have to correspond to the physical file names built. "
141 "Consider using the OUTPUT_NAME target property to create two "
142 "targets with the same physical name while keeping logical "
143 "names distinct. "
144 "Custom targets must simply have globally unique names (unless one "
145 "uses the global property ALLOW_DUPLICATE_CUSTOM_TARGETS with a "
146 "Makefiles generator).",
147 2,6,0, cmPolicies::WARN
150 this->DefinePolicy(
151 CMP0003, "CMP0003",
152 "Libraries linked via full path no longer produce linker search paths.",
153 "This policy affects how libraries whose full paths are NOT known "
154 "are found at link time, but was created due to a change in how CMake "
155 "deals with libraries whose full paths are known. "
156 "Consider the code\n"
157 " target_link_libraries(myexe /path/to/libA.so)\n"
158 "CMake 2.4 and below implemented linking to libraries whose full paths "
159 "are known by splitting them on the link line into separate components "
160 "consisting of the linker search path and the library name. "
161 "The example code might have produced something like\n"
162 " ... -L/path/to -lA ...\n"
163 "in order to link to library A. "
164 "An analysis was performed to order multiple link directories such that "
165 "the linker would find library A in the desired location, but there "
166 "are cases in which this does not work. "
167 "CMake versions 2.6 and above use the more reliable approach of passing "
168 "the full path to libraries directly to the linker in most cases. "
169 "The example code now produces something like\n"
170 " ... /path/to/libA.so ....\n"
171 "Unfortunately this change can break code like\n"
172 " target_link_libraries(myexe /path/to/libA.so B)\n"
173 "where \"B\" is meant to find \"/path/to/libB.so\". "
174 "This code is wrong because the user is asking the linker to find "
175 "library B but has not provided a linker search path (which may be "
176 "added with the link_directories command). "
177 "However, with the old linking implementation the code would work "
178 "accidentally because the linker search path added for library A "
179 "allowed library B to be found."
180 "\n"
181 "In order to support projects depending on linker search paths "
182 "added by linking to libraries with known full paths, the OLD "
183 "behavior for this policy will add the linker search paths even "
184 "though they are not needed for their own libraries. "
185 "When this policy is set to OLD, CMake will produce a link line such as\n"
186 " ... -L/path/to /path/to/libA.so -lB ...\n"
187 "which will allow library B to be found as it was previously. "
188 "When this policy is set to NEW, CMake will produce a link line such as\n"
189 " ... /path/to/libA.so -lB ...\n"
190 "which more accurately matches what the project specified."
191 "\n"
192 "The setting for this policy used when generating the link line is that "
193 "in effect when the target is created by an add_executable or "
194 "add_library command. For the example described above, the code\n"
195 " cmake_policy(SET CMP0003 OLD) # or cmake_policy(VERSION 2.4)\n"
196 " add_executable(myexe myexe.c)\n"
197 " target_link_libraries(myexe /path/to/libA.so B)\n"
198 "will work and suppress the warning for this policy. "
199 "It may also be updated to work with the corrected linking approach:\n"
200 " cmake_policy(SET CMP0003 NEW) # or cmake_policy(VERSION 2.6)\n"
201 " link_directories(/path/to) # needed to find library B\n"
202 " add_executable(myexe myexe.c)\n"
203 " target_link_libraries(myexe /path/to/libA.so B)\n"
204 "Even better, library B may be specified with a full path:\n"
205 " add_executable(myexe myexe.c)\n"
206 " target_link_libraries(myexe /path/to/libA.so /path/to/libB.so)\n"
207 "When all items on the link line have known paths CMake does not check "
208 "this policy so it has no effect.",
209 2,6,0, cmPolicies::WARN);
211 this->DefinePolicy(
212 CMP0004, "CMP0004",
213 "Libraries linked may not have leading or trailing whitespace.",
214 "CMake versions 2.4 and below silently removed leading and trailing "
215 "whitespace from libraries linked with code like\n"
216 " target_link_libraries(myexe \" A \")\n"
217 "This could lead to subtle errors in user projects.\n"
218 "The OLD behavior for this policy is to silently remove leading and "
219 "trailing whitespace. "
220 "The NEW behavior for this policy is to diagnose the existence of "
221 "such whitespace as an error. "
222 "The setting for this policy used when checking the library names is "
223 "that in effect when the target is created by an add_executable or "
224 "add_library command.",
225 2,6,0, cmPolicies::WARN);
227 this->DefinePolicy(
228 CMP0005, "CMP0005",
229 "Preprocessor definition values are now escaped automatically.",
230 "This policy determines whether or not CMake should generate escaped "
231 "preprocessor definition values added via add_definitions. "
232 "CMake versions 2.4 and below assumed that only trivial values would "
233 "be given for macros in add_definitions calls. "
234 "It did not attempt to escape non-trivial values such as string "
235 "literals in generated build rules. "
236 "CMake versions 2.6 and above support escaping of most values, but "
237 "cannot assume the user has not added escapes already in an attempt to "
238 "work around limitations in earlier versions.\n"
239 "The OLD behavior for this policy is to place definition values given "
240 "to add_definitions directly in the generated build rules without "
241 "attempting to escape anything. "
242 "The NEW behavior for this policy is to generate correct escapes "
243 "for all native build tools automatically. "
244 "See documentation of the COMPILE_DEFINITIONS target property for "
245 "limitations of the escaping implementation.",
246 2,6,0, cmPolicies::WARN);
249 cmPolicies::~cmPolicies()
251 // free the policies
252 std::map<cmPolicies::PolicyID,cmPolicy *>::iterator i
253 = this->Policies.begin();
254 for (;i != this->Policies.end(); ++i)
256 delete i->second;
260 void cmPolicies::DefinePolicy(cmPolicies::PolicyID iD,
261 const char *idString,
262 const char *shortDescription,
263 const char *longDescription,
264 unsigned int majorVersionIntroduced,
265 unsigned int minorVersionIntroduced,
266 unsigned int patchVersionIntroduced,
267 cmPolicies::PolicyStatus status)
269 // a policy must be unique and can only be defined once
270 if (this->Policies.find(iD) != this->Policies.end())
272 cmSystemTools::Error("Attempt to redefine a CMake policy for policy "
273 "ID ", this->GetPolicyIDString(iD).c_str());
274 return;
277 this->Policies[iD] = new cmPolicy(iD, idString,
278 shortDescription,
279 longDescription,
280 majorVersionIntroduced,
281 minorVersionIntroduced,
282 patchVersionIntroduced,
283 status);
284 this->PolicyStringMap[idString] = iD;
287 bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
288 const char *version)
290 std::string ver = "2.4.0";
292 if (version && strlen(version) > 0)
294 ver = version;
297 unsigned int majorVer = 2;
298 unsigned int minorVer = 0;
299 unsigned int patchVer = 0;
301 // parse the string
302 if(sscanf(ver.c_str(), "%u.%u.%u",
303 &majorVer, &minorVer, &patchVer) < 2)
305 return false;
308 // it is an error if the policy version is less than 2.4
309 if (majorVer < 2 || majorVer == 2 && minorVer < 4)
311 mf->IssueMessage(cmake::FATAL_ERROR,
312 "An attempt was made to set the policy version of CMake to something "
313 "earlier than \"2.4\". "
314 "In CMake 2.4 and below backwards compatibility was handled with the "
315 "CMAKE_BACKWARDS_COMPATIBILITY variable. "
316 "In order to get compatibility features supporting versions earlier "
317 "than 2.4 set policy CMP0001 to OLD to tell CMake to check the "
318 "CMAKE_BACKWARDS_COMPATIBILITY variable. "
319 "One way to so this is to set the policy version to 2.4 exactly."
323 // now loop over all the policies and set them as appropriate
324 std::map<cmPolicies::PolicyID,cmPolicy *>::iterator i
325 = this->Policies.begin();
326 for (;i != this->Policies.end(); ++i)
328 if (i->second->IsPolicyNewerThan(majorVer,minorVer,patchVer))
330 if (!mf->SetPolicy(i->second->ID, cmPolicies::WARN))
332 return false;
335 else
337 if (!mf->SetPolicy(i->second->ID, cmPolicies::NEW))
339 return false;
343 return true;
346 // is this a valid status the listfile can set this policy to?
347 bool cmPolicies::IsValidPolicyStatus(cmPolicies::PolicyID id,
348 cmPolicies::PolicyStatus status)
350 // if they are setting a feature to anything other than OLD or WARN and the
351 // feature is not known about then that is an error
352 if (this->Policies.find(id) == this->Policies.end())
354 if (status == cmPolicies::WARN ||
355 status == cmPolicies::OLD)
357 return true;
359 cmOStringStream error;
360 error <<
361 "Error: an attempt was made to enable the new behavior for " <<
362 "a new feature that is in a later version of CMake than "
363 "what you are runing, please upgrade to a newer version "
364 "of CMake.";
365 cmSystemTools::Error(error.str().c_str());
366 return false;
369 // now we know the feature is defined, so the only issue is if someone is
370 // setting it to WARN or OLD when the feature is REQUIRED_ALWAYS
371 if ((status == cmPolicies::WARN ||
372 status == cmPolicies::OLD) &&
373 this->Policies[id]->Status == cmPolicies::REQUIRED_ALWAYS)
375 cmOStringStream error;
376 error <<
377 "Error: an attempt was made to enable the old behavior for " <<
378 "a feature that is no longer supported. The feature in " <<
379 "question is feature " <<
380 id <<
381 " which had new behavior introduced in CMake version " <<
382 this->Policies[id]->GetVersionString() <<
383 " please either update your CMakeLists files to conform to " <<
384 "the new behavior " <<
385 "or use an older version of CMake that still supports " <<
386 "the old behavior. Run cmake --help-policies " <<
387 id << " for more information.";
388 cmSystemTools::Error(error.str().c_str());
389 return false;
392 return true;
395 // is this a valid status the listfile can set this policy to?
396 bool cmPolicies::IsValidUsedPolicyStatus(cmPolicies::PolicyID id,
397 cmPolicies::PolicyStatus status)
399 // if they are setting a feature to anything other than OLD or WARN and the
400 // feature is not known about then that is an error
401 if (this->Policies.find(id) == this->Policies.end())
403 if (status == cmPolicies::WARN ||
404 status == cmPolicies::OLD)
406 return true;
408 cmOStringStream error;
409 error <<
410 "Error: an attempt was made to enable the new behavior for " <<
411 "a new feature that is in a later version of CMake than "
412 "what you are runing, please upgrade to a newer version "
413 "of CMake.";
414 cmSystemTools::Error(error.str().c_str());
415 return false;
418 // now we know the feature is defined, so the only issue is if someone is
419 // setting it to WARN or OLD when the feature is REQUIRED_ALWAYS
420 if ((status == cmPolicies::WARN ||
421 status == cmPolicies::OLD) &&
422 (this->Policies[id]->Status == cmPolicies::REQUIRED_ALWAYS ||
423 this->Policies[id]->Status == cmPolicies::REQUIRED_IF_USED))
425 cmOStringStream error;
426 error <<
427 "Error: an attempt was made to enable the old behavior for " <<
428 "a feature that is no longer supported. The feature in " <<
429 "question is feature " <<
430 id <<
431 " which had new behavior introduced in CMake version " <<
432 this->Policies[id]->GetVersionString() <<
433 " please either update your CMakeLists files to conform to " <<
434 "the new behavior " <<
435 "or use an older version of CMake that still supports " <<
436 "the old behavior. Run cmake --help-policies " <<
437 id << " for more information.";
438 cmSystemTools::Error(error.str().c_str());
439 return false;
442 return true;
445 bool cmPolicies::GetPolicyID(const char *id, cmPolicies::PolicyID &pid)
447 if (!id || strlen(id) < 1)
449 return false;
451 std::map<std::string,cmPolicies::PolicyID>::iterator pos =
452 this->PolicyStringMap.find(id);
453 if (pos == this->PolicyStringMap.end())
455 return false;
457 pid = pos->second;
458 return true;
461 std::string cmPolicies::GetPolicyIDString(cmPolicies::PolicyID pid)
463 std::map<cmPolicies::PolicyID,cmPolicy *>::iterator pos =
464 this->Policies.find(pid);
465 if (pos == this->Policies.end())
467 return "";
469 return pos->second->IDString;
473 ///! return a warning string for a given policy
474 std::string cmPolicies::GetPolicyWarning(cmPolicies::PolicyID id)
476 std::map<cmPolicies::PolicyID,cmPolicy *>::iterator pos =
477 this->Policies.find(id);
478 if (pos == this->Policies.end())
480 cmSystemTools::Error(
481 "Request for warning text for undefined policy!");
482 return "Request for warning text for undefined policy!";
485 cmOStringStream msg;
486 msg <<
487 "Policy " << pos->second->IDString << " is not set: "
488 "" << pos->second->ShortDescription << " "
489 "Run \"cmake --help-policy " << pos->second->IDString << "\" for "
490 "policy details. "
491 "Use the cmake_policy command to set the policy "
492 "and suppress this warning.";
493 return msg.str();
497 ///! return an error string for when a required policy is unspecified
498 std::string cmPolicies::GetRequiredPolicyError(cmPolicies::PolicyID id)
500 std::map<cmPolicies::PolicyID,cmPolicy *>::iterator pos =
501 this->Policies.find(id);
502 if (pos == this->Policies.end())
504 cmSystemTools::Error(
505 "Request for error text for undefined policy!");
506 return "Request for warning text for undefined policy!";
509 cmOStringStream error;
510 error <<
511 "Policy " << pos->second->IDString << " is not set to NEW: "
512 "" << pos->second->ShortDescription << " "
513 "Run \"cmake --help-policy " << pos->second->IDString << "\" for "
514 "policy details. "
515 "CMake now requires this policy to be set to NEW by the project. "
516 "The policy may be set explicitly using the code\n"
517 " cmake_policy(SET " << pos->second->IDString << " NEW)\n"
518 "or by upgrading all policies with the code\n"
519 " cmake_policy(VERSION " << pos->second->GetVersionString() <<
520 ") # or later\n"
521 "Run \"cmake --help-command cmake_policy\" for more information.";
522 return error.str();
525 ///! Get the default status for a policy
526 cmPolicies::PolicyStatus
527 cmPolicies::GetPolicyStatus(cmPolicies::PolicyID id)
529 // if the policy is not know then what?
530 std::map<cmPolicies::PolicyID,cmPolicy *>::iterator pos =
531 this->Policies.find(id);
532 if (pos == this->Policies.end())
534 // TODO is this right?
535 return cmPolicies::WARN;
538 return pos->second->Status;
541 void cmPolicies::GetDocumentation(std::vector<cmDocumentationEntry>& v)
543 // now loop over all the policies and set them as appropriate
544 std::map<cmPolicies::PolicyID,cmPolicy *>::iterator i
545 = this->Policies.begin();
546 for (;i != this->Policies.end(); ++i)
548 cmOStringStream full;
549 full << i->second->LongDescription;
550 full << "\nThis policy was introduced in CMake version ";
551 full << i->second->GetVersionString() << ". ";
552 full << "CMake version " << cmVersion::GetMajorVersion()
553 << "." << cmVersion::GetMinorVersion() << " ";
554 // add in some more text here based on status
555 switch (i->second->Status)
557 case cmPolicies::WARN:
558 full << "defaults to WARN for this policy. "
559 << "Use the cmake_policy command to set it to OLD or NEW.";
560 break;
561 case cmPolicies::OLD:
562 full << "defaults to the OLD behavior for this policy.";
563 break;
564 case cmPolicies::NEW:
565 full << "defaults to the NEW behavior for this policy.";
566 break;
567 case cmPolicies::REQUIRED_IF_USED:
568 full << "requires the policy to be set to NEW if you use it. "
569 << "Use the cmake_policy command to set it to NEW.";
570 break;
571 case cmPolicies::REQUIRED_ALWAYS:
572 full << "requires the policy to be set to NEW. "
573 << "Use the cmake_policy command to set it to NEW.";
574 break;
577 cmDocumentationEntry e(i->second->IDString.c_str(),
578 i->second->ShortDescription.c_str(),
579 full.str().c_str());
580 v.push_back(e);