/* 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 #include #include "cmStringAlgorithms.h" #include "cmTargetTypes.h" #include "cmValue.h" class cmMakefile; class cmTargetPropertyComputer { public: template 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_, or _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 static std::string const& ImportedLocation(Target const* tgt, std::string const& config); template 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 static cmValue GetSources(Target const* tgt); };