From 5ee9e6bc11a01c7450ffeb14d86f0fe0cef540d6 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 25 Nov 2013 16:23:11 +0100 Subject: cmTarget: Add whitelist of properties on INTERFACE_LIBRARY. --- Source/cmStandardIncludes.h | 6 ++ Source/cmTarget.cxx | 70 ++++++++++++++++++++++ .../RunCMake/interface_library/RunCMakeTest.cmake | 1 + .../interface_library/whitelist-result.txt | 1 + .../interface_library/whitelist-stderr.txt | 19 ++++++ Tests/RunCMake/interface_library/whitelist.cmake | 6 ++ 6 files changed, 103 insertions(+) create mode 100644 Tests/RunCMake/interface_library/whitelist-result.txt create mode 100644 Tests/RunCMake/interface_library/whitelist-stderr.txt create mode 100644 Tests/RunCMake/interface_library/whitelist.cmake diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index 1ccec68..7369fe6 100644 --- a/Source/cmStandardIncludes.h +++ b/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; }; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 022048c..b0a8fd1 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1384,12 +1384,63 @@ 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) { if (!prop) { 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(); diff --git a/Tests/RunCMake/interface_library/RunCMakeTest.cmake b/Tests/RunCMake/interface_library/RunCMakeTest.cmake index 7375888..e257fb3 100644 --- a/Tests/RunCMake/interface_library/RunCMakeTest.cmake +++ b/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) diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/interface_library/whitelist-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/interface_library/whitelist-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/interface_library/whitelist-stderr.txt b/Tests/RunCMake/interface_library/whitelist-stderr.txt new file mode 100644 index 0000000..577c0cc --- /dev/null +++ b/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\) diff --git a/Tests/RunCMake/interface_library/whitelist.cmake b/Tests/RunCMake/interface_library/whitelist.cmake new file mode 100644 index 0000000..98ef05c --- /dev/null +++ b/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) -- cgit v0.12