|
|
@@ -396,9 +396,6 @@ cmComputeLinkInformation
|
|
|
->SetImplicitDirectories(this->ImplicitLinkDirs);
|
|
|
}
|
|
|
|
|
|
- // Initial state.
|
|
|
- this->HaveUserFlagItem = false;
|
|
|
-
|
|
|
// Decide whether to enable compatible library search path mode.
|
|
|
// There exists code that effectively does
|
|
|
//
|
|
|
@@ -410,12 +407,18 @@ cmComputeLinkInformation
|
|
|
// because -L/path/to would be added by the -L/-l split for A. In
|
|
|
// 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 =
|
|
|
+ this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
|
|
|
+ if(this->OldLinkDirMode)
|
|
|
{
|
|
|
- this->OldLinkDirMode = true;
|
|
|
+ // 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);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -537,7 +540,10 @@ bool cmComputeLinkInformation::Compute()
|
|
|
}
|
|
|
|
|
|
// Finish setting up linker search directories.
|
|
|
- this->FinishLinkerSearchDirectories();
|
|
|
+ if(!this->FinishLinkerSearchDirectories())
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
@@ -1037,7 +1043,9 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item)
|
|
|
|
|
|
// For compatibility with CMake 2.4 include the item's directory in
|
|
|
// the linker search path.
|
|
|
- if(this->OldLinkDirMode)
|
|
|
+ if(this->OldLinkDirMode &&
|
|
|
+ this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
|
|
|
+ this->OldLinkDirMask.end())
|
|
|
{
|
|
|
this->OldLinkDirItems.push_back(item);
|
|
|
}
|
|
|
@@ -1161,7 +1169,7 @@ void cmComputeLinkInformation::AddUserItem(std::string const& item)
|
|
|
else if(item[0] == '-' || item[0] == '$' || item[0] == '`')
|
|
|
{
|
|
|
// This is a linker option provided by the user.
|
|
|
- this->HaveUserFlagItem = true;
|
|
|
+ this->OldUserFlagItems.push_back(item);
|
|
|
|
|
|
// Restore the target link type since this item does not specify
|
|
|
// one.
|
|
|
@@ -1174,7 +1182,7 @@ void cmComputeLinkInformation::AddUserItem(std::string const& item)
|
|
|
else
|
|
|
{
|
|
|
// This is a name specified by the user.
|
|
|
- this->HaveUserFlagItem = true;
|
|
|
+ this->OldUserFlagItems.push_back(item);
|
|
|
|
|
|
// We must ask the linker to search for a library with this name.
|
|
|
// Restore the target link type since this item does not specify
|
|
|
@@ -1304,18 +1312,115 @@ void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
-void cmComputeLinkInformation::FinishLinkerSearchDirectories()
|
|
|
+bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
|
|
|
{
|
|
|
// Support broken projects if necessary.
|
|
|
- if(this->HaveUserFlagItem && this->OldLinkDirMode)
|
|
|
+ if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
|
|
|
+ !this->OldLinkDirMode)
|
|
|
{
|
|
|
- for(std::vector<std::string>::const_iterator
|
|
|
- i = this->OldLinkDirItems.begin();
|
|
|
- i != this->OldLinkDirItems.end(); ++i)
|
|
|
+ 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)
|
|
|
{
|
|
|
- this->OrderLinkerSearchPath->AddLinkLibrary(*i);
|
|
|
+ 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.";
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|