| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file LICENSE.rst or https://cmake.org/licensing for details. */ |
| #pragma once |
| |
| #include "cmConfigure.h" // IWYU pragma: keep |
| |
| #include <string> |
| #include <utility> |
| |
| #include "cmStringAlgorithms.h" |
| #include "cmTargetTypes.h" |
| #include "cmValue.h" |
| |
| class cmMakefile; |
| |
| class cmTargetPropertyComputer |
| { |
| public: |
| template <typename Target> |
| static cmValue GetProperty(Target const* tgt, std::string const& prop, |
| cmMakefile const& mf) |
| { |
| if (cmValue loc = GetLocation(tgt, prop, mf)) { |
| return loc; |
| } |
| if (prop == "SOURCES") { |
| return GetSources(tgt); |
| } |
| return nullptr; |
| } |
| |
| // True if `prop` is a *computed* location property for `type` -- i.e. one of |
| // LOCATION, LOCATION_<CONFIG>, or <CONFIG>_LOCATION on a target type that |
| // synthesizes a location. Reading one of these from a non-imported target |
| // is an error. Excludes IMPORTED_LOCATION and XCODE_ATTRIBUTE_*. If |
| // non-null, `config` is filled with the requested configuration ("" for |
| // plain LOCATION). |
| static bool IsComputedLocationProperty(cm::TargetType type, |
| std::string const& prop, |
| std::string* config = nullptr) |
| { |
| switch (type) { |
| case cm::TargetType::EXECUTABLE: |
| case cm::TargetType::STATIC_LIBRARY: |
| case cm::TargetType::SHARED_LIBRARY: |
| case cm::TargetType::MODULE_LIBRARY: |
| case cm::TargetType::UNKNOWN_LIBRARY: |
| break; |
| default: |
| return false; |
| } |
| if (prop == "LOCATION") { |
| if (config) { |
| config->clear(); |
| } |
| return true; |
| } |
| if (cmHasLiteralPrefix(prop, "LOCATION_")) { |
| if (config) { |
| *config = prop.substr(9); |
| } |
| return true; |
| } |
| if (cmHasLiteralSuffix(prop, "_LOCATION") && |
| !cmHasLiteralPrefix(prop, "XCODE_ATTRIBUTE_")) { |
| std::string c(prop.c_str(), prop.size() - 9); |
| if (c != "IMPORTED") { |
| if (config) { |
| *config = std::move(c); |
| } |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private: |
| static void IssueLocationPropertyError(std::string const& tgtName, |
| cmMakefile const& mf); |
| |
| template <typename Target> |
| static std::string const& ImportedLocation(Target const* tgt, |
| std::string const& config); |
| |
| template <typename Target> |
| static cmValue GetLocation(Target const* tgt, std::string const& prop, |
| cmMakefile const& mf) |
| { |
| // Watch for special "computed" properties that are dependent on |
| // other properties or variables. Always recompute them. |
| std::string config; |
| if (!IsComputedLocationProperty(tgt->GetType(), prop, &config)) { |
| return nullptr; |
| } |
| if (!tgt->IsImported()) { |
| IssueLocationPropertyError(tgt->GetName(), mf); |
| return nullptr; |
| } |
| return cmValue(ImportedLocation(tgt, config)); |
| } |
| |
| template <typename Target> |
| static cmValue GetSources(Target const* tgt); |
| }; |