Преглед изворни кода

cmTarget: Add whitelist of properties on INTERFACE_LIBRARY.

Stephen Kelly пре 12 година
родитељ
комит
5ee9e6bc11

+ 6 - 0
Source/cmStandardIncludes.h

@@ -428,6 +428,12 @@ struct cmStrCmp {
     return strcmp(input, m_test) == 0;
   }
 
+  // For use with binary_search
+  bool operator()(const char *str1, const char *str2)
+  {
+    return strcmp(str1, str2) < 0;
+  }
+
 private:
   const char *m_test;
 };

+ 70 - 0
Source/cmTarget.cxx

@@ -1383,6 +1383,47 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
     }
 }
 
+//----------------------------------------------------------------------------
+static bool whiteListedInterfaceProperty(const char *prop)
+{
+  if(cmHasLiteralPrefix(prop, "INTERFACE_"))
+    {
+    return true;
+    }
+  static const char* builtIns[] = {
+    // ###: This must remain sorted. It is processed with a binary search.
+    "COMPATIBLE_INTERFACE_BOOL",
+    "COMPATIBLE_INTERFACE_NUMBER_MAX",
+    "COMPATIBLE_INTERFACE_NUMBER_MIN",
+    "COMPATIBLE_INTERFACE_STRING",
+    "EXCLUDE_FROM_ALL",
+    "EXCLUDE_FROM_DEFAULT_BUILD",
+    "EXPORT_NAME",
+    "IMPORTED_LINK_INTERFACE_LANGUAGES",
+    "IMPORTED",
+    "NAME",
+    "TYPE",
+    "VERSION"
+  };
+
+  if (std::binary_search(cmArrayBegin(builtIns),
+                         cmArrayEnd(builtIns),
+                         prop,
+                         cmStrCmp(prop)))
+    {
+    return true;
+    }
+
+  if (cmHasLiteralPrefix(prop, "EXCLUDE_FROM_DEFAULT_BUILD_")
+      || cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LANGUAGES_")
+      || cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_"))
+    {
+    return true;
+    }
+
+  return false;
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::SetProperty(const char* prop, const char* value)
 {
@@ -1390,6 +1431,16 @@ void cmTarget::SetProperty(const char* prop, const char* value)
     {
     return;
     }
+  if (this->GetType() == INTERFACE_LIBRARY
+      && !whiteListedInterfaceProperty(prop))
+    {
+    cmOStringStream e;
+    e << "INTERFACE_LIBRARY targets may only have whitelisted properties.  "
+         "The property \"" << prop << "\" is not allowed.";
+    this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+    return;
+    }
+
   if (strcmp(prop, "NAME") == 0)
     {
     cmOStringStream e;
@@ -1459,6 +1510,15 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
     {
     return;
     }
+  if (this->GetType() == INTERFACE_LIBRARY
+      && !whiteListedInterfaceProperty(prop))
+    {
+    cmOStringStream e;
+    e << "INTERFACE_LIBRARY targets may only have whitelisted properties.  "
+         "The property \"" << prop << "\" is not allowed.";
+    this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+    return;
+    }
   if (strcmp(prop, "NAME") == 0)
     {
     cmOStringStream e;
@@ -2574,6 +2634,16 @@ const char *cmTarget::GetProperty(const char* prop,
     return 0;
     }
 
+  if (this->GetType() == INTERFACE_LIBRARY
+      && !whiteListedInterfaceProperty(prop))
+    {
+    cmOStringStream e;
+    e << "INTERFACE_LIBRARY targets may only have whitelisted properties.  "
+         "The property \"" << prop << "\" is not allowed.";
+    this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+    return 0;
+    }
+
   if (strcmp(prop, "NAME") == 0)
     {
     return this->GetName();

+ 1 - 0
Tests/RunCMake/interface_library/RunCMakeTest.cmake

@@ -3,3 +3,4 @@ include(RunCMake)
 run_cmake(invalid_name)
 run_cmake(target_commands)
 run_cmake(no_shared_libs)
+run_cmake(whitelist)

+ 1 - 0
Tests/RunCMake/interface_library/whitelist-result.txt

@@ -0,0 +1 @@
+1

+ 19 - 0
Tests/RunCMake/interface_library/whitelist-stderr.txt

@@ -0,0 +1,19 @@
+CMake Error at whitelist.cmake:4 \(set_property\):
+  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
+  property "OUTPUT_NAME" is not allowed.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+
+
+CMake Error at whitelist.cmake:5 \(set_property\):
+  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
+  property "OUTPUT_NAME" is not allowed.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+
+
+CMake Error at whitelist.cmake:6 \(get_target_property\):
+  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
+  property "OUTPUT_NAME" is not allowed.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 6 - 0
Tests/RunCMake/interface_library/whitelist.cmake

@@ -0,0 +1,6 @@
+
+add_library(iface INTERFACE)
+
+set_property(TARGET iface PROPERTY OUTPUT_NAME output)
+set_property(TARGET iface APPEND PROPERTY OUTPUT_NAME append)
+get_target_property(outname iface OUTPUT_NAME)