1 #include "cmPolicies.h"
3 #include "cmMakefile.h"
4 #include "cmSourceFile.h"
11 const char* cmPolicies::PolicyStatusNames
[] = {
12 "OLD", "WARN", "NEW", "REQUIRED_IF_USED", "REQUIRED_ALWAYS"
18 cmPolicy(cmPolicies::PolicyID iD
,
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!");
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
;
52 bool IsPolicyNewerThan(unsigned int majorV
,
56 if (majorV
< this->MajorVersionIntroduced
)
60 if (majorV
> this->MajorVersionIntroduced
)
64 if (minorV
< this->MinorVersionIntroduced
)
68 if (minorV
> this->MinorVersionIntroduced
)
72 return (patchV
< this->PatchVersionIntroduced
);
75 cmPolicies::PolicyID ID
;
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
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 "
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
114 "CMAKE_BACKWARDS_COMPATIBILITY should no longer be used.",
115 "The OLD behavior is to check CMAKE_BACKWARDS_COMPATIBILITY and present "
117 "The NEW behavior is to ignore CMAKE_BACKWARDS_COMPATIBILITY "
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
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 "
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
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."
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."
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
);
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
);
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()
252 std::map
<cmPolicies::PolicyID
,cmPolicy
*>::iterator i
253 = this->Policies
.begin();
254 for (;i
!= this->Policies
.end(); ++i
)
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());
277 this->Policies
[iD
] = new cmPolicy(iD
, idString
,
280 majorVersionIntroduced
,
281 minorVersionIntroduced
,
282 patchVersionIntroduced
,
284 this->PolicyStringMap
[idString
] = iD
;
287 bool cmPolicies::ApplyPolicyVersion(cmMakefile
*mf
,
290 std::string ver
= "2.4.0";
292 if (version
&& strlen(version
) > 0)
297 unsigned int majorVer
= 2;
298 unsigned int minorVer
= 0;
299 unsigned int patchVer
= 0;
302 if(sscanf(ver
.c_str(), "%u.%u.%u",
303 &majorVer
, &minorVer
, &patchVer
) < 2)
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
))
337 if (!mf
->SetPolicy(i
->second
->ID
, cmPolicies::NEW
))
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
)
359 cmOStringStream 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 "
365 cmSystemTools::Error(error
.str().c_str());
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
;
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 " <<
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());
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
)
408 cmOStringStream 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 "
414 cmSystemTools::Error(error
.str().c_str());
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
;
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 " <<
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());
445 bool cmPolicies::GetPolicyID(const char *id
, cmPolicies::PolicyID
&pid
)
447 if (!id
|| strlen(id
) < 1)
451 std::map
<std::string
,cmPolicies::PolicyID
>::iterator pos
=
452 this->PolicyStringMap
.find(id
);
453 if (pos
== this->PolicyStringMap
.end())
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())
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!";
487 "Policy " << pos
->second
->IDString
<< " is not set: "
488 "" << pos
->second
->ShortDescription
<< " "
489 "Run \"cmake --help-policy " << pos
->second
->IDString
<< "\" for "
491 "Use the cmake_policy command to set the policy "
492 "and suppress this warning.";
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
;
511 "Policy " << pos
->second
->IDString
<< " is not set to NEW: "
512 "" << pos
->second
->ShortDescription
<< " "
513 "Run \"cmake --help-policy " << pos
->second
->IDString
<< "\" for "
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() <<
521 "Run \"cmake --help-command cmake_policy\" for more information.";
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.";
561 case cmPolicies::OLD
:
562 full
<< "defaults to the OLD behavior for this policy.";
564 case cmPolicies::NEW
:
565 full
<< "defaults to the NEW behavior for this policy.";
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.";
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.";
577 cmDocumentationEntry
e(i
->second
->IDString
.c_str(),
578 i
->second
->ShortDescription
.c_str(),