diff options
-rw-r--r-- | Source/cmComputeLinkInformation.cxx | 108 | ||||
-rw-r--r-- | Source/cmComputeLinkInformation.h | 1 | ||||
-rw-r--r-- | Source/cmPolicies.cxx | 26 | ||||
-rw-r--r-- | Source/cmPolicies.h | 1 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 3 | ||||
-rw-r--r-- | Source/cmTarget.h | 5 |
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; |