/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmTarget.h"

#include <algorithm>
#include <cassert>
#include <iterator>
#include <map>
#include <set>
#include <sstream>
#include <unordered_map>
#include <unordered_set>

#include <cm/memory>
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>

#include "cmsys/RegularExpression.hxx"

#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmFileSet.h"
#include "cmFindPackageStack.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProperty.h"
#include "cmPropertyDefinition.h"
#include "cmPropertyMap.h"
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
#include "cmSourceFileLocationKind.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
#include "cmTargetPropertyComputer.h"
#include "cmValue.h"
#include "cmXcFramework.h"
#include "cmake.h"

template <>
const std::string& cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>(
  cmTarget const* tgt)
{
  static std::string loc;
  if (tgt->IsImported()) {
    loc = tgt->ImportedGetFullPath("", cmStateEnums::RuntimeBinaryArtifact);
    return loc;
  }

  cmGlobalGenerator* gg = tgt->GetGlobalGenerator();
  if (!gg->GetConfigureDoneCMP0026()) {
    gg->CreateGenerationObjects();
  }
  cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName());
  loc = gt->GetLocationForBuild();
  return loc;
}

template <>
const std::string& cmTargetPropertyComputer::ComputeLocation<cmTarget>(
  cmTarget const* tgt, const std::string& config)
{
  static std::string loc;
  if (tgt->IsImported()) {
    loc =
      tgt->ImportedGetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
    return loc;
  }

  cmGlobalGenerator* gg = tgt->GetGlobalGenerator();
  if (!gg->GetConfigureDoneCMP0026()) {
    gg->CreateGenerationObjects();
  }
  cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName());
  loc = gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
  return loc;
}

template <>
cmValue cmTargetPropertyComputer::GetSources<cmTarget>(cmTarget const* tgt,
                                                       cmMakefile const& mf)
{
  cmBTStringRange entries = tgt->GetSourceEntries();
  if (entries.empty()) {
    return nullptr;
  }

  std::ostringstream ss;
  const char* sep = "";
  for (auto const& entry : entries) {
    cmList files{ entry.Value };
    for (std::string const& file : files) {
      if (cmHasLiteralPrefix(file, "$<TARGET_OBJECTS:") &&
          file.back() == '>') {
        std::string objLibName = file.substr(17, file.size() - 18);

        if (cmGeneratorExpression::Find(objLibName) != std::string::npos) {
          ss << sep;
          sep = ";";
          ss << file;
          continue;
        }

        bool addContent = false;
        bool noMessage = true;
        std::ostringstream e;
        MessageType messageType = MessageType::AUTHOR_WARNING;
        switch (mf.GetPolicyStatus(cmPolicies::CMP0051)) {
          case cmPolicies::WARN:
            e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0051) << "\n";
            noMessage = false;
            CM_FALLTHROUGH;
          case cmPolicies::OLD:
            break;
          case cmPolicies::REQUIRED_ALWAYS:
          case cmPolicies::REQUIRED_IF_USED:
          case cmPolicies::NEW:
            addContent = true;
            break;
        }
        if (!noMessage) {
          e << "Target \"" << tgt->GetName()
            << "\" contains $<TARGET_OBJECTS> generator expression in its "
               "sources list.  This content was not previously part of the "
               "SOURCES property when that property was read at configure "
               "time.  Code reading that property needs to be adapted to "
               "ignore the generator expression using the string(GENEX_STRIP) "
               "command.";
          mf.IssueMessage(messageType, e.str());
        }
        if (addContent) {
          ss << sep;
          sep = ";";
          ss << file;
        }
      } else if (cmGeneratorExpression::Find(file) == std::string::npos) {
        ss << sep;
        sep = ";";
        ss << file;
      } else {
        cmSourceFile* sf = tgt->GetMakefile()->GetOrCreateSource(file);
        // Construct what is known about this source file location.
        cmSourceFileLocation const& location = sf->GetLocation();
        std::string sname = location.GetDirectory();
        if (!sname.empty()) {
          sname += "/";
        }
        sname += location.GetName();

        ss << sep;
        sep = ";";
        // Append this list entry.
        ss << sname;
      }
    }
  }
  static std::string srcs;
  srcs = ss.str();
  return cmValue(srcs);
}

namespace {
struct FileSetEntries
{
  FileSetEntries(cm::static_string_view propertyName)
    : PropertyName(propertyName)
  {
  }

  cm::static_string_view const PropertyName;
  std::vector<BT<std::string>> Entries;
};

struct FileSetType
{
  FileSetType(cm::static_string_view typeName,
              cm::static_string_view defaultDirectoryProperty,
              cm::static_string_view defaultPathProperty,
              cm::static_string_view directoryPrefix,
              cm::static_string_view pathPrefix,
              cm::static_string_view typeDescription,
              cm::static_string_view defaultDescription,
              cm::static_string_view arbitraryDescription,
              FileSetEntries selfEntries, FileSetEntries interfaceEntries)
    : TypeName(typeName)
    , DefaultDirectoryProperty(defaultDirectoryProperty)
    , DefaultPathProperty(defaultPathProperty)
    , DirectoryPrefix(directoryPrefix)
    , PathPrefix(pathPrefix)
    , TypeDescription(typeDescription)
    , DefaultDescription(defaultDescription)
    , ArbitraryDescription(arbitraryDescription)
    , SelfEntries(std::move(selfEntries))
    , InterfaceEntries(std::move(interfaceEntries))
  {
  }

  cm::static_string_view const TypeName;
  cm::static_string_view const DefaultDirectoryProperty;
  cm::static_string_view const DefaultPathProperty;
  cm::static_string_view const DirectoryPrefix;
  cm::static_string_view const PathPrefix;
  cm::static_string_view const TypeDescription;
  cm::static_string_view const DefaultDescription;
  cm::static_string_view const ArbitraryDescription;

  FileSetEntries SelfEntries;
  FileSetEntries InterfaceEntries;

  enum class Action
  {
    Set,
    Append,
  };

  template <typename ValueType>
  bool WriteProperties(cmTarget* tgt, cmTargetInternals* impl,
                       const std::string& prop, ValueType value,
                       Action action);
  std::pair<bool, cmValue> ReadProperties(cmTarget const* tgt,
                                          cmTargetInternals const* impl,
                                          const std::string& prop) const;

  void AddFileSet(const std::string& name, cmFileSetVisibility vis,
                  cmListFileBacktrace bt);
};

struct UsageRequirementProperty
{
  enum class AppendEmpty
  {
    Yes,
    No,
  };

  UsageRequirementProperty(cm::static_string_view name,
                           AppendEmpty appendEmpty = AppendEmpty::No)
    : Name(name)
    , AppendBehavior(appendEmpty)
  {
  }

  void CopyFromEntries(cmBTStringRange entries)
  {
    return cm::append(this->Entries, entries);
  }

  enum class Action
  {
    Set,
    Prepend,
    Append,
  };

  template <typename ValueType>
  bool Write(cmTargetInternals const* impl,
             cm::optional<cmListFileBacktrace> const& bt,
             const std::string& prop, ValueType value, Action action);
  template <typename ValueType>
  void WriteDirect(cmTargetInternals const* impl,
                   cm::optional<cmListFileBacktrace> const& bt,
                   ValueType value, Action action);
  void WriteDirect(BT<std::string> value, Action action);
  std::pair<bool, cmValue> Read(const std::string& prop) const;

  cm::static_string_view const Name;
  AppendEmpty const AppendBehavior;

  std::vector<BT<std::string>> Entries;
};

struct TargetProperty
{
  enum class InitCondition
  {
    // Always initialize the property.
    Always,
    // Never initialize the property.
    Never,
    // Only initialize if the target can compile sources.
    CanCompileSources,
    // Only apply to Xcode generators.
    NeedsXcode,
    // Only apply to Xcode generators on targets that can compile sources.
    NeedsXcodeAndCanCompileSources,
    // Needs to be a "normal" target (any non-global, non-utility target).
    NormalTarget,
    // Any non-imported target.
    NonImportedTarget,
    // Needs to be a "normal" target (any non-global, non-utility target) that
    // is not `IMPORTED`.
    NormalNonImportedTarget,
    // Needs to be a "normal" target with an artifact (no `INTERFACE`
    // libraries).
    TargetWithArtifact,
    // Needs to be a "normal" target with an artifact that is not an
    // executable.
    NonExecutableWithArtifact,
    // Needs to be a linkable library target (no `OBJECT` or `MODULE`
    // libraries).
    LinkableLibraryTarget,
    // Needs to be an executable.
    ExecutableTarget,
    // Needs to be a shared library (`SHARED`).
    SharedLibraryTarget,
    // Needs to be a target with meaningful symbol exports (`SHARED` or
    // `EXECUTABLE`).
    TargetWithSymbolExports,
    // Targets with "commands" associated with them. Basically everything
    // except global and `INTERFACE` targets.
    TargetWithCommands,
  };

  enum class Repetition
  {
    Once,
    PerConfig,
    PerConfigPrefix,
  };

  TargetProperty(cm::static_string_view name)
    : Name(name)
  {
  }

  TargetProperty(cm::static_string_view name, cm::static_string_view dflt,
                 InitCondition init)
    : Name(name)
    , Default(dflt)
    , InitConditional(init)
  {
  }

  TargetProperty(cm::static_string_view name, InitCondition init)
    : Name(name)
    , InitConditional(init)
  {
  }

  TargetProperty(cm::static_string_view name, InitCondition init,
                 Repetition repeat)
    : Name(name)
    , InitConditional(init)
    , Repeat(repeat)
  {
  }

  cm::static_string_view const Name;
  cm::optional<cm::static_string_view> const Default = {};
  InitCondition const InitConditional = InitCondition::Always;
  Repetition const Repeat = Repetition::Once;
};

#define IC TargetProperty::InitCondition
#define R TargetProperty::Repetition

/* clang-format off */
#define COMMON_LANGUAGE_PROPERTIES(lang)                                      \
  { #lang "_COMPILER_LAUNCHER"_s, IC::CanCompileSources },                    \
  { #lang "_STANDARD"_s, IC::CanCompileSources },                             \
  { #lang "_STANDARD_REQUIRED"_s, IC::CanCompileSources },                    \
  { #lang "_EXTENSIONS"_s, IC::CanCompileSources },                           \
  { #lang "_VISIBILITY_PRESET"_s, IC::CanCompileSources }
/* clang-format on */

TargetProperty const StaticTargetProperties[] = {
  /* clang-format off */
  // Compilation properties
  { "COMPILE_WARNING_AS_ERROR"_s, IC::CanCompileSources },
  { "INTERPROCEDURAL_OPTIMIZATION"_s, IC::CanCompileSources },
  { "INTERPROCEDURAL_OPTIMIZATION_"_s, IC::TargetWithArtifact, R::PerConfig },
  { "NO_SYSTEM_FROM_IMPORTED"_s, IC::CanCompileSources },
  // Set to `True` for `SHARED` and `MODULE` targets.
  { "POSITION_INDEPENDENT_CODE"_s, IC::CanCompileSources },
  { "VISIBILITY_INLINES_HIDDEN"_s, IC::CanCompileSources },
  // -- Features
  // ---- PCH
  { "DISABLE_PRECOMPILE_HEADERS"_s, IC::CanCompileSources },
  { "PCH_WARN_INVALID"_s, "ON"_s, IC::CanCompileSources },
  { "PCH_INSTANTIATE_TEMPLATES"_s, "ON"_s, IC::CanCompileSources },
  // -- Platforms
  // ---- Android
  { "ANDROID_API"_s, IC::CanCompileSources },
  { "ANDROID_API_MIN"_s, IC::CanCompileSources },
  { "ANDROID_ARCH"_s, IC::CanCompileSources },
  { "ANDROID_ASSETS_DIRECTORIES"_s, IC::CanCompileSources },
  { "ANDROID_JAVA_SOURCE_DIR"_s, IC::CanCompileSources },
  { "ANDROID_STL_TYPE"_s, IC::CanCompileSources },
  // ---- macOS
  { "OSX_ARCHITECTURES"_s, IC::CanCompileSources },
  // ---- Windows
  { "MSVC_DEBUG_INFORMATION_FORMAT"_s, IC::CanCompileSources },
  { "MSVC_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
  { "VS_JUST_MY_CODE_DEBUGGING"_s, IC::CanCompileSources },
  { "VS_DEBUGGER_COMMAND"_s, IC::ExecutableTarget },
  { "VS_DEBUGGER_COMMAND_ARGUMENTS"_s, IC::ExecutableTarget },
  { "VS_DEBUGGER_ENVIRONMENT"_s, IC::ExecutableTarget },
  { "VS_DEBUGGER_WORKING_DIRECTORY"_s, IC::ExecutableTarget },
  // ---- OpenWatcom
  { "WATCOM_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
  // -- Language
  // ---- C
  COMMON_LANGUAGE_PROPERTIES(C),
  // ---- C++
  COMMON_LANGUAGE_PROPERTIES(CXX),
  // ---- CSharp
  { "DOTNET_SDK"_s, IC::NonImportedTarget },
  { "DOTNET_TARGET_FRAMEWORK"_s, IC::TargetWithCommands },
  { "DOTNET_TARGET_FRAMEWORK_VERSION"_s, IC::TargetWithCommands },
  // ---- CUDA
  COMMON_LANGUAGE_PROPERTIES(CUDA),
  { "CUDA_SEPARABLE_COMPILATION"_s, IC::CanCompileSources },
  { "CUDA_ARCHITECTURES"_s, IC::CanCompileSources },
  // ---- Fortran
  { "Fortran_FORMAT"_s, IC::CanCompileSources },
  { "Fortran_MODULE_DIRECTORY"_s, IC::CanCompileSources },
  { "Fortran_COMPILER_LAUNCHER"_s, IC::CanCompileSources },
  { "Fortran_PREPROCESS"_s, IC::CanCompileSources },
  { "Fortran_VISIBILITY_PRESET"_s, IC::CanCompileSources },
  // ---- HIP
  COMMON_LANGUAGE_PROPERTIES(HIP),
  { "HIP_ARCHITECTURES"_s, IC::CanCompileSources },
  // ---- ISPC
  { "ISPC_COMPILER_LAUNCHER"_s, IC::CanCompileSources },
  { "ISPC_HEADER_DIRECTORY"_s, IC::CanCompileSources },
  { "ISPC_HEADER_SUFFIX"_s, "_ispc.h"_s, IC::CanCompileSources },
  { "ISPC_INSTRUCTION_SETS"_s, IC::CanCompileSources },
  // ---- Objective C
  COMMON_LANGUAGE_PROPERTIES(OBJC),
  // ---- Objective C++
  COMMON_LANGUAGE_PROPERTIES(OBJCXX),
  // ---- Swift
  { "Swift_LANGUAGE_VERSION"_s, IC::CanCompileSources },
  { "Swift_MODULE_DIRECTORY"_s, IC::CanCompileSources },
  { "Swift_COMPILATION_MODE"_s, IC::CanCompileSources },
  // ---- moc
  { "AUTOMOC"_s, IC::CanCompileSources },
  { "AUTOMOC_COMPILER_PREDEFINES"_s, IC::CanCompileSources },
  { "AUTOMOC_MACRO_NAMES"_s, IC::CanCompileSources },
  { "AUTOMOC_MOC_OPTIONS"_s, IC::CanCompileSources },
  { "AUTOMOC_PATH_PREFIX"_s, IC::CanCompileSources },
  { "AUTOMOC_EXECUTABLE"_s, IC::CanCompileSources },
  // ---- uic
  { "AUTOUIC"_s, IC::CanCompileSources },
  { "AUTOUIC_OPTIONS"_s, IC::CanCompileSources },
  { "AUTOUIC_SEARCH_PATHS"_s, IC::CanCompileSources },
  { "AUTOUIC_EXECUTABLE"_s, IC::CanCompileSources },
  // ---- rcc
  { "AUTORCC"_s, IC::CanCompileSources },
  { "AUTORCC_OPTIONS"_s, IC::CanCompileSources },
  { "AUTORCC_EXECUTABLE"_s, IC::CanCompileSources },

  // Linking properties
  { "LINKER_TYPE"_s, IC::CanCompileSources },
  { "ENABLE_EXPORTS"_s, IC::TargetWithSymbolExports },
  { "LINK_LIBRARIES_ONLY_TARGETS"_s, IC::NormalNonImportedTarget },
  { "LINK_SEARCH_START_STATIC"_s, IC::CanCompileSources },
  { "LINK_SEARCH_END_STATIC"_s, IC::CanCompileSources },
  // Initialize per-configuration name postfix property from the variable only
  // for non-executable targets.  This preserves compatibility with previous
  // CMake versions in which executables did not support this variable.
  // Projects may still specify the property directly.
  { "_POSTFIX"_s, IC::NonExecutableWithArtifact, R::PerConfigPrefix },
  // -- Dependent library lookup
  { "MACOSX_RPATH"_s, IC::CanCompileSources },
  // ---- Build
  { "BUILD_RPATH"_s, IC::CanCompileSources },
  { "BUILD_RPATH_USE_ORIGIN"_s, IC::CanCompileSources },
  { "SKIP_BUILD_RPATH"_s, "OFF"_s, IC::CanCompileSources },
  { "BUILD_WITH_INSTALL_RPATH"_s, "OFF"_s, IC::CanCompileSources },
  { "BUILD_WITH_INSTALL_NAME_DIR"_s, IC::CanCompileSources },
  // ---- Install
  { "INSTALL_NAME_DIR"_s, IC::CanCompileSources },
  { "INSTALL_REMOVE_ENVIRONMENT_RPATH"_s, IC::CanCompileSources },
  { "INSTALL_RPATH"_s, ""_s, IC::CanCompileSources },
  { "INSTALL_RPATH_USE_LINK_PATH"_s, "OFF"_s, IC::CanCompileSources },
  // -- Platforms
  // ---- AIX
  { "AIX_EXPORT_ALL_SYMBOLS"_s, IC::TargetWithSymbolExports },
  // ---- Android
  { "ANDROID_GUI"_s, IC::ExecutableTarget },
  { "ANDROID_JAR_DIRECTORIES"_s, IC::CanCompileSources },
  { "ANDROID_JAR_DEPENDENCIES"_s, IC::CanCompileSources },
  { "ANDROID_NATIVE_LIB_DIRECTORIES"_s, IC::CanCompileSources },
  { "ANDROID_NATIVE_LIB_DEPENDENCIES"_s, IC::CanCompileSources },
  { "ANDROID_PROGUARD"_s, IC::CanCompileSources },
  { "ANDROID_PROGUARD_CONFIG_PATH"_s, IC::CanCompileSources },
  { "ANDROID_SECURE_PROPS_PATH"_s, IC::CanCompileSources },
  // ---- iOS
  { "IOS_INSTALL_COMBINED"_s, IC::CanCompileSources },
  // ---- macOS
  { "FRAMEWORK_MULTI_CONFIG_POSTFIX_"_s, IC::LinkableLibraryTarget, R::PerConfig },
  // ---- Windows
  { "DLL_NAME_WITH_SOVERSION"_s, IC::SharedLibraryTarget },
  { "GNUtoMS"_s, IC::CanCompileSources },
  { "WIN32_EXECUTABLE"_s, IC::CanCompileSources },
  { "WINDOWS_EXPORT_ALL_SYMBOLS"_s, IC::TargetWithSymbolExports },
  // -- Languages
  // ---- C
  { "C_LINKER_LAUNCHER"_s, IC::CanCompileSources },
  // ---- C++
  { "CXX_LINKER_LAUNCHER"_s, IC::CanCompileSources },
  // ---- CUDA
  { "CUDA_RESOLVE_DEVICE_SYMBOLS"_s, IC::CanCompileSources },
  { "CUDA_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
  // ---- HIP
  { "HIP_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
  // ---- Objective C
  { "OBJC_LINKER_LAUNCHER"_s, IC::CanCompileSources },
  // ---- Objective C++
  { "OBJCXX_LINKER_LAUNCHER"_s, IC::CanCompileSources },

  // Static analysis
  // -- C
  { "C_CLANG_TIDY"_s, IC::CanCompileSources },
  { "C_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
  { "C_CPPLINT"_s, IC::CanCompileSources },
  { "C_CPPCHECK"_s, IC::CanCompileSources },
  { "C_INCLUDE_WHAT_YOU_USE"_s, IC::CanCompileSources },
  // -- C++
  { "CXX_CLANG_TIDY"_s, IC::CanCompileSources },
  { "CXX_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
  { "CXX_CPPLINT"_s, IC::CanCompileSources },
  { "CXX_CPPCHECK"_s, IC::CanCompileSources },
  { "CXX_INCLUDE_WHAT_YOU_USE"_s, IC::CanCompileSources },
  // -- Objective C
  { "OBJC_CLANG_TIDY"_s, IC::CanCompileSources },
  { "OBJC_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
  // -- Objective C++
  { "OBJCXX_CLANG_TIDY"_s, IC::CanCompileSources },
  { "OBJCXX_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
  // -- Linking
  { "LINK_WHAT_YOU_USE"_s, IC::CanCompileSources },

  // Build graph properties
  { "LINK_DEPENDS_NO_SHARED"_s, IC::CanCompileSources },
  { "UNITY_BUILD"_s, IC::CanCompileSources },
  { "UNITY_BUILD_UNIQUE_ID"_s, IC::CanCompileSources },
  { "UNITY_BUILD_BATCH_SIZE"_s, "8"_s, IC::CanCompileSources },
  { "UNITY_BUILD_MODE"_s, "BATCH"_s, IC::CanCompileSources },
  { "OPTIMIZE_DEPENDENCIES"_s, IC::CanCompileSources },
  { "VERIFY_INTERFACE_HEADER_SETS"_s },
  // -- Android
  { "ANDROID_ANT_ADDITIONAL_OPTIONS"_s, IC::CanCompileSources },
  { "ANDROID_PROCESS_MAX"_s, IC::CanCompileSources },
  { "ANDROID_SKIP_ANT_STEP"_s, IC::CanCompileSources },
  // -- Autogen
  { "AUTOGEN_COMMAND_LINE_LENGTH_MAX"_s, IC::CanCompileSources },
  { "AUTOGEN_ORIGIN_DEPENDS"_s, IC::CanCompileSources },
  { "AUTOGEN_PARALLEL"_s, IC::CanCompileSources },
  { "AUTOGEN_USE_SYSTEM_INCLUDE"_s, IC::CanCompileSources },
  { "AUTOGEN_BETTER_GRAPH_MULTI_CONFIG"_s, IC::CanCompileSources },
  // -- moc
  { "AUTOMOC_DEPEND_FILTERS"_s, IC::CanCompileSources },
  // -- C++
  { "CXX_SCAN_FOR_MODULES"_s, IC::CanCompileSources },
  // -- Ninja
  { "JOB_POOL_COMPILE"_s, IC::CanCompileSources },
  { "JOB_POOL_LINK"_s, IC::CanCompileSources },
  { "JOB_POOL_PRECOMPILE_HEADER"_s, IC::CanCompileSources },
  // -- Visual Studio
  { "VS_NO_COMPILE_BATCHING"_s, IC::CanCompileSources },
  { "VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION"_s, IC::CanCompileSources},

  // Output location properties
  { "ARCHIVE_OUTPUT_DIRECTORY"_s, IC::CanCompileSources },
  { "ARCHIVE_OUTPUT_DIRECTORY_"_s, IC::TargetWithArtifact, R::PerConfig },
  { "COMPILE_PDB_OUTPUT_DIRECTORY"_s, IC::CanCompileSources },
  { "COMPILE_PDB_OUTPUT_DIRECTORY_"_s, IC::TargetWithArtifact, R::PerConfig },
  { "LIBRARY_OUTPUT_DIRECTORY"_s, IC::CanCompileSources },
  { "LIBRARY_OUTPUT_DIRECTORY_"_s, IC::TargetWithArtifact, R::PerConfig },
  { "PDB_OUTPUT_DIRECTORY"_s, IC::CanCompileSources },
  { "PDB_OUTPUT_DIRECTORY_"_s, IC::TargetWithArtifact, R::PerConfig },
  { "RUNTIME_OUTPUT_DIRECTORY"_s, IC::CanCompileSources },
  { "RUNTIME_OUTPUT_DIRECTORY_"_s, IC::TargetWithArtifact, R::PerConfig },

  // macOS bundle properties
  { "FRAMEWORK"_s, IC::CanCompileSources },
  { "FRAMEWORK_MULTI_CONFIG_POSTFIX"_s, IC::CanCompileSources },
  { "MACOSX_BUNDLE"_s, IC::CanCompileSources },

  // Usage requirement properties
  { "LINK_INTERFACE_LIBRARIES"_s, IC::CanCompileSources },
  { "MAP_IMPORTED_CONFIG_"_s, IC::NormalTarget, R::PerConfig },
  { "EXPORT_FIND_PACKAGE_NAME"_s, IC::NormalTarget },

  // Metadata
  { "CROSSCOMPILING_EMULATOR"_s, IC::ExecutableTarget },
  { "EXPORT_COMPILE_COMMANDS"_s, IC::CanCompileSources },
  { "FOLDER"_s },
  { "TEST_LAUNCHER"_s, IC::ExecutableTarget },

  // Xcode properties
  { "XCODE_GENERATE_SCHEME"_s, IC::NeedsXcode },

#ifdef __APPLE__
  { "XCODE_SCHEME_ADDRESS_SANITIZER"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_THREAD_SANITIZER"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_THREAD_SANITIZER_STOP"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_LAUNCH_CONFIGURATION"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_ENABLE_GPU_API_VALIDATION"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_WORKING_DIRECTORY"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_MALLOC_SCRIBBLE"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_MALLOC_GUARD_EDGES"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_GUARD_MALLOC"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_LAUNCH_MODE"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_ZOMBIE_OBJECTS"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_MALLOC_STACK"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_SCHEME_ENVIRONMENT"_s, IC::NeedsXcodeAndCanCompileSources },
  { "XCODE_LINK_BUILD_PHASE_MODE"_s, "NONE"_s, IC::NeedsXcodeAndCanCompileSources },
#endif
  /* clang-format on */
};

#undef COMMON_LANGUAGE_PROPERTIES
#undef IC
#undef R
}

class cmTargetInternals
{
public:
  cmStateEnums::TargetType TargetType;
  cmMakefile* Makefile;
  cmPolicies::PolicyMap PolicyMap;
  std::string Name;
  std::string InstallPath;
  std::string RuntimeInstallPath;
  cmPropertyMap Properties;
  bool IsGeneratorProvided;
  bool HaveInstallRule;
  bool IsDLLPlatform;
  bool IsAIX;
  bool IsApple;
  bool IsAndroid;
  bool BuildInterfaceIncludesAppended;
  bool PerConfig;
  cmTarget::Visibility TargetVisibility;
  std::set<BT<std::pair<std::string, bool>>> Utilities;
  std::vector<cmCustomCommand> PreBuildCommands;
  std::vector<cmCustomCommand> PreLinkCommands;
  std::vector<cmCustomCommand> PostBuildCommands;
  std::vector<cmInstallTargetGenerator*> InstallGenerators;
  std::set<std::string> SystemIncludeDirectories;
  cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
  std::map<std::string, BTs<std::string>> LanguageStandardProperties;
  std::map<cmTargetExport const*, std::vector<std::string>>
    InstallIncludeDirectoriesEntries;
  std::vector<std::pair<cmTarget::TLLSignature, cmListFileContext>>
    TLLCommands;
  std::map<std::string, cmFileSet> FileSets;
  cmListFileBacktrace Backtrace;
  cmFindPackageStack FindPackageStack;

  UsageRequirementProperty IncludeDirectories;
  UsageRequirementProperty CompileOptions;
  UsageRequirementProperty CompileFeatures;
  UsageRequirementProperty CompileDefinitions;
  UsageRequirementProperty PrecompileHeaders;
  UsageRequirementProperty Sources;
  UsageRequirementProperty LinkOptions;
  UsageRequirementProperty LinkDirectories;
  UsageRequirementProperty LinkLibraries;
  UsageRequirementProperty InterfaceLinkLibraries;
  UsageRequirementProperty InterfaceLinkLibrariesDirect;
  UsageRequirementProperty InterfaceLinkLibrariesDirectExclude;
  UsageRequirementProperty ImportedCxxModulesIncludeDirectories;
  UsageRequirementProperty ImportedCxxModulesCompileDefinitions;
  UsageRequirementProperty ImportedCxxModulesCompileFeatures;
  UsageRequirementProperty ImportedCxxModulesCompileOptions;
  UsageRequirementProperty ImportedCxxModulesLinkLibraries;

  FileSetType HeadersFileSets;
  FileSetType CxxModulesFileSets;

  cmTargetInternals();

  bool IsImported() const;

  bool CheckImportedLibName(std::string const& prop,
                            std::string const& value) const;

  std::string ProcessSourceItemCMP0049(const std::string& s) const;

  template <typename ValueType>
  void AddDirectoryToFileSet(cmTarget* self, std::string const& fileSetName,
                             ValueType value, cm::string_view fileSetType,
                             cm::string_view description,
                             FileSetType::Action action);
  template <typename ValueType>
  void AddPathToFileSet(cmTarget* self, std::string const& fileSetName,
                        ValueType value, cm::string_view fileSetType,
                        cm::string_view description,
                        FileSetType::Action action);
  cmValue GetFileSetDirectories(cmTarget const* self,
                                std::string const& fileSetName,
                                cm::string_view fileSetType) const;
  cmValue GetFileSetPaths(cmTarget const* self, std::string const& fileSetName,
                          cm::string_view fileSetType) const;

  cmListFileBacktrace GetBacktrace(
    cm::optional<cmListFileBacktrace> const& bt) const
  {
    return bt ? *bt : this->Makefile->GetBacktrace();
  }
};

cmTargetInternals::cmTargetInternals()
  : IncludeDirectories("INCLUDE_DIRECTORIES"_s)
  , CompileOptions("COMPILE_OPTIONS"_s)
  , CompileFeatures("COMPILE_FEATURES"_s)
  , CompileDefinitions("COMPILE_DEFINITIONS"_s)
  , PrecompileHeaders("PRECOMPILE_HEADERS"_s)
  , Sources("SOURCES"_s, UsageRequirementProperty::AppendEmpty::Yes)
  , LinkOptions("LINK_OPTIONS"_s)
  , LinkDirectories("LINK_DIRECTORIES"_s)
  , LinkLibraries("LINK_LIBRARIES"_s)
  , InterfaceLinkLibraries("INTERFACE_LINK_LIBRARIES"_s)
  , InterfaceLinkLibrariesDirect("INTERFACE_LINK_LIBRARIES_DIRECT"_s)
  , InterfaceLinkLibrariesDirectExclude(
      "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"_s)
  , ImportedCxxModulesIncludeDirectories(
      "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES"_s)
  , ImportedCxxModulesCompileDefinitions(
      "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS"_s)
  , ImportedCxxModulesCompileFeatures(
      "IMPORTED_CXX_MODULES_COMPILE_FEATURES"_s)
  , ImportedCxxModulesCompileOptions("IMPORTED_CXX_MODULES_COMPILE_OPTIONS"_s)
  , ImportedCxxModulesLinkLibraries("IMPORTED_CXX_MODULES_LINK_LIBRARIES"_s)
  , HeadersFileSets("HEADERS"_s, "HEADER_DIRS"_s, "HEADER_SET"_s,
                    "HEADER_DIRS_"_s, "HEADER_SET_"_s, "Header"_s,
                    "The default header set"_s, "Header set"_s,
                    FileSetEntries("HEADER_SETS"_s),
                    FileSetEntries("INTERFACE_HEADER_SETS"_s))
  , CxxModulesFileSets("CXX_MODULES"_s, "CXX_MODULE_DIRS"_s,
                       "CXX_MODULE_SET"_s, "CXX_MODULE_DIRS_"_s,
                       "CXX_MODULE_SET_"_s, "C++ module"_s,
                       "The default C++ module set"_s, "C++ module set"_s,
                       FileSetEntries("CXX_MODULE_SETS"_s),
                       FileSetEntries("INTERFACE_CXX_MODULE_SETS"_s))
{
}

template <typename ValueType>
bool FileSetType::WriteProperties(cmTarget* tgt, cmTargetInternals* impl,
                                  const std::string& prop, ValueType value,
                                  Action action)
{
  if (prop == this->DefaultDirectoryProperty) {
    impl->AddDirectoryToFileSet(tgt, std::string(this->TypeName), value,
                                this->TypeName, this->DefaultDescription,
                                action);
    return true;
  }
  if (prop == this->DefaultPathProperty) {
    impl->AddPathToFileSet(tgt, std::string(this->TypeName), value,
                           this->TypeName, this->DefaultDescription, action);
    return true;
  }
  if (cmHasPrefix(prop, this->DirectoryPrefix)) {
    auto fileSetName = prop.substr(this->DirectoryPrefix.size());
    if (fileSetName.empty()) {
      impl->Makefile->IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat(this->ArbitraryDescription, " name cannot be empty."));
    } else {
      impl->AddDirectoryToFileSet(
        tgt, fileSetName, value, this->TypeName,
        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""),
        action);
    }
    return true;
  }
  if (cmHasPrefix(prop, this->PathPrefix)) {
    auto fileSetName = prop.substr(this->PathPrefix.size());
    if (fileSetName.empty()) {
      impl->Makefile->IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat(this->ArbitraryDescription, " name cannot be empty."));
    } else {
      impl->AddPathToFileSet(
        tgt, fileSetName, value, this->TypeName,
        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""),
        action);
    }
    return true;
  }
  return false;
}

std::pair<bool, cmValue> FileSetType::ReadProperties(
  cmTarget const* tgt, cmTargetInternals const* impl,
  const std::string& prop) const
{
  bool did_read = false;
  cmValue value = nullptr;
  if (prop == this->DefaultDirectoryProperty) {
    value = impl->GetFileSetDirectories(tgt, std::string(this->TypeName),
                                        this->TypeName);
    did_read = true;
  } else if (prop == this->DefaultPathProperty) {
    value =
      impl->GetFileSetPaths(tgt, std::string(this->TypeName), this->TypeName);
    did_read = true;
  } else if (prop == this->SelfEntries.PropertyName) {
    static std::string output;
    output = cmList::to_string(this->SelfEntries.Entries);
    value = cmValue(output);
    did_read = true;
  } else if (prop == this->InterfaceEntries.PropertyName) {
    static std::string output;
    output = cmList::to_string(this->InterfaceEntries.Entries);
    value = cmValue(output);
    did_read = true;
  } else if (cmHasPrefix(prop, this->DirectoryPrefix)) {
    std::string fileSetName = prop.substr(this->DirectoryPrefix.size());
    if (!fileSetName.empty()) {
      value = impl->GetFileSetDirectories(tgt, fileSetName, this->TypeName);
    }
    did_read = true;
  } else if (cmHasPrefix(prop, this->PathPrefix)) {
    std::string fileSetName = prop.substr(this->PathPrefix.size());
    if (!fileSetName.empty()) {
      value = impl->GetFileSetPaths(tgt, fileSetName, this->TypeName);
    }
    did_read = true;
  }
  return { did_read, value };
}

void FileSetType::AddFileSet(const std::string& name, cmFileSetVisibility vis,
                             cmListFileBacktrace bt)
{
  if (cmFileSetVisibilityIsForSelf(vis)) {
    this->SelfEntries.Entries.emplace_back(name, bt);
  }
  if (cmFileSetVisibilityIsForInterface(vis)) {
    this->InterfaceEntries.Entries.emplace_back(name, std::move(bt));
  }
}

template <typename ValueType>
bool UsageRequirementProperty::Write(
  cmTargetInternals const* impl, cm::optional<cmListFileBacktrace> const& bt,
  const std::string& prop, ValueType value, Action action)
{
  if (prop == this->Name) {
    this->WriteDirect(impl, bt, value, action);
    return true;
  }
  return false;
}

template <typename ValueType>
void UsageRequirementProperty::WriteDirect(
  cmTargetInternals const* impl, cm::optional<cmListFileBacktrace> const& bt,
  ValueType value, Action action)
{
  if (action == Action::Set) {
    this->Entries.clear();
  }
  if (value) {
    cmListFileBacktrace lfbt = impl->GetBacktrace(bt);
    if (action == Action::Prepend) {
      this->Entries.emplace(this->Entries.begin(), value, lfbt);
    } else if (action == Action::Set || cmNonempty(value) ||
               this->AppendBehavior == AppendEmpty::Yes) {
      this->Entries.emplace_back(value, lfbt);
    }
  }
}

void UsageRequirementProperty::WriteDirect(BT<std::string> value,
                                           Action action)
{
  if (action == Action::Set) {
    this->Entries.clear();
  }
  if (action == Action::Prepend) {
    this->Entries.emplace(this->Entries.begin(), std::move(value));
  } else {
    this->Entries.emplace_back(std::move(value));
  }
}

std::pair<bool, cmValue> UsageRequirementProperty::Read(
  const std::string& prop) const
{
  bool did_read = false;
  cmValue value = nullptr;
  if (prop == this->Name) {
    if (!this->Entries.empty()) {
      // Storage to back the returned `cmValue`.
      static std::string output;
      output = cmList::to_string(this->Entries);
      value = cmValue(output);
    }
    did_read = true;
  }
  return { did_read, value };
}

cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
                   Visibility vis, cmMakefile* mf, PerConfig perConfig)
  : impl(cm::make_unique<cmTargetInternals>())
{
  assert(mf);
  this->impl->TargetType = type;
  this->impl->Makefile = mf;
  this->impl->Name = name;
  this->impl->IsGeneratorProvided = false;
  this->impl->HaveInstallRule = false;
  this->impl->IsDLLPlatform = false;
  this->impl->IsAIX = false;
  this->impl->IsApple = false;
  this->impl->IsAndroid = false;
  this->impl->TargetVisibility = vis;
  this->impl->BuildInterfaceIncludesAppended = false;
  this->impl->PerConfig = (perConfig == PerConfig::Yes);

  // Check whether this is a DLL platform.
  this->impl->IsDLLPlatform =
    !this->impl->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")
       .empty();

  // Check whether we are targeting AIX.
  {
    std::string const& systemName =
      this->impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME");
    this->impl->IsAIX = (systemName == "AIX" || systemName == "OS400");
  }

  // Check whether we are targeting Apple.
  this->impl->IsApple = this->impl->Makefile->IsOn("APPLE");

  // Check whether we are targeting an Android platform.
  this->impl->IsAndroid = (this->impl->Makefile->GetSafeDefinition(
                             "CMAKE_SYSTEM_NAME") == "Android");

  // Save the backtrace of target construction.
  this->impl->Backtrace = this->impl->Makefile->GetBacktrace();
  if (this->impl->IsImported()) {
    this->impl->FindPackageStack = this->impl->Makefile->GetFindPackageStack();
  }

  if (this->IsNormal()) {
    // Initialize the INCLUDE_DIRECTORIES property based on the current value
    // of the same directory property:
    this->impl->IncludeDirectories.CopyFromEntries(
      this->impl->Makefile->GetIncludeDirectoriesEntries());

    {
      auto const& sysInc = this->impl->Makefile->GetSystemIncludeDirectories();
      this->impl->SystemIncludeDirectories.insert(sysInc.begin(),
                                                  sysInc.end());
    }

    this->impl->CompileOptions.CopyFromEntries(
      this->impl->Makefile->GetCompileOptionsEntries());
    this->impl->LinkOptions.CopyFromEntries(
      this->impl->Makefile->GetLinkOptionsEntries());
    this->impl->LinkDirectories.CopyFromEntries(
      this->impl->Makefile->GetLinkDirectoriesEntries());
  }

  // Record current policies for later use.
  this->impl->Makefile->RecordPolicies(this->impl->PolicyMap);

  if (this->impl->TargetType == cmStateEnums::INTERFACE_LIBRARY) {
    // This policy is checked in a few conditions. The properties relevant
    // to the policy are always ignored for cmStateEnums::INTERFACE_LIBRARY
    // targets,
    // so ensure that the conditions don't lead to nonsense.
    this->impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
  }

  std::set<TargetProperty::InitCondition> metConditions;
  metConditions.insert(TargetProperty::InitCondition::Always);
  if (this->CanCompileSources()) {
    metConditions.insert(TargetProperty::InitCondition::CanCompileSources);
  }
  if (this->GetGlobalGenerator()->IsXcode()) {
    metConditions.insert(TargetProperty::InitCondition::NeedsXcode);
    if (this->CanCompileSources()) {
      metConditions.insert(
        TargetProperty::InitCondition::NeedsXcodeAndCanCompileSources);
    }
  }
  if (!this->IsImported()) {
    metConditions.insert(TargetProperty::InitCondition::NonImportedTarget);
  }
  if (this->impl->TargetType != cmStateEnums::UTILITY &&
      this->impl->TargetType != cmStateEnums::GLOBAL_TARGET) {
    metConditions.insert(TargetProperty::InitCondition::NormalTarget);
    if (this->IsNormal()) {
      metConditions.insert(
        TargetProperty::InitCondition::NormalNonImportedTarget);
    }
    if (this->impl->TargetType != cmStateEnums::INTERFACE_LIBRARY) {
      metConditions.insert(TargetProperty::InitCondition::TargetWithArtifact);
      if (this->impl->TargetType != cmStateEnums::EXECUTABLE) {
        metConditions.insert(
          TargetProperty::InitCondition::NonExecutableWithArtifact);
      }
    }
    if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
        this->impl->TargetType == cmStateEnums::STATIC_LIBRARY) {
      metConditions.insert(
        TargetProperty::InitCondition::LinkableLibraryTarget);
    }
    if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY) {
      metConditions.insert(TargetProperty::InitCondition::SharedLibraryTarget);
    }
  }
  if (this->impl->TargetType == cmStateEnums::EXECUTABLE) {
    metConditions.insert(TargetProperty::InitCondition::ExecutableTarget);
  }
  if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
      this->impl->TargetType == cmStateEnums::EXECUTABLE) {
    metConditions.insert(
      TargetProperty::InitCondition::TargetWithSymbolExports);
  }
  if (this->impl->TargetType <= cmStateEnums::GLOBAL_TARGET) {
    metConditions.insert(TargetProperty::InitCondition::TargetWithCommands);
  }

  std::vector<std::string> configNames =
    mf->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
  for (auto& config : configNames) {
    config = cmSystemTools::UpperCase(config);
  }

  std::string defKey;
  defKey.reserve(128);
  defKey += "CMAKE_";
  auto initProperty = [this, mf, &defKey](const std::string& property,
                                          const char* default_value) {
    // special init for ENABLE_EXPORTS
    // For SHARED_LIBRARY, only CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS variable
    // is used
    // For EXECUTABLE, CMAKE_EXECUTABLE_ENABLE_EXPORTS or else
    // CMAKE_ENABLE_EXPORTS variables are used
    if (property == "ENABLE_EXPORTS"_s) {
      // Replace everything after "CMAKE_"
      defKey.replace(
        defKey.begin() + 6, defKey.end(),
        cmStrCat(this->impl->TargetType == cmStateEnums::EXECUTABLE
                   ? "EXECUTABLE"
                   : "SHARED_LIBRARY",
                 '_', property));
      if (cmValue value = mf->GetDefinition(defKey)) {
        this->SetProperty(property, value);
        return;
      }
      if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY) {
        if (default_value) {
          this->SetProperty(property, default_value);
        }
        return;
      }
    }

    // Replace everything after "CMAKE_"
    defKey.replace(defKey.begin() + 6, defKey.end(), property);
    if (cmValue value = mf->GetDefinition(defKey)) {
      this->SetProperty(property, value);
    } else if (default_value) {
      this->SetProperty(property, default_value);
    }
  };

  std::string dflt_storage;
  for (auto const& tp : StaticTargetProperties) {
    // Ignore properties that we have not met the condition for.
    if (!metConditions.count(tp.InitConditional)) {
      continue;
    }

    const char* dflt = nullptr;
    if (tp.Default) {
      dflt_storage = std::string(*tp.Default);
      dflt = dflt_storage.c_str();
    }

    if (tp.Repeat == TargetProperty::Repetition::Once) {
      initProperty(std::string(tp.Name), dflt);
    } else {
      std::string propertyName;
      for (auto const& configName : configNames) {
        if (tp.Repeat == TargetProperty::Repetition::PerConfig) {
          propertyName = cmStrCat(tp.Name, configName);
        } else if (tp.Repeat == TargetProperty::Repetition::PerConfigPrefix) {
          propertyName = cmStrCat(configName, tp.Name);
        }
        initProperty(propertyName, dflt);
      }
    }
  }

  // Clean up some property defaults.
  if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
      this->impl->TargetType == cmStateEnums::MODULE_LIBRARY) {
    this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
  }

  // check for "CMAKE_VS_GLOBALS" variable and set up target properties
  // if any
  cmValue globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
  if (globals) {
    const std::string genName = mf->GetGlobalGenerator()->GetName();
    if (cmHasLiteralPrefix(genName, "Visual Studio")) {
      cmList props{ *globals };
      const std::string vsGlobal = "VS_GLOBAL_";
      for (const std::string& i : props) {
        // split NAME=VALUE
        const std::string::size_type assignment = i.find('=');
        if (assignment != std::string::npos) {
          const std::string propName = vsGlobal + i.substr(0, assignment);
          const std::string propValue = i.substr(assignment + 1);
          initProperty(propName, propValue.c_str());
        }
      }
    }
  }

  if (!this->IsNormal() || mf->GetPropertyAsBool("SYSTEM")) {
    this->SetProperty("SYSTEM", "ON");
  }

  for (auto const& prop : mf->GetState()->GetPropertyDefinitions().GetMap()) {
    if (prop.first.second == cmProperty::TARGET &&
        !prop.second.GetInitializeFromVariable().empty()) {
      if (auto value =
            mf->GetDefinition(prop.second.GetInitializeFromVariable())) {
        this->SetProperty(prop.first.first, value);
      }
    }
  }
}

cmTarget::cmTarget(cmTarget&&) noexcept = default;
cmTarget::~cmTarget() = default;

cmTarget& cmTarget::operator=(cmTarget&&) noexcept = default;

cmStateEnums::TargetType cmTarget::GetType() const
{
  return this->impl->TargetType;
}

cmMakefile* cmTarget::GetMakefile() const
{
  return this->impl->Makefile;
}

cmPolicies::PolicyMap const& cmTarget::GetPolicyMap() const
{
  return this->impl->PolicyMap;
}

const std::string& cmTarget::GetName() const
{
  return this->impl->Name;
}

cmPolicies::PolicyStatus cmTarget::GetPolicyStatus(
  cmPolicies::PolicyID policy) const
{
  return this->impl->PolicyMap.Get(policy);
}

cmGlobalGenerator* cmTarget::GetGlobalGenerator() const
{
  return this->impl->Makefile->GetGlobalGenerator();
}

BTs<std::string> const* cmTarget::GetLanguageStandardProperty(
  const std::string& propertyName) const
{
  auto entry = this->impl->LanguageStandardProperties.find(propertyName);
  if (entry != this->impl->LanguageStandardProperties.end()) {
    return &entry->second;
  }

  return nullptr;
}

void cmTarget::SetLanguageStandardProperty(std::string const& lang,
                                           std::string const& value,
                                           const std::string& feature)
{
  cmListFileBacktrace featureBacktrace;
  for (auto const& entry : this->impl->CompileFeatures.Entries) {
    if (entry.Value == feature) {
      featureBacktrace = entry.Backtrace;
      break;
    }
  }

  BTs<std::string>& languageStandardProperty =
    this->impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")];
  if (languageStandardProperty.Value != value) {
    languageStandardProperty.Value = value;
    languageStandardProperty.Backtraces.clear();
  }
  languageStandardProperty.Backtraces.emplace_back(featureBacktrace);
}

void cmTarget::AddUtility(std::string const& name, bool cross,
                          cmMakefile const* mf)
{
  this->impl->Utilities.insert(BT<std::pair<std::string, bool>>(
    { name, cross }, mf ? mf->GetBacktrace() : cmListFileBacktrace()));
}

void cmTarget::AddUtility(BT<std::pair<std::string, bool>> util)
{
  this->impl->Utilities.emplace(std::move(util));
}

std::set<BT<std::pair<std::string, bool>>> const& cmTarget::GetUtilities()
  const
{
  return this->impl->Utilities;
}

cmListFileBacktrace const& cmTarget::GetBacktrace() const
{
  return this->impl->Backtrace;
}

cmFindPackageStack const& cmTarget::GetFindPackageStack() const
{
  return this->impl->FindPackageStack;
}

bool cmTarget::IsExecutableWithExports() const
{
  return (this->GetType() == cmStateEnums::EXECUTABLE &&
          this->GetPropertyAsBool("ENABLE_EXPORTS"));
}

bool cmTarget::IsSharedLibraryWithExports() const
{
  return (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
          this->GetPropertyAsBool("ENABLE_EXPORTS"));
}

bool cmTarget::IsFrameworkOnApple() const
{
  return ((this->GetType() == cmStateEnums::SHARED_LIBRARY ||
           this->GetType() == cmStateEnums::STATIC_LIBRARY) &&
          this->IsApple() && this->GetPropertyAsBool("FRAMEWORK"));
}

bool cmTarget::IsAppBundleOnApple() const
{
  return (this->GetType() == cmStateEnums::EXECUTABLE && this->IsApple() &&
          this->GetPropertyAsBool("MACOSX_BUNDLE"));
}

bool cmTarget::IsAndroidGuiExecutable() const
{
  return (this->GetType() == cmStateEnums::EXECUTABLE &&
          this->impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI"));
}

bool cmTarget::HasKnownObjectFileLocation(std::string* reason) const
{
  return this->GetGlobalGenerator()->HasKnownObjectFileLocation(*this, reason);
}

std::vector<cmCustomCommand> const& cmTarget::GetPreBuildCommands() const
{
  return this->impl->PreBuildCommands;
}

void cmTarget::AddPreBuildCommand(cmCustomCommand const& cmd)
{
  this->impl->PreBuildCommands.push_back(cmd);
}

void cmTarget::AddPreBuildCommand(cmCustomCommand&& cmd)
{
  this->impl->PreBuildCommands.push_back(std::move(cmd));
}

std::vector<cmCustomCommand> const& cmTarget::GetPreLinkCommands() const
{
  return this->impl->PreLinkCommands;
}

void cmTarget::AddPreLinkCommand(cmCustomCommand const& cmd)
{
  this->impl->PreLinkCommands.push_back(cmd);
}

void cmTarget::AddPreLinkCommand(cmCustomCommand&& cmd)
{
  this->impl->PreLinkCommands.push_back(std::move(cmd));
}

std::vector<cmCustomCommand> const& cmTarget::GetPostBuildCommands() const
{
  return this->impl->PostBuildCommands;
}

void cmTarget::AddPostBuildCommand(cmCustomCommand const& cmd)
{
  this->impl->PostBuildCommands.push_back(cmd);
}

void cmTarget::AddPostBuildCommand(cmCustomCommand&& cmd)
{
  this->impl->PostBuildCommands.push_back(std::move(cmd));
}

void cmTarget::AddTracedSources(std::vector<std::string> const& srcs)
{
  if (!srcs.empty()) {
    this->impl->Sources.WriteDirect(this->impl.get(), {},
                                    cmValue(cmJoin(srcs, ";")),
                                    UsageRequirementProperty::Action::Append);
  }
}

void cmTarget::AddSources(std::vector<std::string> const& srcs)
{
  std::vector<std::string> srcFiles;
  for (auto filename : srcs) {
    if (!cmGeneratorExpression::StartsWithGeneratorExpression(filename)) {
      if (!filename.empty()) {
        filename = this->impl->ProcessSourceItemCMP0049(filename);
        if (filename.empty()) {
          return;
        }
      }
      this->impl->Makefile->GetOrCreateSource(filename);
    }
    srcFiles.emplace_back(filename);
  }
  this->AddTracedSources(srcFiles);
}

std::string cmTargetInternals::ProcessSourceItemCMP0049(
  const std::string& s) const
{
  std::string src = s;

  // For backwards compatibility replace variables in source names.
  // This should eventually be removed.
  this->Makefile->ExpandVariablesInString(src);
  if (src != s) {
    std::ostringstream e;
    bool noMessage = false;
    MessageType messageType = MessageType::AUTHOR_WARNING;
    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0049)) {
      case cmPolicies::WARN:
        e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0049) << "\n";
        break;
      case cmPolicies::OLD:
        noMessage = true;
        break;
      case cmPolicies::REQUIRED_ALWAYS:
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::NEW:
        messageType = MessageType::FATAL_ERROR;
    }
    if (!noMessage) {
      e << "Legacy variable expansion in source file \"" << s
        << "\" expanded to \"" << src << "\" in target \"" << this->Name
        << "\".  This behavior will be removed in a "
           "future version of CMake.";
      this->Makefile->IssueMessage(messageType, e.str());
      if (messageType == MessageType::FATAL_ERROR) {
        return "";
      }
    }
  }
  return src;
}

std::string cmTarget::GetSourceCMP0049(const std::string& s)
{
  return this->impl->ProcessSourceItemCMP0049(s);
}

struct CreateLocation
{
  cmMakefile const* Makefile;

  CreateLocation(cmMakefile const* mf)
    : Makefile(mf)
  {
  }

  cmSourceFileLocation operator()(const std::string& filename) const
  {
    return cmSourceFileLocation(this->Makefile, filename);
  }
};

struct LocationMatcher
{
  const cmSourceFileLocation& Needle;

  LocationMatcher(const cmSourceFileLocation& needle)
    : Needle(needle)
  {
  }

  bool operator()(cmSourceFileLocation& loc)
  {
    return loc.Matches(this->Needle);
  }
};

struct TargetPropertyEntryFinder
{
private:
  const cmSourceFileLocation& Needle;

public:
  TargetPropertyEntryFinder(const cmSourceFileLocation& needle)
    : Needle(needle)
  {
  }

  bool operator()(BT<std::string> const& entry)
  {
    cmList files{ entry.Value };
    std::vector<cmSourceFileLocation> locations;
    locations.reserve(files.size());
    std::transform(files.begin(), files.end(), std::back_inserter(locations),
                   CreateLocation(this->Needle.GetMakefile()));

    return std::find_if(locations.begin(), locations.end(),
                        LocationMatcher(this->Needle)) != locations.end();
  }
};

cmSourceFile* cmTarget::AddSource(const std::string& src, bool before)
{
  cmSourceFileLocation sfl(this->impl->Makefile, src,
                           cmSourceFileLocationKind::Known);
  auto const& sources = this->impl->Sources.Entries;
  if (std::find_if(sources.begin(), sources.end(),
                   TargetPropertyEntryFinder(sfl)) == sources.end()) {
    this->impl->Sources.WriteDirect(
      this->impl.get(), {}, cmValue(src),
      before ? UsageRequirementProperty::Action::Prepend
             : UsageRequirementProperty::Action::Append);
  }
  if (cmGeneratorExpression::Find(src) != std::string::npos) {
    return nullptr;
  }
  return this->impl->Makefile->GetOrCreateSource(
    src, false, cmSourceFileLocationKind::Known);
}

void cmTarget::ClearDependencyInformation(cmMakefile& mf) const
{
  std::string depname = cmStrCat(this->GetName(), "_LIB_DEPENDS");
  mf.RemoveCacheDefinition(depname);
}

std::string cmTarget::GetDebugGeneratorExpressions(
  const std::string& value, cmTargetLinkLibraryType llt) const
{
  if (llt == GENERAL_LibraryType) {
    return value;
  }

  // Get the list of configurations considered to be DEBUG.
  std::vector<std::string> debugConfigs =
    this->impl->Makefile->GetCMakeInstance()->GetDebugConfigs();

  std::string configString = "$<CONFIG:" + debugConfigs[0] + ">";

  if (debugConfigs.size() > 1) {
    for (std::string const& conf : cmMakeRange(debugConfigs).advance(1)) {
      configString += ",$<CONFIG:" + conf + ">";
    }
    configString = "$<OR:" + configString + ">";
  }

  if (llt == OPTIMIZED_LibraryType) {
    configString = "$<NOT:" + configString + ">";
  }
  return "$<" + configString + ":" + value + ">";
}

static std::string targetNameGenex(const std::string& lib)
{
  return "$<TARGET_NAME:" + lib + ">";
}

bool cmTarget::PushTLLCommandTrace(TLLSignature signature,
                                   cmListFileContext const& lfc)
{
  bool ret = true;
  if (!this->impl->TLLCommands.empty()) {
    if (this->impl->TLLCommands.back().first != signature) {
      ret = false;
    }
  }
  if (this->impl->TLLCommands.empty() ||
      this->impl->TLLCommands.back().second != lfc) {
    this->impl->TLLCommands.emplace_back(signature, lfc);
  }
  return ret;
}

void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
{
  const char* sigString =
    (sig == cmTarget::KeywordTLLSignature ? "keyword" : "plain");
  s << "The uses of the " << sigString << " signature are here:\n";
  for (auto const& cmd : this->impl->TLLCommands) {
    if (cmd.first == sig) {
      cmListFileContext lfc = cmd.second;
      lfc.FilePath = cmSystemTools::RelativeIfUnder(
        this->impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath);
      s << " * " << lfc << '\n';
    }
  }
}

std::string const& cmTarget::GetInstallPath() const
{
  return this->impl->InstallPath;
}

void cmTarget::SetInstallPath(std::string const& name)
{
  this->impl->InstallPath = name;
}

std::string const& cmTarget::GetRuntimeInstallPath() const
{
  return this->impl->RuntimeInstallPath;
}

void cmTarget::SetRuntimeInstallPath(std::string const& name)
{
  this->impl->RuntimeInstallPath = name;
}

bool cmTarget::GetHaveInstallRule() const
{
  return this->impl->HaveInstallRule;
}

void cmTarget::SetHaveInstallRule(bool hir)
{
  this->impl->HaveInstallRule = hir;
}

void cmTarget::AddInstallGenerator(cmInstallTargetGenerator* g)
{
  this->impl->InstallGenerators.emplace_back(g);
}

std::vector<cmInstallTargetGenerator*> const& cmTarget::GetInstallGenerators()
  const
{
  return this->impl->InstallGenerators;
}

bool cmTarget::GetIsGeneratorProvided() const
{
  return this->impl->IsGeneratorProvided;
}

void cmTarget::SetIsGeneratorProvided(bool igp)
{
  this->impl->IsGeneratorProvided = igp;
}

cmTarget::LinkLibraryVectorType const& cmTarget::GetOriginalLinkLibraries()
  const
{
  return this->impl->OriginalLinkLibraries;
}

void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
                              cmTargetLinkLibraryType llt)
{
  cmTarget* tgt = mf.FindTargetToUse(lib);
  {
    const bool isNonImportedTarget = tgt && !tgt->IsImported();

    const std::string libName =
      (isNonImportedTarget && llt != GENERAL_LibraryType)
      ? targetNameGenex(lib)
      : lib;
    this->AppendProperty("LINK_LIBRARIES",
                         this->GetDebugGeneratorExpressions(libName, llt),
                         mf.GetBacktrace());
  }

  if (cmGeneratorExpression::Find(lib) != std::string::npos ||
      (tgt &&
       (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
        tgt->GetType() == cmStateEnums::OBJECT_LIBRARY)) ||
      (this->impl->Name == lib)) {
    return;
  }

  this->impl->OriginalLinkLibraries.emplace_back(lib, llt);

  // Add the explicit dependency information for libraries. This is
  // simply a set of libraries separated by ";". There should always
  // be a trailing ";". These library names are not canonical, in that
  // they may be "-framework x", "-ly", "/path/libz.a", etc.
  // We shouldn't remove duplicates here because external libraries
  // may be purposefully duplicated to handle recursive dependencies,
  // and we removing one instance will break the link line. Duplicates
  // will be appropriately eliminated at emit time.
  if (this->impl->TargetType >= cmStateEnums::STATIC_LIBRARY &&
      this->impl->TargetType <= cmStateEnums::MODULE_LIBRARY &&
      (this->GetPolicyStatusCMP0073() == cmPolicies::OLD ||
       this->GetPolicyStatusCMP0073() == cmPolicies::WARN)) {
    std::string targetEntry = cmStrCat(this->impl->Name, "_LIB_DEPENDS");
    std::string dependencies;
    cmValue old_val = mf.GetDefinition(targetEntry);
    if (old_val) {
      dependencies += *old_val;
    }
    switch (llt) {
      case GENERAL_LibraryType:
        dependencies += "general";
        break;
      case DEBUG_LibraryType:
        dependencies += "debug";
        break;
      case OPTIMIZED_LibraryType:
        dependencies += "optimized";
        break;
    }
    dependencies += ";";
    dependencies += lib;
    dependencies += ";";
    mf.AddCacheDefinition(targetEntry, dependencies,
                          "Dependencies for the target", cmStateEnums::STATIC);
  }
}

void cmTarget::AddSystemIncludeDirectories(const std::set<std::string>& incs)
{
  this->impl->SystemIncludeDirectories.insert(incs.begin(), incs.end());
}

std::set<std::string> const& cmTarget::GetSystemIncludeDirectories() const
{
  return this->impl->SystemIncludeDirectories;
}

void cmTarget::AddInstallIncludeDirectories(cmTargetExport const& te,
                                            cmStringRange const& incs)
{
  std::copy(
    incs.begin(), incs.end(),
    std::back_inserter(this->impl->InstallIncludeDirectoriesEntries[&te]));
}

cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries(
  cmTargetExport const& te) const
{
  auto i = this->impl->InstallIncludeDirectoriesEntries.find(&te);
  if (i == this->impl->InstallIncludeDirectoriesEntries.end()) {
    decltype(i->second) empty;
    return cmMakeRange(empty);
  }
  return cmMakeRange(i->second);
}

cmBTStringRange cmTarget::GetIncludeDirectoriesEntries() const
{
  return cmMakeRange(this->impl->IncludeDirectories.Entries);
}

cmBTStringRange cmTarget::GetCompileOptionsEntries() const
{
  return cmMakeRange(this->impl->CompileOptions.Entries);
}

cmBTStringRange cmTarget::GetCompileFeaturesEntries() const
{
  return cmMakeRange(this->impl->CompileFeatures.Entries);
}

cmBTStringRange cmTarget::GetCompileDefinitionsEntries() const
{
  return cmMakeRange(this->impl->CompileDefinitions.Entries);
}

cmBTStringRange cmTarget::GetPrecompileHeadersEntries() const
{
  return cmMakeRange(this->impl->PrecompileHeaders.Entries);
}

cmBTStringRange cmTarget::GetSourceEntries() const
{
  return cmMakeRange(this->impl->Sources.Entries);
}

cmBTStringRange cmTarget::GetLinkOptionsEntries() const
{
  return cmMakeRange(this->impl->LinkOptions.Entries);
}

cmBTStringRange cmTarget::GetLinkDirectoriesEntries() const
{
  return cmMakeRange(this->impl->LinkDirectories.Entries);
}

cmBTStringRange cmTarget::GetLinkImplementationEntries() const
{
  return cmMakeRange(this->impl->LinkLibraries.Entries);
}

cmBTStringRange cmTarget::GetLinkInterfaceEntries() const
{
  return cmMakeRange(this->impl->InterfaceLinkLibraries.Entries);
}

cmBTStringRange cmTarget::GetLinkInterfaceDirectEntries() const
{
  return cmMakeRange(this->impl->InterfaceLinkLibrariesDirect.Entries);
}

cmBTStringRange cmTarget::GetLinkInterfaceDirectExcludeEntries() const
{
  return cmMakeRange(this->impl->InterfaceLinkLibrariesDirectExclude.Entries);
}

void cmTarget::CopyPolicyStatuses(cmTarget const* tgt)
{
  // Normal targets cannot be the target of a copy.
  assert(!this->IsNormal());
  // Imported targets cannot be the target of a copy.
  assert(!this->IsImported());
  // Only imported targets can be the source of a copy.
  assert(tgt->IsImported());

  this->impl->PolicyMap = tgt->impl->PolicyMap;
}

void cmTarget::CopyImportedCxxModulesEntries(cmTarget const* tgt)
{
  // Normal targets cannot be the target of a copy.
  assert(!this->IsNormal());
  // Imported targets cannot be the target of a copy.
  assert(!this->IsImported());
  // Only imported targets can be the source of a copy.
  assert(tgt->IsImported());

  this->impl->IncludeDirectories.Entries.clear();
  this->impl->IncludeDirectories.CopyFromEntries(
    cmMakeRange(tgt->impl->ImportedCxxModulesIncludeDirectories.Entries));
  this->impl->CompileDefinitions.Entries.clear();
  this->impl->CompileDefinitions.CopyFromEntries(
    cmMakeRange(tgt->impl->ImportedCxxModulesCompileDefinitions.Entries));
  this->impl->CompileFeatures.Entries.clear();
  this->impl->CompileFeatures.CopyFromEntries(
    cmMakeRange(tgt->impl->ImportedCxxModulesCompileFeatures.Entries));
  this->impl->CompileOptions.Entries.clear();
  this->impl->CompileOptions.CopyFromEntries(
    cmMakeRange(tgt->impl->ImportedCxxModulesCompileOptions.Entries));
  this->impl->LinkLibraries.Entries.clear();
  this->impl->LinkLibraries.CopyFromEntries(
    cmMakeRange(tgt->impl->ImportedCxxModulesLinkLibraries.Entries));

  // Copy the C++ module fileset entries from `tgt`'s `INTERFACE` to this
  // target's `PRIVATE`.
  this->impl->CxxModulesFileSets.SelfEntries.Entries.clear();
  this->impl->CxxModulesFileSets.SelfEntries.Entries =
    tgt->impl->CxxModulesFileSets.InterfaceEntries.Entries;
}

void cmTarget::CopyImportedCxxModulesProperties(cmTarget const* tgt)
{
  // Normal targets cannot be the target of a copy.
  assert(!this->IsNormal());
  // Imported targets cannot be the target of a copy.
  assert(!this->IsImported());
  // Only imported targets can be the source of a copy.
  assert(tgt->IsImported());

  // The list of properties that are relevant here include:
  // - compilation-specific properties for any language or platform
  // - compilation-specific properties for C++
  // - build graph-specific properties that affect compilation
  // - IDE metadata properties
  // - static analysis properties

  static const std::string propertiesToCopy[] = {
    // Compilation properties
    "DEFINE_SYMBOL",
    "DEPRECATION",
    "NO_SYSTEM_FROM_IMPORTED",
    "POSITION_INDEPENDENT_CODE",
    "VISIBILITY_INLINES_HIDDEN",
    // -- Platforms
    // ---- Android
    "ANDROID_API",
    "ANDROID_API_MIN",
    "ANDROID_ARCH",
    "ANDROID_STL_TYPE",
    // ---- macOS
    "OSX_ARCHITECTURES",
    // ---- Windows
    "MSVC_DEBUG_INFORMATION_FORMAT",
    "MSVC_RUNTIME_LIBRARY",
    "VS_PLATFORM_TOOLSET",
    // ---- OpenWatcom
    "WATCOM_RUNTIME_LIBRARY",
    // -- Language
    // ---- C++
    "CXX_COMPILER_LAUNCHER",
    "CXX_STANDARD",
    "CXX_STANDARD_REQUIRED",
    "CXX_EXTENSIONS",
    "CXX_VISIBILITY_PRESET",

    // Static analysis
    "CXX_CLANG_TIDY",
    "CXX_CLANG_TIDY_EXPORT_FIXES_DIR",
    "CXX_CPPLINT",
    "CXX_CPPCHECK",
    "CXX_INCLUDE_WHAT_YOU_USE",

    // Build graph properties
    "EXCLUDE_FROM_ALL",
    "EXCLUDE_FROM_DEFAULT_BUILD",
    "OPTIMIZE_DEPENDENCIES",
    // -- Ninja
    "JOB_POOL_COMPILE",
    // -- Visual Studio
    "VS_NO_COMPILE_BATCHING",
    "VS_PROJECT_IMPORT",

    // Metadata
    "EchoString",
    "EXPORT_COMPILE_COMMANDS",
    "FOLDER",
    "LABELS",
    "PROJECT_LABEL",
    "SYSTEM",
  };

  auto copyProperty = [this, tgt](std::string const& prop) -> cmValue {
    cmValue value = tgt->GetProperty(prop);
    // Always set the property; it may have been explicitly unset.
    this->SetProperty(prop, value);
    return value;
  };

  for (auto const& prop : propertiesToCopy) {
    copyProperty(prop);
  }

  static const cm::static_string_view perConfigPropertiesToCopy[] = {
    "EXCLUDE_FROM_DEFAULT_BUILD_"_s,
    "IMPORTED_CXX_MODULES_"_s,
    "MAP_IMPORTED_CONFIG_"_s,
    "OSX_ARCHITECTURES_"_s,
  };

  std::vector<std::string> configNames =
    this->impl->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
  for (std::string const& configName : configNames) {
    std::string configUpper = cmSystemTools::UpperCase(configName);
    for (auto const& perConfigProp : perConfigPropertiesToCopy) {
      copyProperty(cmStrCat(perConfigProp, configUpper));
    }
  }

  if (this->GetGlobalGenerator()->IsXcode()) {
    cmValue xcodeGenerateScheme = copyProperty("XCODE_GENERATE_SCHEME");

    // TODO: Make sure these show up on the imported target in the first place
    // XCODE_ATTRIBUTE_???

    if (xcodeGenerateScheme.IsOn()) {
#ifdef __APPLE__
      static const std::string xcodeSchemePropertiesToCopy[] = {
        // FIXME: Do all of these apply? Do they matter?
        "XCODE_SCHEME_ADDRESS_SANITIZER",
        "XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN",
        "XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER",
        "XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS",
        "XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE",
        "XCODE_SCHEME_ENABLE_GPU_API_VALIDATION",
        "XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION",
        "XCODE_SCHEME_GUARD_MALLOC",
        "XCODE_SCHEME_LAUNCH_CONFIGURATION",
        "XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP",
        "XCODE_SCHEME_MALLOC_GUARD_EDGES",
        "XCODE_SCHEME_MALLOC_SCRIBBLE",
        "XCODE_SCHEME_MALLOC_STACK",
        "XCODE_SCHEME_THREAD_SANITIZER",
        "XCODE_SCHEME_THREAD_SANITIZER_STOP",
        "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER",
        "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP",
        "XCODE_SCHEME_ZOMBIE_OBJECTS",
      };

      for (auto const& xcodeProperty : xcodeSchemePropertiesToCopy) {
        copyProperty(xcodeProperty);
      }
#endif
    }
  }
}

cmBTStringRange cmTarget::GetHeaderSetsEntries() const
{
  return cmMakeRange(this->impl->HeadersFileSets.SelfEntries.Entries);
}

cmBTStringRange cmTarget::GetCxxModuleSetsEntries() const
{
  return cmMakeRange(this->impl->CxxModulesFileSets.SelfEntries.Entries);
}

cmBTStringRange cmTarget::GetInterfaceHeaderSetsEntries() const
{
  return cmMakeRange(this->impl->HeadersFileSets.InterfaceEntries.Entries);
}

cmBTStringRange cmTarget::GetInterfaceCxxModuleSetsEntries() const
{
  return cmMakeRange(this->impl->CxxModulesFileSets.InterfaceEntries.Entries);
}

namespace {
#define MAKE_PROP(PROP) const std::string prop##PROP = #PROP
MAKE_PROP(C_STANDARD);
MAKE_PROP(CXX_STANDARD);
MAKE_PROP(CUDA_STANDARD);
MAKE_PROP(HIP_STANDARD);
MAKE_PROP(OBJC_STANDARD);
MAKE_PROP(OBJCXX_STANDARD);
MAKE_PROP(COMPILE_DEFINITIONS);
MAKE_PROP(COMPILE_FEATURES);
MAKE_PROP(COMPILE_OPTIONS);
MAKE_PROP(PRECOMPILE_HEADERS);
MAKE_PROP(PRECOMPILE_HEADERS_REUSE_FROM);
MAKE_PROP(CUDA_CUBIN_COMPILATION);
MAKE_PROP(CUDA_FATBIN_COMPILATION);
MAKE_PROP(CUDA_OPTIX_COMPILATION);
MAKE_PROP(CUDA_PTX_COMPILATION);
MAKE_PROP(IMPORTED);
MAKE_PROP(IMPORTED_GLOBAL);
MAKE_PROP(INCLUDE_DIRECTORIES);
MAKE_PROP(LINK_OPTIONS);
MAKE_PROP(IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES);
MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS);
MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_FEATURES);
MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_OPTIONS);
MAKE_PROP(IMPORTED_CXX_MODULES_LINK_LIBRARIES);
MAKE_PROP(LINK_DIRECTORIES);
MAKE_PROP(LINK_LIBRARIES);
MAKE_PROP(MANUALLY_ADDED_DEPENDENCIES);
MAKE_PROP(NAME);
MAKE_PROP(SOURCES);
MAKE_PROP(TYPE);
MAKE_PROP(BINARY_DIR);
MAKE_PROP(SOURCE_DIR);
MAKE_PROP(FALSE);
MAKE_PROP(TRUE);
MAKE_PROP(INTERFACE_LINK_LIBRARIES);
MAKE_PROP(INTERFACE_LINK_LIBRARIES_DIRECT);
MAKE_PROP(INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE);
#undef MAKE_PROP
}

namespace {

enum class ReadOnlyCondition
{
  All,
  Imported,
  NonImported,
};

struct ReadOnlyProperty
{
  ReadOnlyProperty(ReadOnlyCondition cond)
    : Condition{ cond }
    , Policy{} {};
  ReadOnlyProperty(ReadOnlyCondition cond, cmPolicies::PolicyID id)
    : Condition{ cond }
    , Policy{ id } {};

  ReadOnlyCondition Condition;
  cm::optional<cmPolicies::PolicyID> Policy;

  std::string message(const std::string& prop, cmTarget* target) const
  {
    std::string msg;
    if (this->Condition == ReadOnlyCondition::All) {
      msg = " property is read-only for target(\"";
    } else if (this->Condition == ReadOnlyCondition::Imported) {
      msg = " property can't be set on imported targets(\"";
    } else if (this->Condition == ReadOnlyCondition::NonImported) {
      msg = " property can't be set on non-imported targets(\"";
    }
    return cmStrCat(prop, msg, target->GetName(), "\")\n");
  }

  bool isReadOnly(const std::string& prop, cmMakefile* context,
                  cmTarget* target) const
  {
    auto importedTarget = target->IsImported();
    bool matchingCondition = true;
    if ((!importedTarget && this->Condition == ReadOnlyCondition::Imported) ||
        (importedTarget &&
         this->Condition == ReadOnlyCondition::NonImported)) {
      matchingCondition = false;
    }
    if (!matchingCondition) {
      // Not read-only in this scenario
      return false;
    }

    bool readOnly = true;
    if (!this->Policy) {
      // No policy associated, so is always read-only
      context->IssueMessage(MessageType::FATAL_ERROR,
                            this->message(prop, target));
    } else {
      switch (target->GetPolicyStatus(*this->Policy)) {
        case cmPolicies::WARN:
          context->IssueMessage(
            MessageType::AUTHOR_WARNING,
            cmPolicies::GetPolicyWarning(cmPolicies::CMP0160) + "\n" +
              this->message(prop, target));
          CM_FALLTHROUGH;
        case cmPolicies::OLD:
          readOnly = false;
          break;
        case cmPolicies::REQUIRED_ALWAYS:
        case cmPolicies::REQUIRED_IF_USED:
        case cmPolicies::NEW:
          context->IssueMessage(MessageType::FATAL_ERROR,
                                this->message(prop, target));
          break;
      }
    }
    return readOnly;
  }
};

bool IsSetableProperty(cmMakefile* context, cmTarget* target,
                       const std::string& prop)
{
  using ROC = ReadOnlyCondition;
  static std::unordered_map<std::string, ReadOnlyProperty> const readOnlyProps{
    { "EXPORT_NAME", { ROC::Imported } },
    { "HEADER_SETS", { ROC::All } },
    { "IMPORTED_GLOBAL", { ROC::NonImported } },
    { "INTERFACE_HEADER_SETS", { ROC::All } },
    { "MANUALLY_ADDED_DEPENDENCIES", { ROC::All } },
    { "NAME", { ROC::All } },
    { "SOURCES", { ROC::Imported } },
    { "TYPE", { ROC::All } },
    { "ALIAS_GLOBAL", { ROC::All, cmPolicies::CMP0160 } },
    { "BINARY_DIR", { ROC::All, cmPolicies::CMP0160 } },
    { "CXX_MODULE_SETS", { ROC::All, cmPolicies::CMP0160 } },
    { "IMPORTED", { ROC::All, cmPolicies::CMP0160 } },
    { "INTERFACE_CXX_MODULE_SETS", { ROC::All, cmPolicies::CMP0160 } },
    { "LOCATION", { ROC::All, cmPolicies::CMP0160 } },
    { "LOCATION_CONFIG", { ROC::All, cmPolicies::CMP0160 } },
    { "SOURCE_DIR", { ROC::All, cmPolicies::CMP0160 } }
  };

  auto it = readOnlyProps.find(prop);

  if (it != readOnlyProps.end()) {
    return !(it->second.isReadOnly(prop, context, target));
  }
  return true;
}
}

void cmTarget::SetProperty(const std::string& prop, cmValue value)
{
  if (!IsSetableProperty(this->impl->Makefile, this, prop)) {
    return;
  }

  UsageRequirementProperty* usageRequirements[] = {
    &this->impl->IncludeDirectories,
    &this->impl->CompileOptions,
    &this->impl->CompileFeatures,
    &this->impl->CompileDefinitions,
    &this->impl->PrecompileHeaders,
    &this->impl->Sources,
    &this->impl->LinkOptions,
    &this->impl->LinkDirectories,
    &this->impl->LinkLibraries,
    &this->impl->InterfaceLinkLibraries,
    &this->impl->InterfaceLinkLibrariesDirect,
    &this->impl->InterfaceLinkLibrariesDirectExclude,
    &this->impl->ImportedCxxModulesIncludeDirectories,
    &this->impl->ImportedCxxModulesCompileDefinitions,
    &this->impl->ImportedCxxModulesCompileFeatures,
    &this->impl->ImportedCxxModulesCompileOptions,
    &this->impl->ImportedCxxModulesLinkLibraries,
  };

  for (auto* usageRequirement : usageRequirements) {
    if (usageRequirement->Write(this->impl.get(), {}, prop, value,
                                UsageRequirementProperty::Action::Set)) {
      return;
    }
  }

  FileSetType* fileSetTypes[] = {
    &this->impl->HeadersFileSets,
    &this->impl->CxxModulesFileSets,
  };

  for (auto* fileSetType : fileSetTypes) {
    if (fileSetType->WriteProperties(this, this->impl.get(), prop, value,
                                     FileSetType::Action::Set)) {
      return;
    }
  }

  if (prop == propIMPORTED_GLOBAL) {
    if (!cmIsOn(value)) {
      std::ostringstream e;
      e << "IMPORTED_GLOBAL property can't be set to FALSE on targets (\""
        << this->impl->Name << "\")\n";
      this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
      return;
    }
    /* no need to change anything if value does not change */
    if (!this->IsImportedGloballyVisible()) {
      this->impl->TargetVisibility = Visibility::ImportedGlobally;
      this->GetGlobalGenerator()->IndexTarget(this);
    }
  } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME") &&
             !this->impl->CheckImportedLibName(
               prop,
               value ? value
                     : std::string{})) { // NOLINT(bugprone-branch-clone)
    /* error was reported by check method */
  } else if (prop == propCUDA_CUBIN_COMPILATION ||
             prop == propCUDA_FATBIN_COMPILATION ||
             prop == propCUDA_OPTIX_COMPILATION ||
             prop == propCUDA_PTX_COMPILATION) {
    auto const& compiler =
      this->impl->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
    auto const& compilerVersion =
      this->impl->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_VERSION");
    if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
      auto e =
        cmStrCat(prop, " property can only be applied to OBJECT targets(",
                 this->impl->Name, ")\n");
      this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
      return;
    }
    const bool flag_found =
      (prop == propCUDA_PTX_COMPILATION &&
       this->impl->Makefile->GetDefinition("_CMAKE_CUDA_PTX_FLAG")) ||
      (prop == propCUDA_CUBIN_COMPILATION &&
       this->impl->Makefile->GetDefinition("_CMAKE_CUDA_CUBIN_FLAG")) ||
      (prop == propCUDA_FATBIN_COMPILATION &&
       this->impl->Makefile->GetDefinition("_CMAKE_CUDA_FATBIN_FLAG")) ||
      (prop == propCUDA_OPTIX_COMPILATION &&
       this->impl->Makefile->GetDefinition("_CMAKE_CUDA_OPTIX_FLAG"));
    if (flag_found) {
      this->impl->Properties.SetProperty(prop, value);
    } else {
      auto e = cmStrCat(prop, " property is not supported by ", compiler,
                        "  compiler version ", compilerVersion, ".");
      this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
      return;
    }
  } else if (prop == propPRECOMPILE_HEADERS_REUSE_FROM) {
    if (this->GetProperty("PRECOMPILE_HEADERS")) {
      std::ostringstream e;
      e << "PRECOMPILE_HEADERS property is already set on target (\""
        << this->impl->Name << "\")\n";
      this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
      return;
    }
    auto* reusedTarget = this->impl->Makefile->GetCMakeInstance()
                           ->GetGlobalGenerator()
                           ->FindTarget(value);
    if (!reusedTarget) {
      const std::string e(
        "PRECOMPILE_HEADERS_REUSE_FROM set with non existing target");
      this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
      return;
    }

    std::string reusedFrom = reusedTarget->GetSafeProperty(prop);
    if (reusedFrom.empty()) {
      reusedFrom = *value;
    }

    this->impl->Properties.SetProperty(prop, reusedFrom);

    reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom);
    reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
                              cmStrCat(reusedFrom, ".dir/"));

    cmValue tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
    this->SetProperty("COMPILE_PDB_NAME", tmp);
    this->AddUtility(reusedFrom, false, this->impl->Makefile);
  } else if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
             prop == propCUDA_STANDARD || prop == propHIP_STANDARD ||
             prop == propOBJC_STANDARD || prop == propOBJCXX_STANDARD) {
    if (value) {
      this->impl->LanguageStandardProperties[prop] =
        BTs<std::string>(value, this->impl->Makefile->GetBacktrace());
    } else {
      this->impl->LanguageStandardProperties.erase(prop);
    }
  } else {
    this->impl->Properties.SetProperty(prop, value);
  }
}

void cmTarget::AppendProperty(const std::string& prop,
                              const std::string& value,
                              cm::optional<cmListFileBacktrace> const& bt,
                              bool asString)
{
  if (!IsSetableProperty(this->impl->Makefile, this, prop)) {
    return;
  }
  if (prop == "IMPORTED_GLOBAL") {
    this->impl->Makefile->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("IMPORTED_GLOBAL property can't be appended, only set on "
               "imported targets (\"",
               this->impl->Name, "\")\n"));
  }
  if (prop == propPRECOMPILE_HEADERS &&
      this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) {
    this->impl->Makefile->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat(
        "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target (\"",
        this->impl->Name, "\")\n"));
    return;
  }

  UsageRequirementProperty* usageRequirements[] = {
    &this->impl->IncludeDirectories,
    &this->impl->CompileOptions,
    &this->impl->CompileFeatures,
    &this->impl->CompileDefinitions,
    &this->impl->PrecompileHeaders,
    &this->impl->Sources,
    &this->impl->LinkOptions,
    &this->impl->LinkDirectories,
    &this->impl->LinkLibraries,
    &this->impl->InterfaceLinkLibraries,
    &this->impl->InterfaceLinkLibrariesDirect,
    &this->impl->InterfaceLinkLibrariesDirectExclude,
    &this->impl->ImportedCxxModulesIncludeDirectories,
    &this->impl->ImportedCxxModulesCompileDefinitions,
    &this->impl->ImportedCxxModulesCompileFeatures,
    &this->impl->ImportedCxxModulesCompileOptions,
    &this->impl->ImportedCxxModulesLinkLibraries,
  };

  for (auto* usageRequirement : usageRequirements) {
    if (usageRequirement->Write(this->impl.get(), bt, prop, cmValue(value),
                                UsageRequirementProperty::Action::Append)) {
      return;
    }
  }

  FileSetType* fileSetTypes[] = {
    &this->impl->HeadersFileSets,
    &this->impl->CxxModulesFileSets,
  };

  for (auto* fileSetType : fileSetTypes) {
    if (fileSetType->WriteProperties(this, this->impl.get(), prop, value,
                                     FileSetType::Action::Append)) {
      return;
    }
  }

  if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
    this->impl->Makefile->IssueMessage(
      MessageType::FATAL_ERROR, prop + " property may not be APPENDed.");
  } else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" ||
             prop == "CUDA_STANDARD" || prop == "HIP_STANDARD" ||
             prop == "OBJC_STANDARD" || prop == "OBJCXX_STANDARD") {
    this->impl->Makefile->IssueMessage(
      MessageType::FATAL_ERROR, prop + " property may not be appended.");
  } else {
    this->impl->Properties.AppendProperty(prop, value, asString);
  }
}

template <typename ValueType>
void cmTargetInternals::AddDirectoryToFileSet(cmTarget* self,
                                              std::string const& fileSetName,
                                              ValueType value,
                                              cm::string_view fileSetType,
                                              cm::string_view description,
                                              FileSetType::Action action)
{
  auto* fileSet = self->GetFileSet(fileSetName);
  if (!fileSet) {
    this->Makefile->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat(description, "has not yet been created."));
    return;
  }
  if (fileSet->GetType() != fileSetType) {
    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                 cmStrCat("File set \"", fileSetName,
                                          "\" is not of type \"", fileSetType,
                                          "\"."));
    return;
  }
  if (action == FileSetType::Action::Set) {
    fileSet->ClearDirectoryEntries();
  }
  if (cmNonempty(value)) {
    fileSet->AddDirectoryEntry(
      BT<std::string>(value, this->Makefile->GetBacktrace()));
  }
}

template <typename ValueType>
void cmTargetInternals::AddPathToFileSet(cmTarget* self,
                                         std::string const& fileSetName,
                                         ValueType value,
                                         cm::string_view fileSetType,
                                         cm::string_view description,
                                         FileSetType::Action action)
{
  auto* fileSet = self->GetFileSet(fileSetName);
  if (!fileSet) {
    this->Makefile->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat(description, "has not yet been created."));
    return;
  }
  if (fileSet->GetType() != fileSetType) {
    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                 cmStrCat("File set \"", fileSetName,
                                          "\" is not of type \"", fileSetType,
                                          "\"."));
    return;
  }
  if (action == FileSetType::Action::Set) {
    fileSet->ClearFileEntries();
  }
  if (cmNonempty(value)) {
    fileSet->AddFileEntry(
      BT<std::string>(value, this->Makefile->GetBacktrace()));
  }
}

cmValue cmTargetInternals::GetFileSetDirectories(
  cmTarget const* self, std::string const& fileSetName,
  cm::string_view fileSetType) const
{
  auto const* fileSet = self->GetFileSet(fileSetName);
  if (!fileSet) {
    return nullptr;
  }
  if (fileSet->GetType() != fileSetType) {
    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                 cmStrCat("File set \"", fileSetName,
                                          "\" is not of type \"", fileSetType,
                                          "\"."));
    return nullptr;
  }
  static std::string output;
  output = cmList::to_string(fileSet->GetDirectoryEntries());
  return cmValue(output);
}

cmValue cmTargetInternals::GetFileSetPaths(cmTarget const* self,
                                           std::string const& fileSetName,
                                           cm::string_view fileSetType) const
{
  auto const* fileSet = self->GetFileSet(fileSetName);
  if (!fileSet) {
    return nullptr;
  }
  if (fileSet->GetType() != fileSetType) {
    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                 cmStrCat("File set \"", fileSetName,
                                          "\" is not of type \"", fileSetType,
                                          "\"."));
    return nullptr;
  }
  static std::string output;
  output = cmList::to_string(fileSet->GetFileEntries());
  return cmValue(output);
}

void cmTarget::AppendBuildInterfaceIncludes()
{
  if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
      this->GetType() != cmStateEnums::STATIC_LIBRARY &&
      this->GetType() != cmStateEnums::MODULE_LIBRARY &&
      this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
      !this->IsExecutableWithExports()) {
    return;
  }
  if (this->impl->BuildInterfaceIncludesAppended) {
    return;
  }
  this->impl->BuildInterfaceIncludesAppended = true;

  if (this->impl->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE")) {
    std::string dirs = this->impl->Makefile->GetCurrentBinaryDirectory();
    if (!dirs.empty()) {
      dirs += ';';
    }
    dirs += this->impl->Makefile->GetCurrentSourceDirectory();
    if (!dirs.empty()) {
      this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
                           ("$<BUILD_INTERFACE:" + dirs + ">"));
    }
  }
}

namespace {
bool CheckLinkLibraryPattern(UsageRequirementProperty const& usage,
                             cmake* context)
{
  // Look for <LINK_LIBRARY:> and </LINK_LIBRARY:> internal tags
  static cmsys::RegularExpression linkPattern(
    "(^|;)(</?LINK_(LIBRARY|GROUP):[^;>]*>)(;|$)");

  bool isValid = true;

  for (const auto& item : usage.Entries) {
    if (!linkPattern.find(item.Value)) {
      continue;
    }

    isValid = false;

    // Report an error.
    context->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat(
        "Property ", usage.Name, " contains the invalid item \"",
        linkPattern.match(2), "\". The ", usage.Name,
        " property may contain the generator-expression \"$<LINK_",
        linkPattern.match(3),
        ":...>\" which may be used to specify how the libraries are linked."),
      item.Backtrace);
  }

  return isValid;
}
}

void cmTarget::FinalizeTargetConfiguration(
  const cmBTStringRange& noConfigCompileDefinitions,
  cm::optional<std::map<std::string, cmValue>>& perConfigCompileDefinitions)
{
  if (this->GetType() == cmStateEnums::GLOBAL_TARGET) {
    return;
  }

  if (!CheckLinkLibraryPattern(this->impl->LinkLibraries,
                               this->GetMakefile()->GetCMakeInstance()) ||
      !CheckLinkLibraryPattern(this->impl->InterfaceLinkLibraries,
                               this->GetMakefile()->GetCMakeInstance()) ||
      !CheckLinkLibraryPattern(this->impl->InterfaceLinkLibrariesDirect,
                               this->GetMakefile()->GetCMakeInstance())) {
    return;
  }

  this->AppendBuildInterfaceIncludes();

  if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
    return;
  }

  for (auto const& def : noConfigCompileDefinitions) {
    this->InsertCompileDefinition(def);
  }

  auto* mf = this->GetMakefile();
  cmPolicies::PolicyStatus polSt = mf->GetPolicyStatus(cmPolicies::CMP0043);
  if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
    if (perConfigCompileDefinitions) {
      for (auto const& it : *perConfigCompileDefinitions) {
        if (cmValue val = it.second) {
          this->AppendProperty(it.first, *val);
        }
      }
    } else {
      perConfigCompileDefinitions.emplace();
      std::vector<std::string> configs =
        mf->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);

      for (std::string const& c : configs) {
        std::string defPropName =
          cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(c));
        cmValue val = mf->GetProperty(defPropName);
        (*perConfigCompileDefinitions)[defPropName] = val;
        if (val) {
          this->AppendProperty(defPropName, *val);
        }
      }
    }
  }
}

void cmTarget::InsertInclude(BT<std::string> const& entry, bool before)
{
  this->impl->IncludeDirectories.WriteDirect(
    entry,
    before ? UsageRequirementProperty::Action::Prepend
           : UsageRequirementProperty::Action::Append);
}

void cmTarget::InsertCompileOption(BT<std::string> const& entry, bool before)
{
  this->impl->CompileOptions.WriteDirect(
    entry,
    before ? UsageRequirementProperty::Action::Prepend
           : UsageRequirementProperty::Action::Append);
}

void cmTarget::InsertCompileDefinition(BT<std::string> const& entry)
{
  this->impl->CompileDefinitions.WriteDirect(
    entry, UsageRequirementProperty::Action::Append);
}

void cmTarget::InsertLinkOption(BT<std::string> const& entry, bool before)
{
  this->impl->LinkOptions.WriteDirect(
    entry,
    before ? UsageRequirementProperty::Action::Prepend
           : UsageRequirementProperty::Action::Append);
}

void cmTarget::InsertLinkDirectory(BT<std::string> const& entry, bool before)
{
  this->impl->LinkDirectories.WriteDirect(
    entry,
    before ? UsageRequirementProperty::Action::Prepend
           : UsageRequirementProperty::Action::Append);
}

void cmTarget::InsertPrecompileHeader(BT<std::string> const& entry)
{
  this->impl->PrecompileHeaders.WriteDirect(
    entry, UsageRequirementProperty::Action::Append);
}

namespace {
void CheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
                                   const std::string& value,
                                   cmMakefile* context, bool imported)
{
  // Support imported and non-imported versions of the property.
  const char* base = (imported ? "IMPORTED_LINK_INTERFACE_LIBRARIES"
                               : "LINK_INTERFACE_LIBRARIES");

  // Look for link-type keywords in the value.
  static cmsys::RegularExpression keys("(^|;)(debug|optimized|general)(;|$)");
  if (keys.find(value)) {
    // Report an error.
    std::ostringstream e;
    e << "Property " << prop << " may not contain link-type keyword \""
      << keys.match(2) << "\".  "
      << "The " << base << " property has a per-configuration "
      << "version called " << base << "_<CONFIG> which may be "
      << "used to specify per-configuration rules.";
    if (!imported) {
      e << "  "
        << "Alternatively, an IMPORTED library may be created, configured "
        << "with a per-configuration location, and then named in the "
        << "property value.  "
        << "See the add_library command's IMPORTED mode for details."
        << "\n"
        << "If you have a list of libraries that already contains the "
        << "keyword, use the target_link_libraries command with its "
        << "LINK_INTERFACE_LIBRARIES mode to set the property.  "
        << "The command automatically recognizes link-type keywords and sets "
        << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
        << "properties accordingly.";
    }
    context->IssueMessage(MessageType::FATAL_ERROR, e.str());
  }
}

void CheckINTERFACE_LINK_LIBRARIES(const std::string& value,
                                   cmMakefile* context)
{
  // Look for link-type keywords in the value.
  static cmsys::RegularExpression keys("(^|;)(debug|optimized|general)(;|$)");
  if (keys.find(value)) {
    // Report an error.
    std::ostringstream e;

    e << "Property INTERFACE_LINK_LIBRARIES may not contain link-type "
         "keyword \""
      << keys.match(2)
      << "\".  The INTERFACE_LINK_LIBRARIES "
         "property may contain configuration-sensitive generator-expressions "
         "which may be used to specify per-configuration rules.";

    context->IssueMessage(MessageType::FATAL_ERROR, e.str());
  }
}

void CheckIMPORTED_GLOBAL(const cmTarget* target, cmMakefile* context)
{
  const auto& targets = context->GetOwnedImportedTargets();
  auto it =
    std::find_if(targets.begin(), targets.end(),
                 [&](const std::unique_ptr<cmTarget>& importTarget) -> bool {
                   return target == importTarget.get();
                 });
  if (it == targets.end()) {
    std::ostringstream e;
    e << "Attempt to promote imported target \"" << target->GetName()
      << "\" to global scope (by setting IMPORTED_GLOBAL) "
         "which is not built in this directory.";
    context->IssueMessage(MessageType::FATAL_ERROR, e.str());
  }
}
}

void cmTarget::CheckProperty(const std::string& prop,
                             cmMakefile* context) const
{
  // Certain properties need checking.
  if (cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES")) {
    if (cmValue value = this->GetProperty(prop)) {
      CheckLINK_INTERFACE_LIBRARIES(prop, *value, context, false);
    }
  } else if (cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES")) {
    if (cmValue value = this->GetProperty(prop)) {
      CheckLINK_INTERFACE_LIBRARIES(prop, *value, context, true);
    }
  } else if (prop == "INTERFACE_LINK_LIBRARIES") {
    if (cmValue value = this->GetProperty(prop)) {
      CheckINTERFACE_LINK_LIBRARIES(*value, context);
    }
  } else if (prop == "IMPORTED_GLOBAL") {
    if (this->IsImported()) {
      CheckIMPORTED_GLOBAL(this, context);
    }
  }
}

cmValue cmTarget::GetComputedProperty(const std::string& prop,
                                      cmMakefile& mf) const
{
  return cmTargetPropertyComputer::GetProperty(this, prop, mf);
}

cmValue cmTarget::GetProperty(const std::string& prop) const
{
  static std::unordered_set<std::string> const specialProps{
    propC_STANDARD,
    propCXX_STANDARD,
    propCUDA_STANDARD,
    propHIP_STANDARD,
    propOBJC_STANDARD,
    propOBJCXX_STANDARD,
    propLINK_LIBRARIES,
    propTYPE,
    propINCLUDE_DIRECTORIES,
    propCOMPILE_FEATURES,
    propCOMPILE_OPTIONS,
    propCOMPILE_DEFINITIONS,
    propPRECOMPILE_HEADERS,
    propLINK_OPTIONS,
    propLINK_DIRECTORIES,
    propIMPORTED,
    propIMPORTED_GLOBAL,
    propMANUALLY_ADDED_DEPENDENCIES,
    propNAME,
    propBINARY_DIR,
    propSOURCE_DIR,
    propSOURCES,
    propINTERFACE_LINK_LIBRARIES,
    propINTERFACE_LINK_LIBRARIES_DIRECT,
    propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE,
    propIMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES,
    propIMPORTED_CXX_MODULES_COMPILE_DEFINITIONS,
    propIMPORTED_CXX_MODULES_COMPILE_FEATURES,
    propIMPORTED_CXX_MODULES_COMPILE_OPTIONS,
    propIMPORTED_CXX_MODULES_LINK_LIBRARIES,
  };
  if (specialProps.count(prop)) {
    if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
        prop == propCUDA_STANDARD || prop == propHIP_STANDARD ||
        prop == propOBJC_STANDARD || prop == propOBJCXX_STANDARD) {
      auto propertyIter = this->impl->LanguageStandardProperties.find(prop);
      if (propertyIter == this->impl->LanguageStandardProperties.end()) {
        return nullptr;
      }
      return cmValue(propertyIter->second.Value);
    }

    UsageRequirementProperty const* usageRequirements[] = {
      &this->impl->IncludeDirectories,
      &this->impl->CompileOptions,
      &this->impl->CompileFeatures,
      &this->impl->CompileDefinitions,
      &this->impl->PrecompileHeaders,
      &this->impl->Sources,
      &this->impl->LinkOptions,
      &this->impl->LinkDirectories,
      &this->impl->LinkLibraries,
      &this->impl->InterfaceLinkLibraries,
      &this->impl->InterfaceLinkLibrariesDirect,
      &this->impl->InterfaceLinkLibrariesDirectExclude,
      &this->impl->ImportedCxxModulesIncludeDirectories,
      &this->impl->ImportedCxxModulesCompileDefinitions,
      &this->impl->ImportedCxxModulesCompileFeatures,
      &this->impl->ImportedCxxModulesCompileOptions,
      &this->impl->ImportedCxxModulesLinkLibraries,
    };

    for (auto const* usageRequirement : usageRequirements) {
      auto value = usageRequirement->Read(prop);
      if (value.first) {
        return value.second;
      }
    }

    // the type property returns what type the target is
    if (prop == propTYPE) {
      return cmValue(cmState::GetTargetTypeName(this->GetType()));
    }
    if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
      if (this->impl->Utilities.empty()) {
        return nullptr;
      }

      static std::string output;
      static std::vector<std::string> utilities;
      utilities.resize(this->impl->Utilities.size());
      std::transform(
        this->impl->Utilities.cbegin(), this->impl->Utilities.cend(),
        utilities.begin(),
        [](const BT<std::pair<std::string, bool>>& item) -> std::string {
          return item.Value.first;
        });
      output = cmList::to_string(utilities);
      return cmValue(output);
    }
    if (prop == propIMPORTED) {
      return this->IsImported() ? cmValue(propTRUE) : cmValue(propFALSE);
    }
    if (prop == propIMPORTED_GLOBAL) {
      return this->IsImportedGloballyVisible() ? cmValue(propTRUE)
                                               : cmValue(propFALSE);
    }
    if (prop == propNAME) {
      return cmValue(this->GetName());
    }
    if (prop == propBINARY_DIR) {
      return cmValue(this->impl->Makefile->GetStateSnapshot()
                       .GetDirectory()
                       .GetCurrentBinary());
    }
    if (prop == propSOURCE_DIR) {
      return cmValue(this->impl->Makefile->GetStateSnapshot()
                       .GetDirectory()
                       .GetCurrentSource());
    }
  }

  // Check fileset properties.
  {
    FileSetType* fileSetTypes[] = {
      &this->impl->HeadersFileSets,
      &this->impl->CxxModulesFileSets,
    };

    for (auto* fileSetType : fileSetTypes) {
      auto value = fileSetType->ReadProperties(this, this->impl.get(), prop);
      if (value.first) {
        return value.second;
      }
    }
  }

  cmValue retVal = this->impl->Properties.GetPropertyValue(prop);
  if (!retVal) {
    const bool chain = this->impl->Makefile->GetState()->IsPropertyChained(
      prop, cmProperty::TARGET);
    if (chain) {
      return this->impl->Makefile->GetStateSnapshot()
        .GetDirectory()
        .GetProperty(prop, chain);
    }
    return nullptr;
  }
  return retVal;
}

std::string const& cmTarget::GetSafeProperty(std::string const& prop) const
{
  cmValue ret = this->GetProperty(prop);
  if (ret) {
    return *ret;
  }

  static std::string const s_empty;
  return s_empty;
}

bool cmTarget::GetPropertyAsBool(const std::string& prop) const
{
  return cmIsOn(this->GetProperty(prop));
}

cmPropertyMap const& cmTarget::GetProperties() const
{
  return this->impl->Properties;
}

bool cmTarget::IsDLLPlatform() const
{
  return this->impl->IsDLLPlatform;
}

bool cmTarget::IsAIX() const
{
  return this->impl->IsAIX;
}
bool cmTarget::IsApple() const
{
  return this->impl->IsApple;
}

bool cmTarget::IsNormal() const
{
  switch (this->impl->TargetVisibility) {
    case Visibility::Normal:
      return true;
    case Visibility::Generated:
    case Visibility::Imported:
    case Visibility::ImportedGlobally:
      return false;
  }
  assert(false && "unknown visibility (IsNormal)");
  return false;
}

bool cmTarget::IsSynthetic() const
{
  switch (this->impl->TargetVisibility) {
    case Visibility::Generated:
      return true;
    case Visibility::Normal:
    case Visibility::Imported:
    case Visibility::ImportedGlobally:
      return false;
  }
  assert(false && "unknown visibility (IsSynthetic)");
  return false;
}

bool cmTargetInternals::IsImported() const
{
  switch (this->TargetVisibility) {
    case cmTarget::Visibility::Imported:
    case cmTarget::Visibility::ImportedGlobally:
      return true;
    case cmTarget::Visibility::Normal:
    case cmTarget::Visibility::Generated:
      return false;
  }
  assert(false && "unknown visibility (IsImported)");
  return false;
}

bool cmTarget::IsImported() const
{
  return this->impl->IsImported();
}

bool cmTarget::IsImportedGloballyVisible() const
{
  switch (this->impl->TargetVisibility) {
    case Visibility::ImportedGlobally:
      return true;
    case Visibility::Normal:
    case Visibility::Generated:
    case Visibility::Imported:
      return false;
  }
  assert(false && "unknown visibility (IsImportedGloballyVisible)");
  return false;
}

bool cmTarget::IsPerConfig() const
{
  return this->impl->PerConfig;
}

bool cmTarget::IsRuntimeBinary() const
{
  switch (this->GetType()) {
    case cmStateEnums::EXECUTABLE:
    case cmStateEnums::SHARED_LIBRARY:
    case cmStateEnums::MODULE_LIBRARY:
      return true;
    case cmStateEnums::OBJECT_LIBRARY:
    case cmStateEnums::STATIC_LIBRARY:
    case cmStateEnums::UTILITY:
    case cmStateEnums::INTERFACE_LIBRARY:
    case cmStateEnums::GLOBAL_TARGET:
    case cmStateEnums::UNKNOWN_LIBRARY:
      break;
  }
  return false;
}

bool cmTarget::CanCompileSources() const
{
  if (this->IsImported()) {
    return false;
  }
  if (this->IsSynthetic()) {
    return true;
  }
  switch (this->GetType()) {
    case cmStateEnums::EXECUTABLE:
    case cmStateEnums::STATIC_LIBRARY:
    case cmStateEnums::SHARED_LIBRARY:
    case cmStateEnums::MODULE_LIBRARY:
    case cmStateEnums::OBJECT_LIBRARY:
      return true;
    case cmStateEnums::UTILITY:
    case cmStateEnums::INTERFACE_LIBRARY:
    case cmStateEnums::GLOBAL_TARGET:
    case cmStateEnums::UNKNOWN_LIBRARY:
      break;
  }
  return false;
}

const char* cmTarget::GetSuffixVariableInternal(
  cmStateEnums::ArtifactType artifact) const
{
  switch (this->GetType()) {
    case cmStateEnums::STATIC_LIBRARY:
      return "CMAKE_STATIC_LIBRARY_SUFFIX";
    case cmStateEnums::SHARED_LIBRARY:
      switch (artifact) {
        case cmStateEnums::RuntimeBinaryArtifact:
          return "CMAKE_SHARED_LIBRARY_SUFFIX";
        case cmStateEnums::ImportLibraryArtifact:
          return this->IsApple() ? "CMAKE_APPLE_IMPORT_FILE_SUFFIX"
                                 : "CMAKE_IMPORT_LIBRARY_SUFFIX";
      }
      break;
    case cmStateEnums::MODULE_LIBRARY:
      switch (artifact) {
        case cmStateEnums::RuntimeBinaryArtifact:
          return "CMAKE_SHARED_MODULE_SUFFIX";
        case cmStateEnums::ImportLibraryArtifact:
          return "CMAKE_IMPORT_LIBRARY_SUFFIX";
      }
      break;
    case cmStateEnums::EXECUTABLE:
      switch (artifact) {
        case cmStateEnums::RuntimeBinaryArtifact:
          // Android GUI application packages store the native
          // binary as a shared library.
          return (this->IsAndroidGuiExecutable()
                    ? "CMAKE_SHARED_LIBRARY_SUFFIX"
                    : "CMAKE_EXECUTABLE_SUFFIX");
        case cmStateEnums::ImportLibraryArtifact:
          return (this->impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_SUFFIX"
                                    : "CMAKE_IMPORT_LIBRARY_SUFFIX");
      }
      break;
    default:
      break;
  }
  return "";
}

const char* cmTarget::GetPrefixVariableInternal(
  cmStateEnums::ArtifactType artifact) const
{
  switch (this->GetType()) {
    case cmStateEnums::STATIC_LIBRARY:
      return "CMAKE_STATIC_LIBRARY_PREFIX";
    case cmStateEnums::SHARED_LIBRARY:
      switch (artifact) {
        case cmStateEnums::RuntimeBinaryArtifact:
          return "CMAKE_SHARED_LIBRARY_PREFIX";
        case cmStateEnums::ImportLibraryArtifact:
          return this->IsApple() ? "CMAKE_APPLE_IMPORT_FILE_PREFIX"
                                 : "CMAKE_IMPORT_LIBRARY_PREFIX";
      }
      break;
    case cmStateEnums::MODULE_LIBRARY:
      switch (artifact) {
        case cmStateEnums::RuntimeBinaryArtifact:
          return "CMAKE_SHARED_MODULE_PREFIX";
        case cmStateEnums::ImportLibraryArtifact:
          return "CMAKE_IMPORT_LIBRARY_PREFIX";
      }
      break;
    case cmStateEnums::EXECUTABLE:
      switch (artifact) {
        case cmStateEnums::RuntimeBinaryArtifact:
          // Android GUI application packages store the native
          // binary as a shared library.
          return (this->IsAndroidGuiExecutable()
                    ? "CMAKE_SHARED_LIBRARY_PREFIX"
                    : "");
        case cmStateEnums::ImportLibraryArtifact:
          return (this->impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_PREFIX"
                                    : "CMAKE_IMPORT_LIBRARY_PREFIX");
      }
      break;
    default:
      break;
  }
  return "";
}

std::string cmTarget::ImportedGetFullPath(
  const std::string& config, cmStateEnums::ArtifactType artifact) const
{
  assert(this->IsImported());

  // Lookup/compute/cache the import information for this
  // configuration.
  std::string desired_config = config;
  if (config.empty()) {
    desired_config = "NOCONFIG";
  }

  std::string result;

  cmValue loc = nullptr;
  cmValue imp = nullptr;
  std::string suffix;

  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
      this->GetMappedConfig(desired_config, loc, imp, suffix)) {
    switch (artifact) {
      case cmStateEnums::RuntimeBinaryArtifact:
        if (loc) {
          result = *loc;
        } else if (imp) {
          result = *imp;
        } else {
          std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
          if (cmValue config_location = this->GetProperty(impProp)) {
            result = *config_location;
          } else if (cmValue location =
                       this->GetProperty("IMPORTED_LOCATION")) {
            result = *location;
          }
          if (result.empty() &&
              (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
               this->IsExecutableWithExports())) {
            impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
            if (cmValue config_implib = this->GetProperty(impProp)) {
              result = *config_implib;
            } else if (cmValue implib = this->GetProperty("IMPORTED_IMPLIB")) {
              result = *implib;
            }
          }
        }
        if (this->IsApple() &&
            (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
             this->impl->TargetType == cmStateEnums::STATIC_LIBRARY ||
             this->impl->TargetType == cmStateEnums::UNKNOWN_LIBRARY) &&
            cmSystemTools::IsPathToXcFramework(result)) {
          auto plist = cmParseXcFrameworkPlist(result, *this->impl->Makefile,
                                               this->impl->Backtrace);
          if (!plist) {
            return "";
          }
          auto const* library = plist->SelectSuitableLibrary(
            *this->impl->Makefile, this->impl->Backtrace);
          if (library) {
            result = cmStrCat(result, '/', library->LibraryIdentifier, '/',
                              library->LibraryPath);
          } else {
            return "";
          }
        }
        break;

      case cmStateEnums::ImportLibraryArtifact:
        if (imp) {
          result = *imp;
        } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
                   this->IsExecutableWithExports()) {
          std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
          if (cmValue config_implib = this->GetProperty(impProp)) {
            result = *config_implib;
          } else if (cmValue implib = this->GetProperty("IMPORTED_IMPLIB")) {
            result = *implib;
          }
        }
        break;
    }
  }

  if (result.empty()) {
    if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
      auto message = [&]() -> std::string {
        std::string unset;
        std::string configuration;

        if (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
            artifact == cmStateEnums::RuntimeBinaryArtifact) {
          unset = "IMPORTED_LOCATION or IMPORTED_IMPLIB";
        } else if (artifact == cmStateEnums::RuntimeBinaryArtifact) {
          unset = "IMPORTED_LOCATION";
        } else if (artifact == cmStateEnums::ImportLibraryArtifact) {
          unset = "IMPORTED_IMPLIB";
        }

        if (!config.empty()) {
          configuration = cmStrCat(" configuration \"", config, "\"");
        }

        return cmStrCat(unset, " not set for imported target \"",
                        this->GetName(), "\"", configuration, ".");
      };

      switch (this->GetPolicyStatus(cmPolicies::CMP0111)) {
        case cmPolicies::WARN:
          this->impl->Makefile->IssueMessage(
            MessageType::AUTHOR_WARNING,
            cmPolicies::GetPolicyWarning(cmPolicies::CMP0111) + "\n" +
              message());
          CM_FALLTHROUGH;
        case cmPolicies::OLD:
          break;
        default:
          this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                             message());
      }
    }

    result = cmStrCat(this->GetName(), "-NOTFOUND");
  }
  return result;
}

const cmFileSet* cmTarget::GetFileSet(const std::string& name) const
{
  auto it = this->impl->FileSets.find(name);
  return it == this->impl->FileSets.end() ? nullptr : &it->second;
}

cmFileSet* cmTarget::GetFileSet(const std::string& name)
{
  auto it = this->impl->FileSets.find(name);
  return it == this->impl->FileSets.end() ? nullptr : &it->second;
}

std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet(
  const std::string& name, const std::string& type, cmFileSetVisibility vis)
{
  auto result = this->impl->FileSets.emplace(
    name,
    cmFileSet(*this->GetMakefile()->GetCMakeInstance(), name, type, vis));
  if (result.second) {
    auto bt = this->impl->Makefile->GetBacktrace();
    if (type == this->impl->HeadersFileSets.TypeName) {
      this->impl->HeadersFileSets.AddFileSet(name, vis, std::move(bt));
    } else if (type == this->impl->CxxModulesFileSets.TypeName) {
      this->impl->CxxModulesFileSets.AddFileSet(name, vis, std::move(bt));
    }
  }
  return std::make_pair(&result.first->second, result.second);
}

std::string cmTarget::GetFileSetsPropertyName(const std::string& type)
{
  if (type == "HEADERS") {
    return "HEADER_SETS";
  }
  if (type == "CXX_MODULES") {
    return "CXX_MODULE_SETS";
  }
  return "";
}

std::string cmTarget::GetInterfaceFileSetsPropertyName(const std::string& type)
{
  if (type == "HEADERS") {
    return "INTERFACE_HEADER_SETS";
  }
  if (type == "CXX_MODULES") {
    return "INTERFACE_CXX_MODULE_SETS";
  }
  return "";
}

std::vector<std::string> cmTarget::GetAllFileSetNames() const
{
  std::vector<std::string> result;

  for (auto const& it : this->impl->FileSets) {
    result.push_back(it.first);
  }

  return result;
}

std::vector<std::string> cmTarget::GetAllInterfaceFileSets() const
{
  std::vector<std::string> result;
  auto inserter = std::back_inserter(result);

  auto appendEntries = [=](const std::vector<BT<std::string>>& entries) {
    for (auto const& entry : entries) {
      cmList expanded{ entry.Value };
      std::copy(expanded.begin(), expanded.end(), inserter);
    }
  };

  appendEntries(this->impl->HeadersFileSets.InterfaceEntries.Entries);
  appendEntries(this->impl->CxxModulesFileSets.InterfaceEntries.Entries);

  return result;
}

bool cmTarget::HasFileSets() const
{
  return !this->impl->FileSets.empty();
}

bool cmTargetInternals::CheckImportedLibName(std::string const& prop,
                                             std::string const& value) const
{
  if (this->TargetType != cmStateEnums::INTERFACE_LIBRARY ||
      !this->IsImported()) {
    this->Makefile->IssueMessage(
      MessageType::FATAL_ERROR,
      prop +
        " property may be set only on imported INTERFACE library targets.");
    return false;
  }
  if (!value.empty()) {
    if (value[0] == '-') {
      this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                   prop + " property value\n  " + value +
                                     "\nmay not start with '-'.");
      return false;
    }
    std::string::size_type bad = value.find_first_of(":/\\;");
    if (bad != std::string::npos) {
      this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                   prop + " property value\n  " + value +
                                     "\nmay not contain '" +
                                     value.substr(bad, 1) + "'.");
      return false;
    }
  }
  return true;
}

bool cmTarget::GetMappedConfig(std::string const& desired_config, cmValue& loc,
                               cmValue& imp, std::string& suffix) const
{
  std::string config_upper;
  if (!desired_config.empty()) {
    config_upper = cmSystemTools::UpperCase(desired_config);
  }

  std::string locPropBase;
  if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
    locPropBase = "IMPORTED_LIBNAME";
  } else if (this->GetType() == cmStateEnums::OBJECT_LIBRARY) {
    locPropBase = "IMPORTED_OBJECTS";
  } else {
    locPropBase = "IMPORTED_LOCATION";
  }

  // Track the configuration-specific property suffix.
  suffix = cmStrCat('_', config_upper);

  cmList mappedConfigs;
  {
    std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", config_upper);
    if (cmValue mapValue = this->GetProperty(mapProp)) {
      mappedConfigs.assign(*mapValue, cmList::EmptyElements::Yes);
    }
  }

  // If we needed to find one of the mapped configurations but did not
  // There may be only IMPORTED_IMPLIB for a shared library or an executable
  // with exports.
  bool allowImp = (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
                   this->IsExecutableWithExports()) ||
    (this->IsAIX() && this->IsExecutableWithExports()) ||
    (this->GetMakefile()->PlatformSupportsAppleTextStubs() &&
     this->IsSharedLibraryWithExports());

  // If a mapping was found, check its configurations.
  for (auto mci = mappedConfigs.begin();
       !loc && !imp && mci != mappedConfigs.end(); ++mci) {
    // Look for this configuration.
    if (mci->empty()) {
      // An empty string in the mapping has a special meaning:
      // look up the config-less properties.
      loc = this->GetProperty(locPropBase);
      if (allowImp) {
        imp = this->GetProperty("IMPORTED_IMPLIB");
      }
      // If it was found, set the suffix.
      if (loc || imp) {
        suffix.clear();
      }
    } else {
      std::string mcUpper = cmSystemTools::UpperCase(*mci);
      std::string locProp = cmStrCat(locPropBase, '_', mcUpper);
      loc = this->GetProperty(locProp);
      if (allowImp) {
        std::string impProp = cmStrCat("IMPORTED_IMPLIB_", mcUpper);
        imp = this->GetProperty(impProp);
      }

      // If it was found, use it for all properties below.
      if (loc || imp) {
        suffix = cmStrCat('_', mcUpper);
      }
    }
  }

  // If we needed to find one of the mapped configurations but did not
  // then the target location is not found.  The project does not want
  // any other configuration.
  if (!mappedConfigs.empty() && !loc && !imp) {
    // Interface libraries are always available because their
    // library name is optional so it is okay to leave loc empty.
    return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
  }

  // If we have not yet found it then there are no mapped
  // configurations.  Look for an exact-match.
  if (!loc && !imp) {
    std::string locProp = cmStrCat(locPropBase, suffix);
    loc = this->GetProperty(locProp);
    if (allowImp) {
      std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
      imp = this->GetProperty(impProp);
    }
  }

  // If we have not yet found it then there are no mapped
  // configurations and no exact match.
  if (!loc && !imp) {
    // The suffix computed above is not useful.
    suffix.clear();

    // Look for a configuration-less location.  This may be set by
    // manually-written code.
    loc = this->GetProperty(locPropBase);
    if (allowImp) {
      imp = this->GetProperty("IMPORTED_IMPLIB");
    }
  }

  // If we have not yet found it then the project is willing to try
  // any available configuration.
  if (!loc && !imp) {
    cmList availableConfigs;
    if (cmValue iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
      availableConfigs.assign(*iconfigs);
    }
    for (auto aci = availableConfigs.begin();
         !loc && !imp && aci != availableConfigs.end(); ++aci) {
      suffix = cmStrCat('_', cmSystemTools::UpperCase(*aci));
      std::string locProp = cmStrCat(locPropBase, suffix);
      loc = this->GetProperty(locProp);
      if (allowImp) {
        std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
        imp = this->GetProperty(impProp);
      }
    }
  }
  // If we have not yet found it then the target location is not available.
  if (!loc && !imp) {
    // Interface libraries are always available because their
    // library name is optional so it is okay to leave loc empty.
    return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
  }

  return true;
}
