Browse Source

ENH: Disallow link-type keywords in link interface

The LINK_INTERFACE_LIBRARIES target property may not contain the
"debug", "optimized", or "general" keywords.  These keywords are
supported only by the target_link_libraries (and link_libraries) command
and are not a generic library list feature in CMake.  When a user
attempts to add one of these keywords to the property value, we now
produce an error message that refers users to alternative means.
Brad King 17 years ago
parent
commit
fe98e57e38

+ 3 - 0
Source/cmSetPropertyCommand.cxx

@@ -271,6 +271,9 @@ bool cmSetPropertyCommand::HandleTarget(cmTarget* target)
     target->SetProperty(name, value);
     }
 
+  // Check the resulting value.
+  target->CheckProperty(name, this->Makefile);
+
   return true;
 }
 

+ 1 - 0
Source/cmSetTargetPropertiesCommand.cxx

@@ -103,6 +103,7 @@ bool cmSetTargetPropertiesCommand
       {
       target->SetProperty(propertyPairs[k].c_str(),
                           propertyPairs[k+1].c_str());
+      target->CheckProperty(propertyPairs[k].c_str(), mf);
       }
     }
   // if file is not already in the makefile, then add it

+ 64 - 0
Source/cmTarget.cxx

@@ -22,6 +22,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmComputeLinkInformation.h"
 #include "cmListFileCache.h"
+#include <cmsys/RegularExpression.hxx>
 #include <map>
 #include <set>
 #include <queue>
@@ -1690,6 +1691,69 @@ void cmTarget::AppendProperty(const char* prop, const char* value)
     }
 }
 
+//----------------------------------------------------------------------------
+static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
+  const char* prop, const char* value, cmMakefile* context, bool imported
+  )
+{
+  // Look for link-type keywords in the value.
+  static cmsys::RegularExpression
+    keys("(^|;)(debug|optimized|general)(;|$)");
+  if(!keys.find(value))
+    {
+    return;
+    }
+
+  // Support imported and non-imported versions of the property.
+  const char* base = (imported?
+                      "IMPORTED_LINK_INTERFACE_LIBRARIES" :
+                      "LINK_INTERFACE_LIBRARIES");
+
+  // Report an error.
+  cmOStringStream e;
+  e << "Property " << prop << " may not contain link-type keyword \""
+    << keys.match(2) << "\".  "
+    << "The " << base << " property has a per-configuration "
+    << "version called " << base << "_<CONFIG> which may be "
+    << "used to specify per-configuration rules.";
+  if(!imported)
+    {
+    e << "  "
+      << "Alternatively, an IMPORTED library may be created, configured "
+      << "with a per-configuration location, and then named in the "
+      << "property value.  "
+      << "See the add_library command's IMPORTED mode for details."
+      << "\n"
+      << "If you have a list of libraries that already contains the "
+      << "keyword, use the target_link_libraries command with its "
+      << "LINK_INTERFACE_LIBRARIES mode to set the property.  "
+      << "The command automatically recognizes link-type keywords and sets "
+      << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
+      << "properties accordingly.";
+    }
+  context->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::CheckProperty(const char* prop, cmMakefile* context)
+{
+  // Certain properties need checking.
+  if(strncmp(prop, "LINK_INTERFACE_LIBRARIES", 24) == 0)
+    {
+    if(const char* value = this->GetProperty(prop))
+      {
+      cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
+      }
+    }
+  if(strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES", 33) == 0)
+    {
+    if(const char* value = this->GetProperty(prop))
+      {
+      cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
+      }
+    }
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::MarkAsImported()
 {

+ 1 - 0
Source/cmTarget.h

@@ -245,6 +245,7 @@ public:
   const char *GetProperty(const char *prop);
   const char *GetProperty(const char *prop, cmProperty::ScopeType scope);
   bool GetPropertyAsBool(const char *prop);
+  void CheckProperty(const char* prop, cmMakefile* context);
 
   bool IsImported() const {return this->IsImportedTarget;}