| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing for details. */ |
| |
| #include "cmTargetPropertyComputer.h" |
| |
| #include <cctype> |
| #include <sstream> |
| #include <unordered_set> |
| |
| #include "cmMessageType.h" |
| #include "cmMessenger.h" |
| #include "cmPolicies.h" |
| #include "cmStateSnapshot.h" |
| |
| bool cmTargetPropertyComputer::HandleLocationPropertyPolicy( |
| std::string const& tgtName, cmMessenger* messenger, |
| cmListFileBacktrace const& context) |
| { |
| std::ostringstream e; |
| const char* modal = nullptr; |
| MessageType messageType = MessageType::AUTHOR_WARNING; |
| switch (context.GetBottom().GetPolicy(cmPolicies::CMP0026)) { |
| case cmPolicies::WARN: |
| e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0026) << "\n"; |
| modal = "should"; |
| case cmPolicies::OLD: |
| break; |
| case cmPolicies::REQUIRED_ALWAYS: |
| case cmPolicies::REQUIRED_IF_USED: |
| case cmPolicies::NEW: |
| modal = "may"; |
| messageType = MessageType::FATAL_ERROR; |
| } |
| |
| if (modal) { |
| e << "The LOCATION property " << modal << " not be read from target \"" |
| << tgtName |
| << "\". Use the target name directly with " |
| "add_custom_command, or use the generator expression $<TARGET_FILE>, " |
| "as appropriate.\n"; |
| messenger->IssueMessage(messageType, e.str(), context); |
| } |
| |
| return messageType != MessageType::FATAL_ERROR; |
| } |
| |
| bool cmTargetPropertyComputer::WhiteListedInterfaceProperty( |
| const std::string& prop) |
| { |
| if (cmHasLiteralPrefix(prop, "INTERFACE_")) { |
| return true; |
| } |
| if (cmHasLiteralPrefix(prop, "_")) { |
| return true; |
| } |
| if (std::islower(prop[0])) { |
| return true; |
| } |
| static std::unordered_set<std::string> builtIns; |
| if (builtIns.empty()) { |
| builtIns.insert("COMPATIBLE_INTERFACE_BOOL"); |
| builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MAX"); |
| builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN"); |
| builtIns.insert("COMPATIBLE_INTERFACE_STRING"); |
| builtIns.insert("EXPORT_NAME"); |
| builtIns.insert("IMPORTED"); |
| builtIns.insert("IMPORTED_GLOBAL"); |
| builtIns.insert("MANUALLY_ADDED_DEPENDENCIES"); |
| builtIns.insert("NAME"); |
| builtIns.insert("PRIVATE_HEADER"); |
| builtIns.insert("PUBLIC_HEADER"); |
| builtIns.insert("TYPE"); |
| } |
| |
| if (builtIns.count(prop)) { |
| return true; |
| } |
| |
| if (prop == "IMPORTED_CONFIGURATIONS" || prop == "IMPORTED_LIBNAME" || |
| cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME_") || |
| cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) { |
| return true; |
| } |
| |
| // This property should not be allowed but was incorrectly added in |
| // CMake 3.8. We can't remove it from the whitelist without breaking |
| // projects that try to set it. One day we could warn about this, but |
| // for now silently accept it. |
| if (prop == "NO_SYSTEM_FROM_IMPORTED") { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| bool cmTargetPropertyComputer::PassesWhitelist( |
| cmStateEnums::TargetType tgtType, std::string const& prop, |
| cmMessenger* messenger, cmListFileBacktrace const& context) |
| { |
| if (tgtType == cmStateEnums::INTERFACE_LIBRARY && |
| !WhiteListedInterfaceProperty(prop)) { |
| std::ostringstream e; |
| e << "INTERFACE_LIBRARY targets may only have whitelisted properties. " |
| "The property \"" |
| << prop << "\" is not allowed."; |
| messenger->IssueMessage(MessageType::FATAL_ERROR, e.str(), context); |
| return false; |
| } |
| return true; |
| } |