summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmComputeLinkInformation.cxx108
-rw-r--r--Source/cmComputeLinkInformation.h1
-rw-r--r--Source/cmPolicies.cxx26
-rw-r--r--Source/cmPolicies.h1
-rw-r--r--Source/cmTarget.cxx3
-rw-r--r--Source/cmTarget.h5
6 files changed, 104 insertions, 40 deletions
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 9b6837d..af4b141 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -1042,6 +1042,20 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item)
return;
}
+ // Full path libraries should specify a valid library file name.
+ // See documentation of CMP0008.
+ if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
+ (strstr(this->GlobalGenerator->GetName(), "Visual Studio") ||
+ strstr(this->GlobalGenerator->GetName(), "Xcode")))
+ {
+ std::string file = cmSystemTools::GetFilenameName(item);
+ if(!this->ExtractAnyLibraryName.find(file.c_str()))
+ {
+ this->HandleBadFullItem(item, file);
+ return;
+ }
+ }
+
// This is called to handle a link item that is a full path.
// If the target is not a static library make sure the link type is
// shared. This is because dynamic-mode linking can handle both
@@ -1078,47 +1092,8 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item)
this->Items.push_back(Item(this->LibLinkFileFlag, false));
}
- // Full path libraries should have an extension. CMake 2.4 would
- // add the extension after splitting the file off of the directory.
- // Some existing projects depended on this to build correctly
- // because they left off the extension of an otherwise full-path
- // library. This worked with CMake 2.4 but only for VS IDE builds
- // because the file-level dependency added to the Makefile would not
- // be found. Nevertheless, some projects have this mistake but work
- // because they build only with the VS IDE. We need to support them
- // here by adding the missing extension.
- std::string final_item = item;
- if(strstr(this->GlobalGenerator->GetName(), "Visual Studio") &&
- this->Makefile->NeedBackwardsCompatibility(2,4) &&
- !cmSystemTools::ComparePath(
- cmSystemTools::GetFilenameLastExtension(item).c_str(),
- this->LibLinkSuffix.c_str()))
- {
- // Issue the warning at most once.
- std::string wid = "VSIDE-LINK-EXT-";
- wid += item;
- if(!this->Target->GetPropertyAsBool(wid.c_str()))
- {
- this->Target->SetProperty(wid.c_str(), "1");
- cmOStringStream w;
- w << "Target \"" << this->Target->GetName() << "\" links to "
- << "full-path item\n"
- << " " << item << "\n"
- << "which does not have the proper link extension \""
- << this->LibLinkSuffix << "\". "
- << "CMake is adding the missing extension because compatibility "
- << "with CMake 2.4 is currently enabled and this case worked "
- << "accidentally in that version. "
- << "The link extension should be added by the project developer.";
- this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
- }
-
- // Add the missing extension.
- final_item += this->LibLinkSuffix;
- }
-
// Now add the full path to the library.
- this->Items.push_back(Item(final_item, true));
+ this->Items.push_back(Item(item, true));
}
//----------------------------------------------------------------------------
@@ -1384,6 +1359,59 @@ void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
}
//----------------------------------------------------------------------------
+void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
+ std::string const& file)
+{
+ // Tell the linker to search for the item and provide the proper
+ // path for it. Do not contribute to any CMP0003 warning (do not
+ // put in OldLinkDirItems or OldUserFlagItems).
+ this->AddUserItem(file, false);
+ this->OrderLinkerSearchPath->AddLinkLibrary(item);
+
+ // Produce any needed message.
+ switch(this->Target->GetPolicyStatusCMP0008())
+ {
+ case cmPolicies::WARN:
+ {
+ // Print the warning at most once for this item.
+ std::string wid = "CMP0008-WARNING-GIVEN-";
+ wid += item;
+ if(!this->CMakeInstance->GetPropertyAsBool(wid.c_str()))
+ {
+ this->CMakeInstance->SetProperty(wid.c_str(), "1");
+ cmOStringStream w;
+ w << (this->Makefile->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0008)) << "\n"
+ << "Target \"" << this->Target->GetName() << "\" links to item\n"
+ << " " << item << "\n"
+ << "which is a full-path but not a valid library file name.";
+ this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
+ this->Target->GetBacktrace());
+ }
+ }
+ case cmPolicies::OLD:
+ // OLD behavior does not warn.
+ break;
+ case cmPolicies::NEW:
+ // NEW behavior will not get here.
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ {
+ cmOStringStream e;
+ e << (this->Makefile->GetPolicies()->
+ GetRequiredPolicyError(cmPolicies::CMP0008)) << "\n"
+ << "Target \"" << this->Target->GetName() << "\" links to item\n"
+ << " " << item << "\n"
+ << "which is a full-path but not a valid library file name.";
+ this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+ }
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
{
// Support broken projects if necessary.
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index c1f240b..0ce47bf 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -145,6 +145,7 @@ private:
void DropDirectoryItem(std::string const& item);
bool CheckSharedLibNoSOName(std::string const& item);
void AddSharedLibNoSOName(std::string const& item);
+ void HandleBadFullItem(std::string const& item, std::string const& file);
// Framework info.
void ComputeFrameworkInfo();
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 64caf25..1b9ab96 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -281,6 +281,32 @@ cmPolicies::cmPolicies()
"The NEW behavior for this policy is to correctly count empty "
"elements in a list. ",
2,6,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0008, "CMP0008",
+ "Libraries linked by full-path must have a valid library file name.",
+ "In CMake 2.4 and below it is possible to write code like\n"
+ " target_link_libraries(myexe /full/path/to/somelib)\n"
+ "where \"somelib\" is supposed to be a valid library file name "
+ "such as \"libsomelib.a\" or \"somelib.lib\". "
+ "For Makefile generators this produces an error at build time "
+ "because the dependency on the full path cannot be found. "
+ "For VS IDE and Xcode generators this used to work by accident because "
+ "CMake would always split off the library directory and ask the "
+ "linker to search for the library by name (-lsomelib or somelib.lib). "
+ "Despite the failure with Makefiles, some projects have code like this "
+ "and build only with VS and/or Xcode. "
+ "This version of CMake prefers to pass the full path directly to the "
+ "native build tool, which will fail in this case because it does "
+ "not name a valid library file."
+ "\n"
+ "This policy determines what to do with full paths that do not appear "
+ "to name a valid library file. "
+ "The OLD behavior for this policy is to split the library name from the "
+ "path and ask the linker to search for it. "
+ "The NEW behavior for this policy is to trust the given path and "
+ "pass it directly to the native build tool unchanged.",
+ 2,6,1, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 1085d4c..7c9be18 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -48,6 +48,7 @@ public:
CMP0005, // Definition value escaping
CMP0006, // BUNDLE install rules needed for MACOSX_BUNDLE targets
CMP0007, // list command handling of empty elements
+ CMP0008, // Full-path libraries must be a valid library file name
// Always the last entry. Useful mostly to avoid adding a comma
// the last policy when adding a new one.
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 6e81a1a..7d49a0a 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -55,6 +55,7 @@ cmTarget::cmTarget()
this->Makefile = 0;
this->PolicyStatusCMP0003 = cmPolicies::WARN;
this->PolicyStatusCMP0004 = cmPolicies::WARN;
+ this->PolicyStatusCMP0008 = cmPolicies::WARN;
this->LinkLibrariesAnalyzed = false;
this->HaveInstallRule = false;
this->DLLPlatform = false;
@@ -768,6 +769,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->Makefile->GetPolicyStatus(cmPolicies::CMP0003);
this->PolicyStatusCMP0004 =
this->Makefile->GetPolicyStatus(cmPolicies::CMP0004);
+ this->PolicyStatusCMP0008 =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0008);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 8ec2e1f..7141e41 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -114,6 +114,10 @@ public:
cmPolicies::PolicyStatus GetPolicyStatusCMP0004() const
{ return this->PolicyStatusCMP0004; }
+ /** Get the status of policy CMP0008 when the target was created. */
+ cmPolicies::PolicyStatus GetPolicyStatusCMP0008() const
+ { return this->PolicyStatusCMP0008; }
+
/**
* Get the list of the custom commands for this target
*/
@@ -552,6 +556,7 @@ private:
// Policy status recorded when target was created.
cmPolicies::PolicyStatus PolicyStatusCMP0003;
cmPolicies::PolicyStatus PolicyStatusCMP0004;
+ cmPolicies::PolicyStatus PolicyStatusCMP0008;
// Internal representation details.
friend class cmTargetInternals;