[Cmake-commits] [cmake-commits] king committed cmComputeLinkInformation.cxx 1.24 1.25 cmComputeLinkInformation.h 1.15 1.16 cmDocumentVariables.cxx 1.18 1.19 cmPolicies.cxx 1.20 1.21 cmPolicies.h 1.10 1.11 cmTarget.cxx 1.207 1.208 cmTarget.h 1.109 1.110
cmake-commits at cmake.org
cmake-commits at cmake.org
Thu Mar 13 16:23:20 EDT 2008
Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv16290/Source
Modified Files:
cmComputeLinkInformation.cxx cmComputeLinkInformation.h
cmDocumentVariables.cxx cmPolicies.cxx cmPolicies.h
cmTarget.cxx cmTarget.h
Log Message:
ENH: Convert CMAKE_LINK_OLD_PATHS to policy CMP0003.
- Policy is WARN by default so projects will build
as they did in 2.4 without user intervention
- Remove CMAKE_LINK_OLD_PATHS variable since it was
never in a release and the policy supercedes it
- Report target creation backtrace in warning message
since policy should be set by that point
Index: cmPolicies.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmPolicies.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -C 2 -d -r1.10 -r1.11
*** cmPolicies.h 13 Mar 2008 15:38:46 -0000 1.10
--- cmPolicies.h 13 Mar 2008 20:23:18 -0000 1.11
***************
*** 44,47 ****
--- 44,48 ----
CMP0001, // Ignore old compatibility variable
CMP0002, // Target names must be unique
+ CMP0003, // Linking does not include extra -L paths
// Always the last entry. Useful mostly to avoid adding a comma
Index: cmPolicies.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmPolicies.cxx,v
retrieving revision 1.20
retrieving revision 1.21
diff -C 2 -d -r1.20 -r1.21
*** cmPolicies.cxx 13 Mar 2008 19:01:58 -0000 1.20
--- cmPolicies.cxx 13 Mar 2008 20:23:18 -0000 1.21
***************
*** 140,143 ****
--- 140,204 ----
2,6,0, cmPolicies::WARN
);
+
+ this->DefinePolicy(
+ CMP0003, "CMP0003",
+ "Libraries linked via full path no longer produce linker search paths.",
+ "This policy affects how libraries whose full paths are NOT known "
+ "are found at link time, but was created due to a change in how CMake "
+ "deals with libraries whose full paths are known. "
+ "Consider the code\n"
+ " target_link_libraries(myexe /path/to/libA.so)\n"
+ "CMake 2.4 and below implemented linking to libraries whose full paths "
+ "are known by splitting them on the link line into separate components "
+ "consisting of the linker search path and the library name. "
+ "The example code might have produced something like\n"
+ " ... -L/path/to -lA ...\n"
+ "in order to link to library A. "
+ "An analysis was performed to order multiple link directories such that "
+ "the linker would find library A in the desired location, but there "
+ "are cases in which this does not work. "
+ "CMake versions 2.6 and above use the more reliable approach of passing "
+ "the full path to libraries directly to the linker in most cases. "
+ "The example code now produces something like\n"
+ " ... /path/to/libA.so ....\n"
+ "Unfortunately this change can break code like\n"
+ " target_link_libraries(myexe /path/to/libA.so B)\n"
+ "where \"B\" is meant to find \"/path/to/libB.so\". "
+ "This code is wrong because the user is asking the linker to find "
+ "library B but has not provided a linker search path (which may be "
+ "added with the link_directories command). "
+ "However, with the old linking implementation the code would work "
+ "accidentally because the linker search path added for library A "
+ "allowed library B to be found."
+ "\n"
+ "In order to support projects depending on linker search paths "
+ "added by linking to libraries with known full paths, the OLD "
+ "behavior for this policy will add the linker search paths even "
+ "though they are not needed for their own libraries. "
+ "When this policy is set to OLD, CMake will produce a link line such as\n"
+ " ... -L/path/to /path/to/libA.so -lB ...\n"
+ "which will allow library B to be found as it was previously. "
+ "When this policy is set to NEW, CMake will produce a link line such as\n"
+ " ... /path/to/libA.so -lB ...\n"
+ "which more accurately matches what the project specified."
+ "\n"
+ "The setting for this policy used when generating the link line is that "
+ "in effect when the target is created by an add_executable or "
+ "add_library command. For the example described above, the code\n"
+ " cmake_policy(SET CMP0003 OLD) # or cmake_policy(VERSION 2.4)\n"
+ " add_executable(myexe myexe.c)\n"
+ " target_link_libraries(myexe /path/to/libA.so B)\n"
+ "will work and suppress the warning for this policy. "
+ "It may also be updated to work with the corrected linking approach:\n"
+ " cmake_policy(SET CMP0003 NEW) # or cmake_policy(VERSION 2.6)\n"
+ " link_directories(/path/to) # needed to find library B\n"
+ " add_executable(myexe myexe.c)\n"
+ " target_link_libraries(myexe /path/to/libA.so B)\n"
+ "Even better, library B may be specified with a full path:\n"
+ " add_executable(myexe myexe.c)\n"
+ " target_link_libraries(myexe /path/to/libA.so /path/to/libB.so)\n"
+ "When all items on the link line have known paths CMake does not check "
+ "this policy so it has no effect.",
+ 2,6,0, cmPolicies::WARN);
}
Index: cmComputeLinkInformation.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmComputeLinkInformation.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -C 2 -d -r1.15 -r1.16
*** cmComputeLinkInformation.h 1 Mar 2008 17:51:07 -0000 1.15
--- cmComputeLinkInformation.h 13 Mar 2008 20:23:18 -0000 1.16
***************
*** 154,164 ****
// Linker search path computation.
cmOrderDirectories* OrderLinkerSearchPath;
! void FinishLinkerSearchDirectories();
std::set<cmStdString> ImplicitLinkDirs;
// Linker search path compatibility mode.
std::vector<std::string> OldLinkDirItems;
bool OldLinkDirMode;
- bool HaveUserFlagItem;
// Runtime path computation.
--- 154,166 ----
// Linker search path computation.
cmOrderDirectories* OrderLinkerSearchPath;
! bool FinishLinkerSearchDirectories();
! void PrintLinkPolicyDiagnosis(std::ostream&);
std::set<cmStdString> ImplicitLinkDirs;
// Linker search path compatibility mode.
+ std::set<cmStdString> OldLinkDirMask;
std::vector<std::string> OldLinkDirItems;
+ std::vector<std::string> OldUserFlagItems;
bool OldLinkDirMode;
// Runtime path computation.
Index: cmComputeLinkInformation.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmComputeLinkInformation.cxx,v
retrieving revision 1.24
retrieving revision 1.25
diff -C 2 -d -r1.24 -r1.25
*** cmComputeLinkInformation.cxx 2 Mar 2008 19:35:23 -0000 1.24
--- cmComputeLinkInformation.cxx 13 Mar 2008 20:23:18 -0000 1.25
***************
*** 397,403 ****
}
- // Initial state.
- this->HaveUserFlagItem = false;
-
// Decide whether to enable compatible library search path mode.
// There exists code that effectively does
--- 397,400 ----
***************
*** 411,420 ****
// order to support such projects we need to add the directories
// containing libraries linked with a full path to the -L path.
! this->OldLinkDirMode = false;
! if(this->Makefile->IsOn("CMAKE_LINK_OLD_PATHS") ||
! this->Makefile->GetLocalGenerator()
! ->NeedBackwardsCompatibility(2, 4))
{
! this->OldLinkDirMode = true;
}
}
--- 408,423 ----
// order to support such projects we need to add the directories
// containing libraries linked with a full path to the -L path.
! this->OldLinkDirMode =
! this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
! if(this->OldLinkDirMode)
{
! // Construct a mask to not bother with this behavior for link
! // directories already specified by the user.
! std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
! for(std::vector<std::string>::const_iterator di = dirs.begin();
! di != dirs.end(); ++di)
! {
! this->OldLinkDirMask.insert(*di);
! }
}
}
***************
*** 538,542 ****
// Finish setting up linker search directories.
! this->FinishLinkerSearchDirectories();
return true;
--- 541,548 ----
// Finish setting up linker search directories.
! if(!this->FinishLinkerSearchDirectories())
! {
! return false;
! }
return true;
***************
*** 1038,1042 ****
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
! if(this->OldLinkDirMode)
{
this->OldLinkDirItems.push_back(item);
--- 1044,1050 ----
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
! if(this->OldLinkDirMode &&
! this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
! this->OldLinkDirMask.end())
{
this->OldLinkDirItems.push_back(item);
***************
*** 1162,1166 ****
{
// This is a linker option provided by the user.
! this->HaveUserFlagItem = true;
// Restore the target link type since this item does not specify
--- 1170,1174 ----
{
// This is a linker option provided by the user.
! this->OldUserFlagItems.push_back(item);
// Restore the target link type since this item does not specify
***************
*** 1175,1179 ****
{
// This is a name specified by the user.
! this->HaveUserFlagItem = true;
// We must ask the linker to search for a library with this name.
--- 1183,1187 ----
{
// This is a name specified by the user.
! this->OldUserFlagItems.push_back(item);
// We must ask the linker to search for a library with this name.
***************
*** 1305,1320 ****
//----------------------------------------------------------------------------
! void cmComputeLinkInformation::FinishLinkerSearchDirectories()
{
// Support broken projects if necessary.
! if(this->HaveUserFlagItem && this->OldLinkDirMode)
{
! for(std::vector<std::string>::const_iterator
! i = this->OldLinkDirItems.begin();
! i != this->OldLinkDirItems.end(); ++i)
{
! this->OrderLinkerSearchPath->AddLinkLibrary(*i);
}
}
}
--- 1313,1425 ----
//----------------------------------------------------------------------------
! bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
{
// Support broken projects if necessary.
! if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
! !this->OldLinkDirMode)
{
! return true;
! }
!
! // Enforce policy constraints.
! switch(this->Target->GetPolicyStatusCMP0003())
! {
! case cmPolicies::WARN:
{
! cmOStringStream w;
! w << (this->Makefile->GetPolicies()
! ->GetPolicyWarning(cmPolicies::CMP0003)) << "\n";
! this->PrintLinkPolicyDiagnosis(w);
! this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
! this->Target->GetBacktrace());
}
+ case cmPolicies::OLD:
+ // OLD behavior is to add the paths containing libraries with
+ // known full paths as link directories.
+ break;
+ case cmPolicies::NEW:
+ // Should never happen due to assignment of OldLinkDirMode
+ return true;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ {
+ cmOStringStream e;
+ e << (this->Makefile->GetPolicies()->
+ GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
+ this->PrintLinkPolicyDiagnosis(e);
+ this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+ return false;
+ }
+ break;
+ }
+
+ // Add the link directories for full path items.
+ for(std::vector<std::string>::const_iterator
+ i = this->OldLinkDirItems.begin();
+ i != this->OldLinkDirItems.end(); ++i)
+ {
+ this->OrderLinkerSearchPath->AddLinkLibrary(*i);
+ }
+ return true;
+ }
+
+ //----------------------------------------------------------------------------
+ void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
+ {
+ // Name the target.
+ os << "Target \"" << this->Target->GetName() << "\" ";
+
+ // List the items that would add paths in old behavior.
+ os << " links to some items with known full path:\n";
+ for(std::vector<std::string>::const_iterator
+ i = this->OldLinkDirItems.begin();
+ i != this->OldLinkDirItems.end(); ++i)
+ {
+ os << " " << *i << "\n";
+ }
+
+ // List the items that might need the old-style paths.
+ os << "and to some items with no path known:\n";
+ {
+ // Format the list of unknown items to be as short as possible while
+ // still fitting in the allowed width (a true solution would be the
+ // bin packing problem if we were allowed to change the order).
+ std::string::size_type max_size = 76;
+ std::string line;
+ const char* sep = " ";
+ for(std::vector<std::string>::const_iterator
+ i = this->OldUserFlagItems.begin();
+ i != this->OldUserFlagItems.end(); ++i)
+ {
+ // If the addition of another item will exceed the limit then
+ // output the current line and reset it. Note that the separator
+ // is either " " or ", " which is always 2 characters.
+ if(!line.empty() && (line.size() + i->size() + 2) > max_size)
+ {
+ os << line << "\n";
+ sep = " ";
+ line = "";
+ }
+ line += sep;
+ line += *i;
+
+ // Convert to the other separator.
+ sep = ", ";
}
+ if(!line.empty())
+ {
+ os << line << "\n";
+ }
+ }
+
+ // Tell the user what is wrong.
+ os << "The linker will search for libraries in the second list. "
+ << "Finding them may depend on linker search paths earlier CMake "
+ << "versions added as an implementation detail for linking to the "
+ << "libraries in the first list. "
+ << "For compatibility CMake is including the extra linker search "
+ << "paths, but policy CMP0003 should be set by the project.";
}
Index: cmDocumentVariables.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDocumentVariables.cxx,v
retrieving revision 1.18
retrieving revision 1.19
diff -C 2 -d -r1.18 -r1.19
*** cmDocumentVariables.cxx 4 Mar 2008 14:40:38 -0000 1.18
--- cmDocumentVariables.cxx 13 Mar 2008 20:23:18 -0000 1.19
***************
*** 785,806 ****
"Variables that Control the Build");
cm->DefineProperty
- ("CMAKE_LINK_OLD_PATHS", cmProperty::VARIABLE,
- "Enable linker search path compatibility mode.",
- "This option enables linking compatibility mode for broken projects. "
- "There exists code that effectively does\n"
- " target_link_libraries(myexe /path/to/libA.so -lB)\n"
- "where -lB is meant to link to /path/to/libB.so. This is broken "
- "because it specifies -lB without adding \"/path/to\" to the linker "
- "search path with the link_directories command. With CMake 2.4 and "
- "below the code worked accidentally because \"/path/to\" would be "
- "added to the linker search path by its implementation of linking to "
- "/path/to/libA.so (which passed -L/path/to -lA to the linker). "
- "This option tells CMake to add the directories containing libraries "
- "specified with a full path to the linker search path if the link "
- "line contains any items like -lB. "
- "The behavior is also enabled if CMAKE_BACKWARDS_COMPATIBILITY is "
- "set to 2.4 or lower.", false,
- "Variables that Control the Build");
- cm->DefineProperty
("CMAKE_USE_RELATIVE_PATHS", cmProperty::VARIABLE,
"Use relative paths (May not work!).",
--- 785,788 ----
Index: cmTarget.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.h,v
retrieving revision 1.109
retrieving revision 1.110
diff -C 2 -d -r1.109 -r1.110
*** cmTarget.h 13 Mar 2008 17:48:57 -0000 1.109
--- cmTarget.h 13 Mar 2008 20:23:18 -0000 1.110
***************
*** 20,23 ****
--- 20,24 ----
#include "cmCustomCommand.h"
#include "cmPropertyMap.h"
+ #include "cmPolicies.h"
class cmake;
***************
*** 106,109 ****
--- 107,114 ----
cmMakefile *GetMakefile() const { return this->Makefile;};
+ /** Get the status of policy CMP0003 when the target was created. */
+ cmPolicies::PolicyStatus GetPolicyStatusCMP0003() const
+ { return this->PolicyStatusCMP0003; }
+
/**
* Get the list of the custom commands for this target
***************
*** 531,534 ****
--- 536,542 ----
cmMakefile* Makefile;
+ // Policy status recorded when target was created.
+ cmPolicies::PolicyStatus PolicyStatusCMP0003;
+
// Internal representation details.
friend class cmTargetInternals;
Index: cmTarget.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.cxx,v
retrieving revision 1.207
retrieving revision 1.208
diff -C 2 -d -r1.207 -r1.208
*** cmTarget.cxx 13 Mar 2008 17:48:57 -0000 1.207
--- cmTarget.cxx 13 Mar 2008 20:23:18 -0000 1.208
***************
*** 54,57 ****
--- 54,58 ----
{
this->Makefile = 0;
+ this->PolicyStatusCMP0003 = cmPolicies::WARN;
this->LinkLibrariesAnalyzed = false;
this->HaveInstallRule = false;
***************
*** 727,730 ****
--- 728,735 ----
// Save the backtrace of target construction.
this->Makefile->GetBacktrace(this->Internal->Backtrace);
+
+ // Record current policies for later use.
+ this->PolicyStatusCMP0003 =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0003);
}
More information about the Cmake-commits
mailing list