From 36aba01223cfb28ee574386cd91dbfccc4dc9359 Mon Sep 17 00:00:00 2001
From: Vitaly Stakhovsky <vvs31415@gitlab.org>
Date: Wed, 29 Apr 2020 11:00:00 -0400
Subject: cmGeneratorTarget::GetProperty: return cmProp

---
 Source/cmCommonTargetGenerator.cxx         |   4 +-
 Source/cmComputeLinkInformation.cxx        |  17 +-
 Source/cmCustomCommandGenerator.cxx        |   4 +-
 Source/cmExportFileGenerator.cxx           |  57 +++--
 Source/cmExportTryCompileFileGenerator.cxx |   6 +-
 Source/cmFileAPICodemodel.cxx              |   4 +-
 Source/cmGeneratorExpressionNode.cxx       |  17 +-
 Source/cmGeneratorTarget.cxx               | 387 ++++++++++++++---------------
 Source/cmGeneratorTarget.h                 |   4 +-
 Source/cmGhsMultiTargetGenerator.cxx       |   8 +-
 Source/cmGlobalCommonGenerator.cxx         |   4 +-
 Source/cmGlobalGenerator.cxx               |  24 +-
 Source/cmGlobalGhsMultiGenerator.cxx       |  11 +-
 Source/cmGlobalVisualStudio71Generator.cxx |  12 +-
 Source/cmGlobalVisualStudio7Generator.cxx  |  25 +-
 Source/cmGlobalVisualStudio8Generator.cxx  |  14 +-
 Source/cmGlobalVisualStudioGenerator.cxx   |   6 +-
 Source/cmGlobalXCodeGenerator.cxx          |  48 ++--
 Source/cmInstallTargetGenerator.cxx        |   8 +-
 Source/cmLinkLineDeviceComputer.cxx        |   8 +-
 Source/cmLocalGenerator.cxx                | 147 +++++------
 Source/cmLocalUnixMakefileGenerator3.cxx   |  10 +-
 Source/cmLocalVisualStudio7Generator.cxx   |  65 +++--
 Source/cmMakefileTargetGenerator.cxx       |  43 ++--
 Source/cmNinjaNormalTargetGenerator.cxx    |  12 +-
 Source/cmNinjaTargetGenerator.cxx          |  53 ++--
 Source/cmNinjaUtilityTargetGenerator.cxx   |   4 +-
 Source/cmQtAutoGenInitializer.cxx          |  13 +-
 Source/cmTestGenerator.cxx                 |   6 +-
 Source/cmVisualStudio10TargetGenerator.cxx | 250 +++++++++----------
 Source/cmVisualStudioGeneratorOptions.cxx  |   5 +-
 Source/cmXCodeScheme.cxx                   |  17 +-
 32 files changed, 644 insertions(+), 649 deletions(-)

diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index fbb9429..6c1a476 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -225,9 +225,9 @@ std::string cmCommonTargetGenerator::GetAIXExports(std::string const&)
 {
   std::string aixExports;
   if (this->GeneratorTarget->Target->IsAIX()) {
-    if (const char* exportAll =
+    if (cmProp exportAll =
           this->GeneratorTarget->GetProperty("AIX_EXPORT_ALL_SYMBOLS")) {
-      if (cmIsOff(exportAll)) {
+      if (cmIsOff(*exportAll)) {
         aixExports = "-n";
       }
     }
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index f0174d9..ea7ede4 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -514,8 +514,8 @@ bool cmComputeLinkInformation::Compute()
 
   // Restore the target link type so the correct system runtime
   // libraries are found.
-  const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
-  if (cmIsOn(lss)) {
+  cmProp lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
+  if (lss && cmIsOn(*lss)) {
     this->SetCurrentLinkType(LinkStatic);
   } else {
     this->SetCurrentLinkType(this->StartLinkType);
@@ -591,10 +591,9 @@ void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
   // of a default selection whether or not it is overridden by a property.
   std::string defaultVar =
     cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT");
-  const char* langRuntimeLibraryDefault =
-    this->Makefile->GetDefinition(defaultVar);
-  if (langRuntimeLibraryDefault && *langRuntimeLibraryDefault) {
-    const char* runtimeLibraryValue =
+  cmProp langRuntimeLibraryDefault = this->Makefile->GetDef(defaultVar);
+  if (langRuntimeLibraryDefault && !langRuntimeLibraryDefault->empty()) {
+    cmProp runtimeLibraryValue =
       this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY"));
     if (!runtimeLibraryValue) {
       runtimeLibraryValue = langRuntimeLibraryDefault;
@@ -602,7 +601,7 @@ void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
 
     std::string runtimeLibrary =
       cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
-        runtimeLibraryValue, this->Target->GetLocalGenerator(), this->Config,
+        *runtimeLibraryValue, this->Target->GetLocalGenerator(), this->Config,
         this->Target));
     if (!runtimeLibrary.empty()) {
       if (const char* runtimeLinkOptions = this->Makefile->GetDefinition(
@@ -855,8 +854,8 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo()
   }
 
   // Lookup the starting link type from the target (linked statically?).
-  const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
-  this->StartLinkType = cmIsOn(lss) ? LinkStatic : LinkShared;
+  cmProp lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
+  this->StartLinkType = (lss && cmIsOn(*lss)) ? LinkStatic : LinkShared;
   this->CurrentLinkType = this->StartLinkType;
 }
 
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 2432d2b..0fe19b6 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -111,13 +111,13 @@ void cmCustomCommandGenerator::FillEmulatorsWithArguments()
     if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
         !target->IsImported()) {
 
-      const char* emulator_property =
+      cmProp emulator_property =
         target->GetProperty("CROSSCOMPILING_EMULATOR");
       if (!emulator_property) {
         continue;
       }
 
-      cmExpandList(emulator_property, this->EmulatorsWithArguments[c]);
+      cmExpandList(*emulator_property, this->EmulatorsWithArguments[c]);
     }
   }
 }
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index ea31417..28037c6 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -125,9 +125,9 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
   const std::string& propName, cmGeneratorTarget* target,
   ImportPropertyMap& properties)
 {
-  const char* input = target->GetProperty(propName);
+  cmProp input = target->GetProperty(propName);
   if (input) {
-    properties[propName] = input;
+    properties[propName] = *input;
   }
 }
 
@@ -137,16 +137,16 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
   cmGeneratorExpression::PreprocessContext preprocessRule,
   ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
 {
-  const char* input = target->GetProperty(propName);
+  cmProp input = target->GetProperty(propName);
   if (input) {
-    if (!*input) {
+    if (input->empty()) {
       // Set to empty
       properties[outputName].clear();
       return;
     }
 
     std::string prepro =
-      cmGeneratorExpression::Preprocess(input, preprocessRule);
+      cmGeneratorExpression::Preprocess(*input, preprocessRule);
     if (!prepro.empty()) {
       this->ResolveTargetsInGeneratorExpressions(prepro, target,
                                                  missingTargets);
@@ -174,10 +174,10 @@ bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty(
   if (!target->IsLinkable()) {
     return false;
   }
-  const char* input = target->GetProperty("INTERFACE_LINK_LIBRARIES");
+  cmProp input = target->GetProperty("INTERFACE_LINK_LIBRARIES");
   if (input) {
     std::string prepro =
-      cmGeneratorExpression::Preprocess(input, preprocessRule);
+      cmGeneratorExpression::Preprocess(*input, preprocessRule);
     if (!prepro.empty()) {
       this->ResolveTargetsInGeneratorExpressions(
         prepro, target, missingTargets, ReplaceFreeTargets);
@@ -341,19 +341,19 @@ void cmExportFileGenerator::PopulateSourcesInterface(
   assert(preprocessRule == cmGeneratorExpression::InstallInterface);
 
   const char* propName = "INTERFACE_SOURCES";
-  const char* input = gt->GetProperty(propName);
+  cmProp input = gt->GetProperty(propName);
 
   if (!input) {
     return;
   }
 
-  if (!*input) {
+  if (input->empty()) {
     properties[propName].clear();
     return;
   }
 
   std::string prepro =
-    cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+    cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
   if (!prepro.empty()) {
     this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
 
@@ -372,7 +372,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
   assert(preprocessRule == cmGeneratorExpression::InstallInterface);
 
   const char* propName = "INTERFACE_INCLUDE_DIRECTORIES";
-  const char* input = target->GetProperty(propName);
+  cmProp input = target->GetProperty(propName);
 
   cmGeneratorExpression ge;
 
@@ -399,7 +399,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
   if (!input && exportDirs.empty()) {
     return;
   }
-  if ((input && !*input) && exportDirs.empty()) {
+  if ((input && input->empty()) && exportDirs.empty()) {
     // Set to empty
     properties[propName].clear();
     return;
@@ -407,7 +407,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
 
   prefixItems(exportDirs);
 
-  std::string includes = (input ? input : "");
+  std::string includes = (input ? *input : "");
   const char* sep = input ? ";" : "";
   includes += sep + exportDirs;
   std::string prepro =
@@ -430,19 +430,19 @@ void cmExportFileGenerator::PopulateLinkDependsInterface(
   assert(preprocessRule == cmGeneratorExpression::InstallInterface);
 
   const char* propName = "INTERFACE_LINK_DEPENDS";
-  const char* input = gt->GetProperty(propName);
+  cmProp input = gt->GetProperty(propName);
 
   if (!input) {
     return;
   }
 
-  if (!*input) {
+  if (input->empty()) {
     properties[propName].clear();
     return;
   }
 
   std::string prepro =
-    cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+    cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
   if (!prepro.empty()) {
     this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
 
@@ -461,19 +461,19 @@ void cmExportFileGenerator::PopulateLinkDirectoriesInterface(
   assert(preprocessRule == cmGeneratorExpression::InstallInterface);
 
   const char* propName = "INTERFACE_LINK_DIRECTORIES";
-  const char* input = gt->GetProperty(propName);
+  cmProp input = gt->GetProperty(propName);
 
   if (!input) {
     return;
   }
 
-  if (!*input) {
+  if (input->empty()) {
     properties[propName].clear();
     return;
   }
 
   std::string prepro =
-    cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+    cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
   if (!prepro.empty()) {
     this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
 
@@ -496,11 +496,11 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
 void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop,
                          std::set<std::string>& ifaceProperties)
 {
-  const char* p = tgt->GetProperty(prop);
+  cmProp p = tgt->GetProperty(prop);
   if (!p) {
     return;
   }
-  std::vector<std::string> content = cmExpandedList(p);
+  std::vector<std::string> content = cmExpandedList(*p);
   ifaceProperties.insert(content.begin(), content.end());
 }
 
@@ -761,13 +761,12 @@ void cmExportFileGenerator::SetImportLinkInterface(
     return;
   }
 
-  const char* propContent;
+  cmProp propContent;
 
-  if (const char* prop_suffixed =
+  if (cmProp prop_suffixed =
         target->GetProperty("LINK_INTERFACE_LIBRARIES" + suffix)) {
     propContent = prop_suffixed;
-  } else if (const char* prop =
-               target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
+  } else if (cmProp prop = target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
     propContent = prop;
   } else {
     return;
@@ -789,13 +788,13 @@ void cmExportFileGenerator::SetImportLinkInterface(
     return;
   }
 
-  if (!*propContent) {
+  if (propContent->empty()) {
     properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix].clear();
     return;
   }
 
   std::string prepro =
-    cmGeneratorExpression::Preprocess(propContent, preprocessRule);
+    cmGeneratorExpression::Preprocess(*propContent, preprocessRule);
   if (!prepro.empty()) {
     this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets,
                                                ReplaceFreeTargets);
@@ -855,8 +854,8 @@ void cmExportFileGenerator::SetImportDetailProperties(
       cmGeneratorTarget::ManagedType::Native) {
     std::string prop = cmStrCat("IMPORTED_COMMON_LANGUAGE_RUNTIME", suffix);
     std::string propval;
-    if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
-      propval = p;
+    if (cmProp p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+      propval = *p;
     } else if (target->IsCSharpOnly()) {
       // C# projects do not have the /clr flag, so we set the property
       // here to mark the target as (only) managed (i.e. no .lib file
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index 807ebed..6212667 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -58,7 +58,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
   const std::string& propName, cmGeneratorTarget const* tgt,
   std::string const& language, std::set<cmGeneratorTarget const*>& emitted)
 {
-  const char* prop = tgt->GetProperty(propName);
+  cmProp prop = tgt->GetProperty(propName);
   if (!prop) {
     return std::string();
   }
@@ -67,7 +67,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
 
   cmGeneratorExpressionDAGChecker dagChecker(tgt, propName, nullptr, nullptr);
 
-  std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+  std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*prop);
 
   cmTarget dummyHead("try_compile_dummy_exe", cmStateEnums::EXECUTABLE,
                      cmTarget::VisibilityNormal, tgt->Target->GetMakefile(),
@@ -95,7 +95,7 @@ void cmExportTryCompileFileGenerator::PopulateProperties(
   std::vector<std::string> props = target->GetPropertyKeys();
   for (std::string const& p : props) {
 
-    properties[p] = target->GetProperty(p);
+    properties[p] = *target->GetProperty(p);
 
     if (cmHasLiteralPrefix(p, "IMPORTED_LINK_INTERFACE_LIBRARIES") ||
         cmHasLiteralPrefix(p, "IMPORTED_LINK_DEPENDENT_LIBRARIES") ||
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index f4237cb..f34d7d5 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -1424,9 +1424,9 @@ Json::Value Target::DumpDependency(cmTargetDepend const& td)
 Json::Value Target::DumpFolder()
 {
   Json::Value folder;
-  if (const char* f = this->GT->GetProperty("FOLDER")) {
+  if (cmProp f = this->GT->GetProperty("FOLDER")) {
     folder = Json::objectValue;
-    folder["name"] = f;
+    folder["name"] = *f;
   }
   return folder;
 }
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index d48427e..68f466f 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -920,9 +920,8 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
         std::vector<std::string> mappedConfigs;
         std::string mapProp = cmStrCat(
           "MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config));
-        if (const char* mapValue =
-              context->CurrentTarget->GetProperty(mapProp)) {
-          cmExpandList(cmSystemTools::UpperCase(mapValue), mappedConfigs);
+        if (cmProp mapValue = context->CurrentTarget->GetProperty(mapProp)) {
+          cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs);
           return cm::contains(mappedConfigs,
                               cmSystemTools::UpperCase(parameters.front()))
             ? "1"
@@ -1484,8 +1483,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
 
     std::string result;
     bool haveProp = false;
-    if (const char* p = target->GetProperty(propertyName)) {
-      result = p;
+    if (cmProp p = target->GetProperty(propertyName)) {
+      result = *p;
       haveProp = true;
     } else if (evaluatingLinkLibraries) {
       return std::string();
@@ -1723,13 +1722,13 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
     for (auto const& lit : testedFeatures) {
       std::vector<std::string> const& langAvailable =
         availableFeatures[lit.first];
-      const char* standardDefault = context->LG->GetMakefile()->GetDefinition(
+      cmProp standardDefault = context->LG->GetMakefile()->GetDef(
         "CMAKE_" + lit.first + "_STANDARD_DEFAULT");
       for (std::string const& it : lit.second) {
         if (!cm::contains(langAvailable, it)) {
           return "0";
         }
-        if (standardDefault && !*standardDefault) {
+        if (standardDefault && standardDefault->empty()) {
           // This compiler has no notion of language standard levels.
           // All features known for the language are always available.
           continue;
@@ -1737,12 +1736,12 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
         if (!context->LG->GetMakefile()->HaveStandardAvailable(
               target->Target, lit.first, it)) {
           if (evalLL) {
-            const char* l = target->GetProperty(lit.first + "_STANDARD");
+            cmProp l = target->GetProperty(lit.first + "_STANDARD");
             if (!l) {
               l = standardDefault;
             }
             assert(l);
-            context->MaxLanguageStandard[target][lit.first] = l;
+            context->MaxLanguageStandard[target][lit.first] = *l;
           } else {
             return "0";
           }
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index fd863a3..509df93 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -356,22 +356,22 @@ const std::string& cmGeneratorTarget::GetName() const
 
 std::string cmGeneratorTarget::GetExportName() const
 {
-  const char* exportName = this->GetProperty("EXPORT_NAME");
+  cmProp exportName = this->GetProperty("EXPORT_NAME");
 
-  if (exportName && *exportName) {
-    if (!cmGeneratorExpression::IsValidTargetName(exportName)) {
+  if (exportName && !exportName->empty()) {
+    if (!cmGeneratorExpression::IsValidTargetName(*exportName)) {
       std::ostringstream e;
-      e << "EXPORT_NAME property \"" << exportName << "\" for \""
+      e << "EXPORT_NAME property \"" << *exportName << "\" for \""
         << this->GetName() << "\": is not valid.";
       cmSystemTools::Error(e.str());
       return "";
     }
-    return exportName;
+    return *exportName;
   }
   return this->GetName();
 }
 
-const char* cmGeneratorTarget::GetProperty(const std::string& prop) const
+cmProp cmGeneratorTarget::GetProperty(const std::string& prop) const
 {
   if (!cmTargetPropertyComputer::PassesWhitelist(
         this->GetType(), prop, this->Makefile->GetMessenger(),
@@ -380,22 +380,22 @@ const char* cmGeneratorTarget::GetProperty(const std::string& prop) const
   }
   if (cmProp result = cmTargetPropertyComputer::GetProperty(
         this, prop, this->Makefile->GetMessenger(), this->GetBacktrace())) {
-    return result->c_str();
+    return result;
   }
   if (cmSystemTools::GetFatalErrorOccured()) {
     return nullptr;
   }
-  cmProp retval = this->Target->GetProperty(prop);
-  return retval ? retval->c_str() : nullptr;
+  return this->Target->GetProperty(prop);
 }
 
 const char* cmGeneratorTarget::GetSafeProperty(const std::string& prop) const
 {
-  const char* ret = this->GetProperty(prop);
+  cmProp ret = this->GetProperty(prop);
   if (!ret) {
     return "";
   }
-  return ret;
+
+  return ret->c_str();
 }
 
 const char* cmGeneratorTarget::GetOutputTargetType(
@@ -484,8 +484,8 @@ std::string cmGeneratorTarget::GetOutputName(
 
     std::string outName;
     for (std::string const& p : props) {
-      if (const char* outNameProp = this->GetProperty(p)) {
-        outName = outNameProp;
+      if (cmProp outNameProp = this->GetProperty(p)) {
+        outName = *outNameProp;
         break;
       }
     }
@@ -541,7 +541,7 @@ std::string cmGeneratorTarget::GetFileSuffix(
 
 std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
 {
-  const char* postfix = nullptr;
+  cmProp postfix = nullptr;
   std::string frameworkPostfix;
   if (!config.empty()) {
     std::string configProp =
@@ -559,16 +559,16 @@ std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
     // framework postfix.
     frameworkPostfix = GetFrameworkMultiConfigPostfix(config);
     if (!frameworkPostfix.empty()) {
-      postfix = frameworkPostfix.c_str();
+      postfix = &frameworkPostfix;
     }
   }
-  return postfix ? postfix : std::string();
+  return postfix ? *postfix : std::string();
 }
 
 std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix(
   const std::string& config) const
 {
-  const char* postfix = nullptr;
+  cmProp postfix = nullptr;
   if (!config.empty()) {
     std::string configProp = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_",
                                       cmSystemTools::UpperCase(config));
@@ -580,7 +580,7 @@ std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix(
       postfix = nullptr;
     }
   }
-  return postfix ? postfix : std::string();
+  return postfix ? *postfix : std::string();
 }
 
 const char* cmGeneratorTarget::GetFilePrefixInternal(
@@ -613,7 +613,7 @@ const char* cmGeneratorTarget::GetFilePrefixInternal(
   }
 
   // Compute prefix value.
-  const char* targetPrefix =
+  cmProp targetPrefix =
     (isImportedLibraryArtifact ? this->GetProperty("IMPORT_PREFIX")
                                : this->GetProperty("PREFIX"));
 
@@ -621,17 +621,17 @@ const char* cmGeneratorTarget::GetFilePrefixInternal(
     const char* prefixVar = this->Target->GetPrefixVariableInternal(artifact);
     if (!language.empty() && prefixVar && *prefixVar) {
       std::string langPrefix = prefixVar + std::string("_") + language;
-      targetPrefix = this->Makefile->GetDefinition(langPrefix);
+      targetPrefix = this->Makefile->GetDef(langPrefix);
     }
 
     // if there is no prefix on the target nor specific language
     // use the cmake definition.
     if (!targetPrefix && prefixVar) {
-      targetPrefix = this->Makefile->GetDefinition(prefixVar);
+      targetPrefix = this->Makefile->GetDef(prefixVar);
     }
   }
 
-  return targetPrefix;
+  return targetPrefix ? targetPrefix->c_str() : nullptr;
 }
 const char* cmGeneratorTarget::GetFileSuffixInternal(
   std::string const& config, cmStateEnums::ArtifactType artifact,
@@ -663,7 +663,7 @@ const char* cmGeneratorTarget::GetFileSuffixInternal(
   }
 
   // Compute suffix value.
-  const char* targetSuffix =
+  cmProp targetSuffix =
     (isImportedLibraryArtifact ? this->GetProperty("IMPORT_SUFFIX")
                                : this->GetProperty("SUFFIX"));
 
@@ -671,17 +671,17 @@ const char* cmGeneratorTarget::GetFileSuffixInternal(
     const char* suffixVar = this->Target->GetSuffixVariableInternal(artifact);
     if (!language.empty() && suffixVar && *suffixVar) {
       std::string langSuffix = suffixVar + std::string("_") + language;
-      targetSuffix = this->Makefile->GetDefinition(langSuffix);
+      targetSuffix = this->Makefile->GetDef(langSuffix);
     }
 
     // if there is no suffix on the target nor specific language
     // use the cmake definition.
     if (!targetSuffix && suffixVar) {
-      targetSuffix = this->Makefile->GetDefinition(suffixVar);
+      targetSuffix = this->Makefile->GetDef(suffixVar);
     }
   }
 
-  return targetSuffix;
+  return targetSuffix ? targetSuffix->c_str() : nullptr;
 }
 
 void cmGeneratorTarget::ClearSourcesCache()
@@ -743,9 +743,9 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
                              std::vector<std::string>& result,
                              bool excludeImported, std::string const& language)
 {
-  if (const char* dirs =
+  if (cmProp dirs =
         depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) {
-    cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget,
+    cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
                                                  dagChecker, depTgt, language),
                  result);
   }
@@ -753,9 +753,8 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
     return;
   }
 
-  if (const char* dirs =
-        depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
-    cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget,
+  if (cmProp dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
+    cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
                                                  dagChecker, depTgt, language),
                  result);
   }
@@ -811,12 +810,12 @@ const char* cmGeneratorTarget::GetFeature(const std::string& feature,
   if (!config.empty()) {
     std::string featureConfig =
       cmStrCat(feature, '_', cmSystemTools::UpperCase(config));
-    if (const char* value = this->GetProperty(featureConfig)) {
-      return value;
+    if (cmProp value = this->GetProperty(featureConfig)) {
+      return value->c_str();
     }
   }
-  if (const char* value = this->GetProperty(feature)) {
-    return value;
+  if (cmProp value = this->GetProperty(feature)) {
+    return value->c_str();
   }
   return this->LocalGenerator->GetFeature(feature, config);
 }
@@ -1172,8 +1171,8 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
     bool& maybeInterfaceProp = i->second;
 
     // If this target itself has a non-empty property value, we are done.
-    const char* p = this->GetProperty(prop);
-    maybeInterfaceProp = p && *p;
+    cmProp p = this->GetProperty(prop);
+    maybeInterfaceProp = p && !p->empty();
 
     // Otherwise, recurse to interface dependencies.
     if (!maybeInterfaceProp) {
@@ -1239,9 +1238,9 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
   cmGeneratorTarget const* headTarget =
     context->HeadTarget ? context->HeadTarget : this;
 
-  if (const char* p = this->GetProperty(prop)) {
+  if (cmProp p = this->GetProperty(prop)) {
     result = cmGeneratorExpressionNode::EvaluateDependentExpression(
-      p, context->LG, context, headTarget, &dagChecker, this);
+      *p, context->LG, context, headTarget, &dagChecker, this);
   }
 
   if (cmLinkInterfaceLibraries const* iface = this->GetLinkInterfaceLibraries(
@@ -1346,9 +1345,8 @@ void AddSwiftImplicitIncludeDirectories(
                          "Swift")) {
           EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
 
-          if (const char* val =
-                dependency->GetProperty("Swift_MODULE_DIRECTORY")) {
-            entry.Values.emplace_back(val);
+          if (cmProp val = dependency->GetProperty("Swift_MODULE_DIRECTORY")) {
+            entry.Values.emplace_back(*val);
           } else {
             entry.Values.emplace_back(
               dependency->GetLocalGenerator()->GetCurrentBinaryDirectory());
@@ -1825,14 +1823,14 @@ std::string cmGeneratorTarget::GetCompilePDBName(
   // Check for a per-configuration output directory target property.
   std::string configUpper = cmSystemTools::UpperCase(config);
   std::string configProp = cmStrCat("COMPILE_PDB_NAME_", configUpper);
-  const char* config_name = this->GetProperty(configProp);
-  if (config_name && *config_name) {
-    return prefix + config_name + ".pdb";
+  cmProp config_name = this->GetProperty(configProp);
+  if (config_name && !config_name->empty()) {
+    return prefix + *config_name + ".pdb";
   }
 
-  const char* name = this->GetProperty("COMPILE_PDB_NAME");
-  if (name && *name) {
-    return prefix + name + ".pdb";
+  cmProp name = this->GetProperty("COMPILE_PDB_NAME");
+  if (name && !name->empty()) {
+    return prefix + *name + ".pdb";
   }
 
   return "";
@@ -2014,10 +2012,9 @@ bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir(
     if (this->GetType() != cmStateEnums::SHARED_LIBRARY) {
       return false;
     }
-    const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
+    cmProp install_name = this->GetProperty("INSTALL_NAME_DIR");
     bool use_install_name = this->MacOSXUseInstallNameDir();
-    if (install_name && use_install_name &&
-        std::string(install_name) == "@rpath") {
+    if (install_name && use_install_name && *install_name == "@rpath") {
       install_name_is_rpath = true;
     } else if (install_name && use_install_name) {
       return false;
@@ -2073,7 +2070,7 @@ bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const
     return false;
   }
 
-  const char* macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
+  cmProp macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
   if (macosx_rpath_str) {
     return this->GetPropertyAsBool("MACOSX_RPATH");
   }
@@ -2090,10 +2087,10 @@ bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const
 
 bool cmGeneratorTarget::MacOSXUseInstallNameDir() const
 {
-  const char* build_with_install_name =
+  cmProp build_with_install_name =
     this->GetProperty("BUILD_WITH_INSTALL_NAME_DIR");
   if (build_with_install_name) {
-    return cmIsOn(build_with_install_name);
+    return cmIsOn(*build_with_install_name);
   }
 
   cmPolicies::PolicyStatus cmp0068 = this->GetPolicyStatusCMP0068();
@@ -2175,11 +2172,8 @@ std::string cmGeneratorTarget::GetAppBundleDirectory(
 {
   std::string fpath = cmStrCat(
     this->GetFullName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
-  const char* ext = this->GetProperty("BUNDLE_EXTENSION");
-  if (!ext) {
-    ext = "app";
-  }
-  fpath += ext;
+  cmProp ext = this->GetProperty("BUNDLE_EXTENSION");
+  fpath += (ext ? *ext : "app");
   if (shouldAddContentLevel(level) &&
       !this->Makefile->PlatformIsAppleEmbedded()) {
     fpath += "/Contents";
@@ -2201,8 +2195,10 @@ std::string cmGeneratorTarget::GetCFBundleDirectory(
 {
   std::string fpath = cmStrCat(
     this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
-  const char* ext = this->GetProperty("BUNDLE_EXTENSION");
-  if (!ext) {
+  std::string ext;
+  if (cmProp p = this->GetProperty("BUNDLE_EXTENSION")) {
+    ext = *p;
+  } else {
     if (this->IsXCTestOnApple()) {
       ext = "xctest";
     } else {
@@ -2225,11 +2221,8 @@ std::string cmGeneratorTarget::GetFrameworkDirectory(
 {
   std::string fpath = cmStrCat(
     this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
-  const char* ext = this->GetProperty("BUNDLE_EXTENSION");
-  if (!ext) {
-    ext = "framework";
-  }
-  fpath += ext;
+  cmProp ext = this->GetProperty("BUNDLE_EXTENSION");
+  fpath += (ext ? *ext : "framework");
   if (shouldAddFullLevel(level) &&
       !this->Makefile->PlatformIsAppleEmbedded()) {
     fpath += "/Versions/";
@@ -2280,11 +2273,11 @@ std::string cmGeneratorTarget::GetInstallNameDirForInstallTree(
 {
   if (this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
     std::string dir;
-    const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
+    cmProp install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
 
     if (this->CanGenerateInstallNameDir(INSTALL_NAME_FOR_INSTALL)) {
-      if (install_name_dir && *install_name_dir) {
-        dir = install_name_dir;
+      if (install_name_dir && !install_name_dir->empty()) {
+        dir = *install_name_dir;
         cmGeneratorExpression::ReplaceInstallPrefix(dir, installPrefix);
         dir =
           cmGeneratorExpression::Evaluate(dir, this->LocalGenerator, config);
@@ -2329,8 +2322,8 @@ const std::string* cmGeneratorTarget::GetExportMacro() const
   if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
       this->GetType() == cmStateEnums::MODULE_LIBRARY ||
       this->IsExecutableWithExports()) {
-    if (const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL")) {
-      this->ExportMacro = custom_export_name;
+    if (cmProp custom_export_name = this->GetProperty("DEFINE_SYMBOL")) {
+      this->ExportMacro = *custom_export_name;
     } else {
       std::string in = cmStrCat(this->GetName(), "_EXPORTS");
       this->ExportMacro = cmSystemTools::MakeCidentifier(in);
@@ -2617,9 +2610,9 @@ std::string cmGeneratorTarget::GetEffectiveFolderName() const
     return effectiveFolder;
   }
 
-  const char* targetFolder = this->GetProperty("FOLDER");
+  cmProp targetFolder = this->GetProperty("FOLDER");
   if (targetFolder) {
-    effectiveFolder += targetFolder;
+    effectiveFolder += *targetFolder;
   }
 
   return effectiveFolder;
@@ -3075,7 +3068,7 @@ std::string cmGeneratorTarget::GetCompilePDBDirectory(
 void cmGeneratorTarget::GetAppleArchs(const std::string& config,
                                       std::vector<std::string>& archVec) const
 {
-  const char* archs = nullptr;
+  cmProp archs = nullptr;
   if (!config.empty()) {
     std::string defVarName =
       cmStrCat("OSX_ARCHITECTURES_", cmSystemTools::UpperCase(config));
@@ -3085,7 +3078,7 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
     archs = this->GetProperty("OSX_ARCHITECTURES");
   }
   if (archs) {
-    cmExpandList(std::string(archs), archVec);
+    cmExpandList(*archs, archVec);
   }
 }
 
@@ -3641,7 +3634,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
   if (!config.empty()) {
     std::string configPropName =
       "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
-    const char* configProp = this->GetProperty(configPropName);
+    cmProp configProp = this->GetProperty(configPropName);
     if (configProp) {
       switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0043)) {
         case cmPolicies::WARN: {
@@ -3652,7 +3645,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
         }
         case cmPolicies::OLD: {
           std::unique_ptr<TargetPropertyEntry> entry =
-            CreateTargetPropertyEntry(configProp);
+            CreateTargetPropertyEntry(*configProp);
           entries.emplace_back(EvaluateTargetPropertyEntry(
             this, config, language, &dagChecker, *entry));
         } break;
@@ -3720,7 +3713,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
     return std::string();
   }
   const cmGeneratorTarget* generatorTarget = this;
-  const char* pchReuseFrom =
+  cmProp pchReuseFrom =
     generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
 
   const auto inserted =
@@ -3735,7 +3728,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
 
     if (pchReuseFrom) {
       generatorTarget =
-        this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+        this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
     }
 
     filename = cmStrCat(
@@ -3833,11 +3826,11 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
     std::string& filename = inserted.first->second;
 
     const cmGeneratorTarget* generatorTarget = this;
-    const char* pchReuseFrom =
+    cmProp pchReuseFrom =
       generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
     if (pchReuseFrom) {
       generatorTarget =
-        this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+        this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
     }
 
     filename =
@@ -3929,11 +3922,11 @@ std::string cmGeneratorTarget::GetPchFile(const std::string& config,
       };
 
       cmGeneratorTarget* generatorTarget = this;
-      const char* pchReuseFrom =
+      cmProp pchReuseFrom =
         generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
       if (pchReuseFrom) {
         generatorTarget =
-          this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+          this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
       }
 
       const std::string pchFileObject =
@@ -4211,8 +4204,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
                                              nullptr, nullptr);
 
   std::vector<EvaluatedTargetPropertyEntry> entries;
-  if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
-    std::vector<std::string> options = cmExpandedList(linkOptions);
+  if (cmProp linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
+    std::vector<std::string> options = cmExpandedList(*linkOptions);
     for (const auto& option : options) {
       std::unique_ptr<TargetPropertyEntry> entry =
         CreateTargetPropertyEntry(option);
@@ -4366,8 +4359,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
                                              nullptr);
 
   std::vector<EvaluatedTargetPropertyEntry> entries;
-  if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
-    std::vector<std::string> depends = cmExpandedList(linkDepends);
+  if (cmProp linkDepends = this->GetProperty("LINK_DEPENDS")) {
+    std::vector<std::string> depends = cmExpandedList(*linkDepends);
     for (const auto& depend : depends) {
       std::unique_ptr<TargetPropertyEntry> entry =
         CreateTargetPropertyEntry(depend);
@@ -4527,8 +4520,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
   }
 
   // Check for library version properties.
-  const char* version = this->GetProperty("VERSION");
-  const char* soversion = this->GetProperty("SOVERSION");
+  cmProp version = this->GetProperty("VERSION");
+  cmProp soversion = this->GetProperty("SOVERSION");
   if (!this->HasSOName(config) ||
       this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") ||
       this->IsFrameworkOnApple()) {
@@ -4569,11 +4562,12 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
     // The library's soname.
     this->ComputeVersionedName(targetNames.SharedObject, prefix,
                                targetNames.Base, suffix, targetNames.Output,
-                               soversion);
+                               (soversion ? soversion->c_str() : nullptr));
 
     // The library's real name on disk.
     this->ComputeVersionedName(targetNames.Real, prefix, targetNames.Base,
-                               suffix, targetNames.Output, version);
+                               suffix, targetNames.Output,
+                               (version ? version->c_str() : nullptr));
   }
 
   // The import library name.
@@ -4606,10 +4600,13 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames(
 // This versioning is supported only for executables and then only
 // when the platform supports symbolic links.
 #if defined(_WIN32) && !defined(__CYGWIN__)
-  const char* version = 0;
+  const char* version = nullptr;
 #else
   // Check for executable version properties.
-  const char* version = this->GetProperty("VERSION");
+  const char* version = nullptr;
+  if (cmProp p = this->GetProperty("VERSION")) {
+    version = p->c_str();
+  }
   if (this->GetType() != cmStateEnums::EXECUTABLE ||
       this->Makefile->IsOn("XCODE")) {
     version = nullptr;
@@ -4750,12 +4747,12 @@ void cmGeneratorTarget::GetFullNameInternal(
   }
 
   // Name shared libraries with their version number on some platforms.
-  if (const char* soversion = this->GetProperty("SOVERSION")) {
+  if (cmProp soversion = this->GetProperty("SOVERSION")) {
     if (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
         !isImportedLibraryArtifact &&
         this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION")) {
       outBase += "-";
-      outBase += soversion;
+      outBase += *soversion;
     }
   }
 
@@ -4786,8 +4783,8 @@ std::string cmGeneratorTarget::GetPDBOutputName(
   props.emplace_back("PDB_NAME");
 
   for (std::string const& p : props) {
-    if (const char* outName = this->GetProperty(p)) {
-      base = outName;
+    if (cmProp outName = this->GetProperty(p)) {
+      base = *outName;
       break;
     }
   }
@@ -4813,8 +4810,8 @@ std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
   props.emplace_back("PDB_NAME");
 
   for (std::string const& p : props) {
-    if (const char* outName = this->GetProperty(p)) {
-      base = outName;
+    if (cmProp outName = this->GetProperty(p)) {
+      base = *outName;
       break;
     }
   }
@@ -4916,8 +4913,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
   this->SourceFileFlagsConstructed = true;
 
   // Process public headers to mark the source files.
-  if (const char* files = this->GetProperty("PUBLIC_HEADER")) {
-    std::vector<std::string> relFiles = cmExpandedList(files);
+  if (cmProp files = this->GetProperty("PUBLIC_HEADER")) {
+    std::vector<std::string> relFiles = cmExpandedList(*files);
     for (std::string const& relFile : relFiles) {
       if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
         SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4929,8 +4926,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
 
   // Process private headers after public headers so that they take
   // precedence if a file is listed in both.
-  if (const char* files = this->GetProperty("PRIVATE_HEADER")) {
-    std::vector<std::string> relFiles = cmExpandedList(files);
+  if (cmProp files = this->GetProperty("PRIVATE_HEADER")) {
+    std::vector<std::string> relFiles = cmExpandedList(*files);
     for (std::string const& relFile : relFiles) {
       if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
         SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4941,8 +4938,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
   }
 
   // Mark sources listed as resources.
-  if (const char* files = this->GetProperty("RESOURCE")) {
-    std::vector<std::string> relFiles = cmExpandedList(files);
+  if (cmProp files = this->GetProperty("RESOURCE")) {
+    std::vector<std::string> relFiles = cmExpandedList(*files);
     for (std::string const& relFile : relFiles) {
       if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
         SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4969,9 +4966,9 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
       this->GetLinkImplementationClosure(config);
     for (cmGeneratorTarget const* li : deps) {
 #define CM_READ_COMPATIBLE_INTERFACE(X, x)                                    \
-  if (const char* prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) {       \
+  if (cmProp prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) {            \
     std::vector<std::string> props;                                           \
-    cmExpandList(prop, props);                                                \
+    cmExpandList(*prop, props);                                               \
     compat.Props##x.insert(props.begin(), props.end());                       \
   }
       CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
@@ -5079,12 +5076,12 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender,
                               const std::string& config, CompatibleType t,
                               PropertyType* /*unused*/)
 {
-  const char* prop = dependee->GetProperty(propName);
+  cmProp prop = dependee->GetProperty(propName);
   if (!prop) {
     return;
   }
 
-  std::vector<std::string> props = cmExpandedList(prop);
+  std::vector<std::string> props = cmExpandedList(*prop);
   std::string pdir =
     cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/prop_tgt/");
 
@@ -5314,8 +5311,9 @@ bool getTypedProperty<bool>(cmGeneratorTarget const* tgt,
     return tgt->GetPropertyAsBool(prop);
   }
 
-  const char* value = tgt->GetProperty(prop);
-  return cmIsOn(genexInterpreter->Evaluate(value, prop));
+  cmProp value = tgt->GetProperty(prop);
+  return cmIsOn(
+    genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop));
 }
 
 template <>
@@ -5323,13 +5321,14 @@ const char* getTypedProperty<const char*>(
   cmGeneratorTarget const* tgt, const std::string& prop,
   cmGeneratorExpressionInterpreter* genexInterpreter)
 {
-  const char* value = tgt->GetProperty(prop);
+  cmProp value = tgt->GetProperty(prop);
 
   if (genexInterpreter == nullptr) {
-    return value;
+    return value ? value->c_str() : nullptr;
   }
 
-  return genexInterpreter->Evaluate(value, prop).c_str();
+  return genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop)
+    .c_str();
 }
 
 template <>
@@ -5337,13 +5336,13 @@ std::string getTypedProperty<std::string>(
   cmGeneratorTarget const* tgt, const std::string& prop,
   cmGeneratorExpressionInterpreter* genexInterpreter)
 {
-  const char* value = tgt->GetProperty(prop);
+  cmProp value = tgt->GetProperty(prop);
 
   if (genexInterpreter == nullptr) {
-    return valueAsString(value);
+    return valueAsString(value ? value->c_str() : nullptr);
   }
 
-  return genexInterpreter->Evaluate(value, prop);
+  return genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop);
 }
 
 template <typename PropertyType>
@@ -5714,13 +5713,13 @@ void cmGeneratorTarget::GetTargetVersion(const std::string& property,
 
   assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
 
-  if (const char* version = this->GetProperty(property)) {
+  if (cmProp version = this->GetProperty(property)) {
     // Try to parse the version number and store the results that were
     // successfully parsed.
     int parsed_major;
     int parsed_minor;
     int parsed_patch;
-    switch (sscanf(version, "%d.%d.%d", &parsed_major, &parsed_minor,
+    switch (sscanf(version->c_str(), "%d.%d.%d", &parsed_major, &parsed_minor,
                    &parsed_patch)) {
       case 3:
         patch = parsed_patch;
@@ -5754,8 +5753,8 @@ std::string cmGeneratorTarget::CreateFortranModuleDirectory(
 {
   std::string mod_dir;
   std::string target_mod_dir;
-  if (const char* prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) {
-    target_mod_dir = prop;
+  if (cmProp prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) {
+    target_mod_dir = *prop;
   } else {
     std::string const& default_mod_dir =
       this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -5786,11 +5785,11 @@ std::string cmGeneratorTarget::GetFrameworkVersion() const
 {
   assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
 
-  if (const char* fversion = this->GetProperty("FRAMEWORK_VERSION")) {
-    return fversion;
+  if (cmProp fversion = this->GetProperty("FRAMEWORK_VERSION")) {
+    return *fversion;
   }
-  if (const char* tversion = this->GetProperty("VERSION")) {
-    return tversion;
+  if (cmProp tversion = this->GetProperty("VERSION")) {
+    return *tversion;
   }
   return "A";
 }
@@ -6026,11 +6025,11 @@ void cmGeneratorTarget::ComputeLinkInterface(
     // How many repetitions are needed if this library has cyclic
     // dependencies?
     std::string propName = cmStrCat("LINK_INTERFACE_MULTIPLICITY", suffix);
-    if (const char* config_reps = this->GetProperty(propName)) {
-      sscanf(config_reps, "%u", &iface.Multiplicity);
-    } else if (const char* reps =
+    if (cmProp config_reps = this->GetProperty(propName)) {
+      sscanf(config_reps->c_str(), "%u", &iface.Multiplicity);
+    } else if (cmProp reps =
                  this->GetProperty("LINK_INTERFACE_MULTIPLICITY")) {
-      sscanf(reps, "%u", &iface.Multiplicity);
+      sscanf(reps->c_str(), "%u", &iface.Multiplicity);
     }
   }
 }
@@ -6180,21 +6179,21 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config,
   }
 
   // Select an output directory.
-  if (const char* config_outdir = this->GetProperty(configProp)) {
+  if (cmProp config_outdir = this->GetProperty(configProp)) {
     // Use the user-specified per-configuration output directory.
-    out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator,
+    out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator,
                                           config);
 
     // Skip per-configuration subdirectory.
     conf.clear();
-  } else if (const char* outdir = this->GetProperty(propertyName)) {
+  } else if (cmProp outdir = this->GetProperty(propertyName)) {
     // Use the user-specified output directory.
     out =
-      cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config);
+      cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config);
 
     // Skip per-configuration subdirectory if the value contained a
     // generator expression.
-    if (out != outdir) {
+    if (out != *outdir) {
       conf.clear();
     }
   } else if (this->GetType() == cmStateEnums::EXECUTABLE) {
@@ -6256,21 +6255,21 @@ bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind,
   }
 
   // Select an output directory.
-  if (const char* config_outdir = this->GetProperty(configProp)) {
+  if (cmProp config_outdir = this->GetProperty(configProp)) {
     // Use the user-specified per-configuration output directory.
-    out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator,
+    out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator,
                                           config);
 
     // Skip per-configuration subdirectory.
     conf.clear();
-  } else if (const char* outdir = this->GetProperty(propertyName)) {
+  } else if (cmProp outdir = this->GetProperty(propertyName)) {
     // Use the user-specified output directory.
     out =
-      cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config);
+      cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config);
 
     // Skip per-configuration subdirectory if the value contained a
     // generator expression.
-    if (out != outdir) {
+    if (out != *outdir) {
       conf.clear();
     }
   }
@@ -6316,12 +6315,13 @@ bool cmGeneratorTarget::GetRPATH(const std::string& config,
                                  const std::string& prop,
                                  std::string& rpath) const
 {
-  const char* value = this->GetProperty(prop);
+  cmProp value = this->GetProperty(prop);
   if (!value) {
     return false;
   }
 
-  rpath = cmGeneratorExpression::Evaluate(value, this->LocalGenerator, config);
+  rpath =
+    cmGeneratorExpression::Evaluate(*value, this->LocalGenerator, config);
 
   return true;
 }
@@ -6340,7 +6340,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
 
   // An explicit list of interface libraries may be set for shared
   // libraries and executables that export symbols.
-  const char* explicitLibraries = nullptr;
+  cmProp explicitLibraries = nullptr;
   std::string linkIfaceProp;
   bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
                            this->GetPolicyStatusCMP0022() != cmPolicies::WARN);
@@ -6369,10 +6369,10 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
       !this->PolicyWarnedCMP0022) {
     // Compare the explicitly set old link interface properties to the
     // preferred new link interface property one and warn if different.
-    const char* newExplicitLibraries =
+    cmProp newExplicitLibraries =
       this->GetProperty("INTERFACE_LINK_LIBRARIES");
     if (newExplicitLibraries &&
-        strcmp(newExplicitLibraries, explicitLibraries) != 0) {
+        (*newExplicitLibraries != *explicitLibraries)) {
       std::ostringstream w;
       /* clang-format off */
       w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
@@ -6381,9 +6381,9 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
         linkIfaceProp << " properties."
         "\n"
         "INTERFACE_LINK_LIBRARIES:\n"
-        "  " << newExplicitLibraries << "\n" <<
+        "  " << *newExplicitLibraries << "\n" <<
         linkIfaceProp << ":\n"
-        "  " << explicitLibraries << "\n";
+        "  " << *explicitLibraries << "\n";
       /* clang-format on */
       this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
       this->PolicyWarnedCMP0022 = true;
@@ -6402,8 +6402,8 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
 
   if (explicitLibraries) {
     // The interface libraries have been explicitly set.
-    this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, headTarget,
-                          usage_requirements_only, iface.Libraries,
+    this->ExpandLinkItems(linkIfaceProp, *explicitLibraries, config,
+                          headTarget, usage_requirements_only, iface.Libraries,
                           iface.HadHeadSensitiveCondition,
                           iface.HadLinkLanguageSensitiveCondition);
   } else if (!cmp0022NEW)
@@ -6423,10 +6423,10 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
       // preferred new link interface property and warn if different.
       std::vector<cmLinkItem> ifaceLibs;
       static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
-      if (const char* newExplicitLibraries = this->GetProperty(newProp)) {
+      if (cmProp newExplicitLibraries = this->GetProperty(newProp)) {
         bool hadHeadSensitiveConditionDummy = false;
         bool hadLinkLanguageSensitiveConditionDummy = false;
-        this->ExpandLinkItems(newProp, newExplicitLibraries, config,
+        this->ExpandLinkItems(newProp, *newExplicitLibraries, config,
                               headTarget, usage_requirements_only, ifaceLibs,
                               hadHeadSensitiveConditionDummy,
                               hadLinkLanguageSensitiveConditionDummy);
@@ -6562,7 +6562,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
   // Get the link interface.
   {
     std::string linkProp = "INTERFACE_LINK_LIBRARIES";
-    const char* propertyLibs = this->GetProperty(linkProp);
+    cmProp propertyLibs = this->GetProperty(linkProp);
 
     if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
       if (!propertyLibs) {
@@ -6577,7 +6577,7 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
     }
     if (propertyLibs) {
       info.LibrariesProp = linkProp;
-      info.Libraries = propertyLibs;
+      info.Libraries = *propertyLibs;
     }
   }
   if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
@@ -6595,31 +6595,30 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
     info.Location = *loc;
   } else {
     std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
-    if (const char* config_location = this->GetProperty(impProp)) {
-      info.Location = config_location;
-    } else if (const char* location = this->GetProperty("IMPORTED_LOCATION")) {
-      info.Location = location;
+    if (cmProp config_location = this->GetProperty(impProp)) {
+      info.Location = *config_location;
+    } else if (cmProp location = this->GetProperty("IMPORTED_LOCATION")) {
+      info.Location = *location;
     }
   }
 
   // Get the soname.
   if (this->GetType() == cmStateEnums::SHARED_LIBRARY) {
     std::string soProp = cmStrCat("IMPORTED_SONAME", suffix);
-    if (const char* config_soname = this->GetProperty(soProp)) {
-      info.SOName = config_soname;
-    } else if (const char* soname = this->GetProperty("IMPORTED_SONAME")) {
-      info.SOName = soname;
+    if (cmProp config_soname = this->GetProperty(soProp)) {
+      info.SOName = *config_soname;
+    } else if (cmProp soname = this->GetProperty("IMPORTED_SONAME")) {
+      info.SOName = *soname;
     }
   }
 
   // Get the "no-soname" mark.
   if (this->GetType() == cmStateEnums::SHARED_LIBRARY) {
     std::string soProp = cmStrCat("IMPORTED_NO_SONAME", suffix);
-    if (const char* config_no_soname = this->GetProperty(soProp)) {
-      info.NoSOName = cmIsOn(config_no_soname);
-    } else if (const char* no_soname =
-                 this->GetProperty("IMPORTED_NO_SONAME")) {
-      info.NoSOName = cmIsOn(no_soname);
+    if (cmProp config_no_soname = this->GetProperty(soProp)) {
+      info.NoSOName = cmIsOn(*config_no_soname);
+    } else if (cmProp no_soname = this->GetProperty("IMPORTED_NO_SONAME")) {
+      info.NoSOName = cmIsOn(*no_soname);
     }
   }
 
@@ -6629,10 +6628,10 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
   } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
              this->IsExecutableWithExports()) {
     std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
-    if (const char* config_implib = this->GetProperty(impProp)) {
-      info.ImportLibrary = config_implib;
-    } else if (const char* implib = this->GetProperty("IMPORTED_IMPLIB")) {
-      info.ImportLibrary = implib;
+    if (cmProp config_implib = this->GetProperty(impProp)) {
+      info.ImportLibrary = *config_implib;
+    } else if (cmProp implib = this->GetProperty("IMPORTED_IMPLIB")) {
+      info.ImportLibrary = *implib;
     }
   }
 
@@ -6640,11 +6639,11 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
   {
     std::string linkProp =
       cmStrCat("IMPORTED_LINK_DEPENDENT_LIBRARIES", suffix);
-    if (const char* config_libs = this->GetProperty(linkProp)) {
-      info.SharedDeps = config_libs;
-    } else if (const char* libs =
+    if (cmProp config_libs = this->GetProperty(linkProp)) {
+      info.SharedDeps = *config_libs;
+    } else if (cmProp libs =
                  this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES")) {
-      info.SharedDeps = libs;
+      info.SharedDeps = *libs;
     }
   }
 
@@ -6652,21 +6651,21 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
   if (this->LinkLanguagePropagatesToDependents()) {
     std::string linkProp =
       cmStrCat("IMPORTED_LINK_INTERFACE_LANGUAGES", suffix);
-    if (const char* config_libs = this->GetProperty(linkProp)) {
-      info.Languages = config_libs;
-    } else if (const char* libs =
+    if (cmProp config_libs = this->GetProperty(linkProp)) {
+      info.Languages = *config_libs;
+    } else if (cmProp libs =
                  this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES")) {
-      info.Languages = libs;
+      info.Languages = *libs;
     }
   }
 
   // Get information if target is managed assembly.
   {
     std::string linkProp = "IMPORTED_COMMON_LANGUAGE_RUNTIME";
-    if (auto pc = this->GetProperty(linkProp + suffix)) {
-      info.Managed = this->CheckManagedType(pc);
-    } else if (auto p = this->GetProperty(linkProp)) {
-      info.Managed = this->CheckManagedType(p);
+    if (cmProp pc = this->GetProperty(linkProp + suffix)) {
+      info.Managed = this->CheckManagedType(*pc);
+    } else if (cmProp p = this->GetProperty(linkProp)) {
+      info.Managed = this->CheckManagedType(*p);
     }
   }
 
@@ -6674,11 +6673,11 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
   if (this->GetType() == cmStateEnums::STATIC_LIBRARY) {
     std::string linkProp =
       cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix);
-    if (const char* config_reps = this->GetProperty(linkProp)) {
-      sscanf(config_reps, "%u", &info.Multiplicity);
-    } else if (const char* reps =
+    if (cmProp config_reps = this->GetProperty(linkProp)) {
+      sscanf(config_reps->c_str(), "%u", &info.Multiplicity);
+    } else if (cmProp reps =
                  this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY")) {
-      sscanf(reps, "%u", &info.Multiplicity);
+      sscanf(reps->c_str(), "%u", &info.Multiplicity);
     }
   }
 }
@@ -6854,15 +6853,15 @@ std::string cmGeneratorTarget::CheckCMP0004(std::string const& item) const
 
 bool cmGeneratorTarget::IsDeprecated() const
 {
-  const char* deprecation = this->GetProperty("DEPRECATION");
-  return deprecation && *deprecation;
+  cmProp deprecation = this->GetProperty("DEPRECATION");
+  return deprecation && !deprecation->empty();
 }
 
 std::string cmGeneratorTarget::GetDeprecation() const
 {
   // find DEPRECATION property
-  if (const char* deprecation = this->GetProperty("DEPRECATION")) {
-    return deprecation;
+  if (cmProp deprecation = this->GetProperty("DEPRECATION")) {
+    return *deprecation;
   }
   return std::string();
 }
@@ -6919,9 +6918,9 @@ bool cmGeneratorTarget::IsCSharpOnly() const
   std::set<std::string> languages = this->GetAllConfigCompileLanguages();
   // Consider an explicit linker language property, but *not* the
   // computed linker language that may depend on linked targets.
-  const char* linkLang = this->GetProperty("LINKER_LANGUAGE");
-  if (linkLang && *linkLang) {
-    languages.insert(linkLang);
+  cmProp linkLang = this->GetProperty("LINKER_LANGUAGE");
+  if (linkLang && !linkLang->empty()) {
+    languages.insert(*linkLang);
   }
   return languages.size() == 1 && languages.count("CSharp") > 0;
 }
@@ -7299,8 +7298,8 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
   }
 
   // Check for explicitly set clr target property.
-  if (auto* clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
-    return this->CheckManagedType(clr);
+  if (cmProp clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+    return this->CheckManagedType(*clr);
   }
 
   // C# targets are always managed. This language specific check
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index dd46bb9..dc98407 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -31,6 +31,8 @@ class cmTarget;
 struct cmGeneratorExpressionContext;
 struct cmGeneratorExpressionDAGChecker;
 
+using cmProp = const std::string*;
+
 class cmGeneratorTarget
 {
 public:
@@ -76,7 +78,7 @@ public:
 
   std::vector<std::string> GetPropertyKeys() const;
   //! Might return a nullptr if the property is not set or invalid
-  const char* GetProperty(const std::string& prop) const;
+  cmProp GetProperty(const std::string& prop) const;
   //! Always returns a valid pointer
   const char* GetSafeProperty(const std::string& prop) const;
   bool GetPropertyAsBool(const std::string& prop) const;
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index f0c6d48..c8a844f 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -549,8 +549,8 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
    */
   for (auto& sg : groupFilesList) {
     std::ostream* fout;
-    bool useProjectFile =
-      cmIsOn(this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
+    bool useProjectFile = cmIsOn(*this->GeneratorTarget->GetProperty(
+                            "GHS_NO_SOURCE_GROUP_FILE")) ||
       cmIsOn(this->Makefile->GetDefinition("CMAKE_GHS_NO_SOURCE_GROUP_FILE"));
     if (useProjectFile || sg.empty()) {
       fout = &fout_proj;
@@ -720,9 +720,9 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
 
 bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
 {
-  const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
+  cmProp p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
   if (p) {
-    return cmIsOn(this->GeneratorTarget->GetProperty("ghs_integrity_app"));
+    return cmIsOn(*p);
   }
   std::vector<cmSourceFile*> sources;
   this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index e04eef1..f57ef04 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -45,8 +45,8 @@ cmGlobalCommonGenerator::ComputeDirectoryTargets() const
       }
       DirectoryTarget::Target t;
       t.GT = gt.get();
-      if (const char* exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
-        if (cmIsOn(exclude)) {
+      if (cmProp exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
+        if (cmIsOn(*exclude)) {
           // This target has been explicitly excluded.
           t.ExcludeFromAll = true;
         } else {
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index a6ca75f..2664fb0 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -303,10 +303,14 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const
     for (const auto& target : localGen->GetGeneratorTargets()) {
       if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
           target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
-          target->GetType() == cmStateEnums::TargetType::UTILITY ||
-          cmIsOn(target->GetProperty("ghs_integrity_app"))) {
+          target->GetType() == cmStateEnums::TargetType::UTILITY) {
         continue;
       }
+      if (cmProp p = target->GetProperty("ghs_integrity_app")) {
+        if (cmIsOn(*p)) {
+          continue;
+        }
+      }
 
       std::vector<std::string> configs;
       target->Makefile->GetConfigurations(configs);
@@ -371,10 +375,14 @@ bool cmGlobalGenerator::CheckTargetsForPchCompilePdb() const
     for (const auto& target : generator->GetGeneratorTargets()) {
       if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
           target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
-          target->GetType() == cmStateEnums::TargetType::UTILITY ||
-          cmIsOn(target->GetProperty("ghs_integrity_app"))) {
+          target->GetType() == cmStateEnums::TargetType::UTILITY) {
         continue;
       }
+      if (cmProp p = target->GetProperty("ghs_integrity_app")) {
+        if (cmIsOn(*p)) {
+          continue;
+        }
+      }
 
       const std::string reuseFrom =
         target->GetSafeProperty("PRECOMPILE_HEADERS_REUSE_FROM");
@@ -2160,8 +2168,8 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
   if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
     return true;
   }
-  if (const char* exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
-    return cmIsOn(exclude);
+  if (cmProp exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
+    return cmIsOn(*exclude);
   }
   // This target is included in its directory.  Check whether the
   // directory is excluded.
@@ -3040,7 +3048,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
 
 #ifndef CMAKE_BOOTSTRAP
   // Check whether labels are enabled for this target.
-  const char* targetLabels = target->GetProperty("LABELS");
+  cmProp targetLabels = target->GetProperty("LABELS");
   cmProp directoryLabels =
     target->Target->GetMakefile()->GetProperty("LABELS");
   const char* cmakeDirectoryLabels =
@@ -3060,7 +3068,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
     // List the target-wide labels.  All sources in the target get
     // these labels.
     if (targetLabels) {
-      cmExpandList(targetLabels, labels);
+      cmExpandList(*targetLabels, labels);
       if (!labels.empty()) {
         fout << "# Target labels\n";
         for (std::string const& l : labels) {
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 24559e6..651bfbd 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -376,8 +376,8 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
   std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
   std::string& rootBinaryDir)
 {
-  const char* projName = target->GetProperty("GENERATOR_FILE_NAME");
-  const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
+  cmProp projName = target->GetProperty("GENERATOR_FILE_NAME");
+  cmProp projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
   if (projName && projType) {
     cmLocalGenerator* lg = target->GetLocalGenerator();
     std::string dir = lg->GetCurrentBinaryDirectory();
@@ -390,9 +390,9 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
       }
     }
 
-    std::string projFile = dir + projName + FILE_EXTENSION;
+    std::string projFile = dir + *projName + FILE_EXTENSION;
     fout << projFile;
-    fout << ' ' << projType << '\n';
+    fout << ' ' << *projType << '\n';
   } else {
     /* Should never happen */
     std::string message =
@@ -469,7 +469,8 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget(
     if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       continue;
     }
-    if (!cmIsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) {
+    cmProp p = t->GetProperty("EXCLUDE_FROM_ALL");
+    if (!(p && cmIsOn(*p))) {
       defaultTargets.push_back(t);
     }
   }
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index d0aec61..7ada325 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -91,7 +91,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
                                                    cmGeneratorTarget const* t)
 {
   // check to see if this is a fortran build
-  const char* ext = ".vcproj";
+  std::string ext = ".vcproj";
   const char* project =
     "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
   if (this->TargetIsFortranOnly(t)) {
@@ -102,9 +102,9 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
     ext = ".csproj";
     project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"";
   }
-  const char* targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
+  cmProp targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
   if (targetExt) {
-    ext = targetExt;
+    ext = *targetExt;
   }
 
   std::string guid = this->GetGUID(dspname);
@@ -198,9 +198,9 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
     std::vector<std::string> mapConfig;
     const char* dstConfig = i.c_str();
     if (target.GetProperty("EXTERNAL_MSPROJECT")) {
-      if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
-                                             cmSystemTools::UpperCase(i))) {
-        cmExpandList(m, mapConfig);
+      if (cmProp m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
+                                        cmSystemTools::UpperCase(i))) {
+        cmExpandList(*m, mapConfig);
         if (!mapConfig.empty()) {
           dstConfig = mapConfig[0].c_str();
         }
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 4b8010a..428c748 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -342,19 +342,19 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
     if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       continue;
     }
-    const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+    cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT");
     if (expath) {
       std::set<std::string> allConfigurations(configs.begin(), configs.end());
-      const char* mapping = target->GetProperty("VS_PLATFORM_MAPPING");
+      cmProp mapping = target->GetProperty("VS_PLATFORM_MAPPING");
       this->WriteProjectConfigurations(fout, target->GetName(), *target,
                                        configs, allConfigurations,
-                                       mapping ? mapping : "");
+                                       mapping ? *mapping : "");
     } else {
       const std::set<std::string>& configsPartOfDefaultBuild =
         this->IsPartOfDefaultBuild(configs, projectTargets, target);
-      const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+      cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
       if (vcprojName) {
-        this->WriteProjectConfigurations(fout, vcprojName, *target, configs,
+        this->WriteProjectConfigurations(fout, *vcprojName, *target, configs,
                                          configsPartOfDefaultBuild);
       }
     }
@@ -375,17 +375,18 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
     bool written = false;
 
     // handle external vc project files
-    const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+    cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT");
     if (expath) {
       std::string project = target->GetName();
-      std::string location = expath;
+      std::string location = *expath;
 
+      cmProp p = target->GetProperty("VS_PROJECT_TYPE");
       this->WriteExternalProject(fout, project, location,
-                                 target->GetProperty("VS_PROJECT_TYPE"),
+                                 p ? p->c_str() : nullptr,
                                  target->GetUtilities());
       written = true;
     } else {
-      const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+      cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
       if (vcprojName) {
         cmLocalGenerator* lg = target->GetLocalGenerator();
         std::string dir = lg->GetCurrentBinaryDirectory();
@@ -393,7 +394,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
         if (dir == ".") {
           dir.clear(); // msbuild cannot handle ".\" prefix
         }
-        this->WriteProject(fout, vcprojName, dir, target);
+        this->WriteProject(fout, *vcprojName, dir, target);
         written = true;
       }
     }
@@ -438,11 +439,11 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends(
     if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       continue;
     }
-    const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+    cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
     if (vcprojName) {
       std::string dir =
         target->GetLocalGenerator()->GetCurrentSourceDirectory();
-      this->WriteProjectDepends(fout, vcprojName, dir.c_str(), target);
+      this->WriteProjectDepends(fout, *vcprojName, dir, target);
     }
   }
 }
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 1df76ca..29ca154 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -244,9 +244,9 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
     std::vector<std::string> mapConfig;
     const char* dstConfig = i.c_str();
     if (target.GetProperty("EXTERNAL_MSPROJECT")) {
-      if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
-                                             cmSystemTools::UpperCase(i))) {
-        cmExpandList(m, mapConfig);
+      if (cmProp m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
+                                        cmSystemTools::UpperCase(i))) {
+        cmExpandList(*m, mapConfig);
         if (!mapConfig.empty()) {
           dstConfig = mapConfig[0].c_str();
         }
@@ -286,15 +286,15 @@ bool cmGlobalVisualStudio8Generator::NeedsDeploy(
     return false;
   }
 
-  if (const char* prop = target.GetProperty("VS_SOLUTION_DEPLOY")) {
+  if (cmProp prop = target.GetProperty("VS_SOLUTION_DEPLOY")) {
     // If set, it dictates behavior
     return cmIsOn(
-      cmGeneratorExpression::Evaluate(prop, target.LocalGenerator, config));
+      cmGeneratorExpression::Evaluate(*prop, target.LocalGenerator, config));
   }
 
   // To be deprecated, disable deployment even if target supports it.
-  if (const char* prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) {
-    if (cmIsOn(cmGeneratorExpression::Evaluate(prop, target.LocalGenerator,
+  if (cmProp prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) {
+    if (cmIsOn(cmGeneratorExpression::Evaluate(*prop, target.LocalGenerator,
                                                config))) {
       // If true, always disable deployment
       return false;
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index b9f4609..28bd1ca 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -808,9 +808,9 @@ bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(
   // This allows the project to control the language choice in
   // a target with none of its own sources, e.g. when also using
   // object libraries.
-  const char* linkLang = gt->GetProperty("LINKER_LANGUAGE");
-  if (linkLang && *linkLang) {
-    languages.insert(linkLang);
+  cmProp linkLang = gt->GetProperty("LINKER_LANGUAGE");
+  if (linkLang && !linkLang->empty()) {
+    languages.insert(*linkLang);
   }
 
   // Intel Fortran .vfproj files do support the resource compiler.
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index f305246..77fa6fa 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1867,16 +1867,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
     this->CurrentLocalGenerator->GetStaticLibraryFlags(
       extraLinkOptions, configName, llang, gtgt);
   } else {
-    const char* targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
+    cmProp targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
     if (targetLinkFlags) {
       this->CurrentLocalGenerator->AppendFlags(extraLinkOptions,
-                                               targetLinkFlags);
+                                               *targetLinkFlags);
     }
     if (!configName.empty()) {
       std::string linkFlagsVar =
         cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(configName));
-      if (const char* linkFlags = gtgt->GetProperty(linkFlagsVar)) {
-        this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, linkFlags);
+      if (cmProp linkFlags = gtgt->GetProperty(linkFlagsVar)) {
+        this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, *linkFlags);
       }
     }
     std::vector<std::string> opts;
@@ -1912,8 +1912,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
   std::string pnsuffix;
   gtgt->GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
 
-  const char* version = gtgt->GetProperty("VERSION");
-  const char* soversion = gtgt->GetProperty("SOVERSION");
+  cmProp version = gtgt->GetProperty("VERSION");
+  cmProp soversion = gtgt->GetProperty("SOVERSION");
   if (!gtgt->HasSOName(configName) || gtgt->IsFrameworkOnApple()) {
     version = nullptr;
     soversion = nullptr;
@@ -1929,9 +1929,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
   std::string soName = pnbase;
   if (version && soversion) {
     realName += ".";
-    realName += version;
+    realName += *version;
     soName += ".";
-    soName += soversion;
+    soName += *soversion;
   }
 
   // Set attributes to specify the proper name for the target.
@@ -1977,10 +1977,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
         std::string fw_version = gtgt->GetFrameworkVersion();
         buildSettings->AddAttribute("FRAMEWORK_VERSION",
                                     this->CreateString(fw_version));
-        const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+        cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
         if (ext) {
           buildSettings->AddAttribute("WRAPPER_EXTENSION",
-                                      this->CreateString(ext));
+                                      this->CreateString(*ext));
         }
 
         std::string plist = this->ComputeInfoPListLocation(gtgt);
@@ -2018,10 +2018,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
           extraLinkOptions += " ";
           extraLinkOptions += createFlags;
         }
-        const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+        cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
         if (ext) {
           buildSettings->AddAttribute("WRAPPER_EXTENSION",
-                                      this->CreateString(ext));
+                                      this->CreateString(*ext));
         }
         std::string plist = this->ComputeInfoPListLocation(gtgt);
         // Xcode will create the final version of Info.plist at build time,
@@ -2052,10 +2052,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
         std::string fw_version = gtgt->GetFrameworkVersion();
         buildSettings->AddAttribute("FRAMEWORK_VERSION",
                                     this->CreateString(fw_version));
-        const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+        cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
         if (ext) {
           buildSettings->AddAttribute("WRAPPER_EXTENSION",
-                                      this->CreateString(ext));
+                                      this->CreateString(*ext));
         }
 
         std::string plist = this->ComputeInfoPListLocation(gtgt);
@@ -2091,10 +2091,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
 
       // Handle bundles and normal executables separately.
       if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
-        const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+        cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
         if (ext) {
           buildSettings->AddAttribute("WRAPPER_EXTENSION",
-                                      this->CreateString(ext));
+                                      this->CreateString(*ext));
         }
         std::string plist = this->ComputeInfoPListLocation(gtgt);
         // Xcode will create the final version of Info.plist at build time,
@@ -2416,9 +2416,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
         std::string attribute = prop.substr(16);
         this->FilterConfigurationAttribute(configName, attribute);
         if (!attribute.empty()) {
-          const char* pr = gtgt->GetProperty(prop);
+          const std::string pr = gtgt->GetSafeProperty(prop);
           std::string processed = cmGeneratorExpression::Evaluate(
-            pr ? pr : "", this->CurrentLocalGenerator, configName);
+            pr, this->CurrentLocalGenerator, configName);
           buildSettings->AddAttribute(attribute,
                                       this->CreateString(processed));
         }
@@ -2537,8 +2537,8 @@ const char* cmGlobalXCodeGenerator::GetTargetLinkFlagsVar(
 const char* cmGlobalXCodeGenerator::GetTargetFileType(
   cmGeneratorTarget* target)
 {
-  if (const char* e = target->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
-    return e;
+  if (cmProp e = target->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
+    return e->c_str();
   }
 
   switch (target->GetType()) {
@@ -2570,8 +2570,8 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType(
 const char* cmGlobalXCodeGenerator::GetTargetProductType(
   cmGeneratorTarget* target)
 {
-  if (const char* e = target->GetProperty("XCODE_PRODUCT_TYPE")) {
-    return e;
+  if (cmProp e = target->GetProperty("XCODE_PRODUCT_TYPE")) {
+    return e->c_str();
   }
 
   switch (target->GetType()) {
@@ -3407,12 +3407,12 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
       continue;
     }
 
-    const char* testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE");
+    cmProp testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE");
     if (!testee) {
       continue;
     }
 
-    testables[testee].push_back(obj.get());
+    testables[*testee].push_back(obj.get());
   }
 
   // generate scheme
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index e05daa8..37d8c28 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -24,6 +24,8 @@
 #include "cmTarget.h"
 #include "cmake.h"
 
+using cmProp = const std::string*; // just to silence IWYU
+
 cmInstallTargetGenerator::cmInstallTargetGenerator(
   std::string targetName, std::string const& dest, bool implib,
   std::string file_permissions, std::vector<std::string> const& configurations,
@@ -133,8 +135,10 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
         cmMakefile const* mf = this->Target->Target->GetMakefile();
 
         // Get App Bundle Extension
-        const char* ext = this->Target->GetProperty("BUNDLE_EXTENSION");
-        if (!ext) {
+        std::string ext;
+        if (cmProp p = this->Target->GetProperty("BUNDLE_EXTENSION")) {
+          ext = *p;
+        } else {
           ext = "app";
         }
 
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index b9a73b0..eebf328 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -177,11 +177,11 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
     return false;
   }
 
-  if (const char* resolveDeviceSymbols =
+  if (cmProp resolveDeviceSymbols =
         target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
     // If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need
     // to honor the value no matter what it is.
-    return cmIsOn(resolveDeviceSymbols);
+    return cmIsOn(*resolveDeviceSymbols);
   }
 
   // Determine if we have any dependencies that require
@@ -190,9 +190,9 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
     target.GetLinkClosure(config);
 
   if (cm::contains(closure->Languages, "CUDA")) {
-    if (const char* separableCompilation =
+    if (cmProp separableCompilation =
           target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
-      if (cmIsOn(separableCompilation)) {
+      if (cmIsOn(*separableCompilation)) {
         bool doDeviceLinking = false;
         switch (target.GetType()) {
           case cmStateEnums::SHARED_LIBRARY:
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 829f9cc..a2208e5 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -6,7 +6,6 @@
 #include <cassert>
 #include <cstdio>
 #include <cstdlib>
-#include <cstring>
 #include <initializer_list>
 #include <iterator>
 #include <sstream>
@@ -805,14 +804,14 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
     if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
       auto copyStandardToObjLang = [&](LanguagePair const& lang) -> bool {
         if (!target->GetProperty(cmStrCat(lang.first, "_STANDARD"))) {
-          auto* standard =
+          cmProp standard =
             target->GetProperty(cmStrCat(lang.second, "_STANDARD"));
           if (!standard) {
-            standard = this->Makefile->GetDefinition(
+            standard = this->Makefile->GetDef(
               cmStrCat("CMAKE_", lang.second, "_STANDARD_DEFAULT"));
           }
           target->Target->SetProperty(cmStrCat(lang.first, "_STANDARD"),
-                                      standard);
+                                      standard ? standard->c_str() : nullptr);
           return true;
         }
         return false;
@@ -821,9 +820,9 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
                                        const char* property) {
         if (!target->GetProperty(cmStrCat(lang.first, property)) &&
             target->GetProperty(cmStrCat(lang.second, property))) {
-          target->Target->SetProperty(
-            cmStrCat(lang.first, property),
-            target->GetProperty(cmStrCat(lang.second, property)));
+          cmProp p = target->GetProperty(cmStrCat(lang.second, property));
+          target->Target->SetProperty(cmStrCat(lang.first, property),
+                                      p ? p->c_str() : nullptr);
         }
       };
       for (auto const& lang : pairedLanguages) {
@@ -832,8 +831,8 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
           copyPropertyToObjLang(lang, "_EXTENSIONS");
         }
       }
-      if (const char* standard = target->GetProperty("CUDA_STANDARD")) {
-        if (std::string{ standard } == "98") {
+      if (cmProp standard = target->GetProperty("CUDA_STANDARD")) {
+        if (*standard == "98") {
           target->Target->SetProperty("CUDA_STANDARD", "03");
         }
       }
@@ -861,10 +860,12 @@ cmStateSnapshot cmLocalGenerator::GetStateSnapshot() const
 const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
                                               const std::string& prop)
 {
+  cmProp p;
   if (target) {
-    return target->GetProperty(prop);
+    p = target->GetProperty(prop);
+  } else {
+    p = this->Makefile->GetProperty(prop);
   }
-  cmProp p = this->Makefile->GetProperty(prop);
   return p ? p->c_str() : nullptr;
 }
 
@@ -992,9 +993,9 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
   if (const char* langFlagRegexStr =
         this->Makefile->GetDefinition(langFlagRegexVar)) {
     // Filter flags acceptable to this language.
-    if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) {
+    if (cmProp targetFlags = target->GetProperty("COMPILE_FLAGS")) {
       std::vector<std::string> opts;
-      cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
+      cmSystemTools::ParseWindowsCommandLine(targetFlags->c_str(), opts);
       // Re-escape these flags since COMPILE_FLAGS were already parsed
       // as a command line above.
       std::string compileOpts;
@@ -1009,10 +1010,10 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
     this->AppendCompileOptions(flags, targetCompileOpts, langFlagRegexStr);
   } else {
     // Use all flags.
-    if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) {
+    if (cmProp targetFlags = target->GetProperty("COMPILE_FLAGS")) {
       // COMPILE_FLAGS are not escaped for historical reasons.
       std::string compileFlags;
-      this->AppendFlags(compileFlags, targetFlags);
+      this->AppendFlags(compileFlags, *targetFlags);
       if (!compileFlags.empty()) {
         flags.emplace_back(std::move(compileFlags));
       }
@@ -1024,11 +1025,11 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
   }
 
   for (auto const& it : target->GetMaxLanguageStandards()) {
-    const char* standard = target->GetProperty(it.first + "_STANDARD");
+    cmProp standard = target->GetProperty(it.first + "_STANDARD");
     if (!standard) {
       continue;
     }
-    if (this->Makefile->IsLaterStandard(it.first, standard, it.second)) {
+    if (this->Makefile->IsLaterStandard(it.first, *standard, it.second)) {
       std::ostringstream e;
       e << "The COMPILE_FEATURES property of target \"" << target->GetName()
         << "\" was evaluated when computing the link "
@@ -1037,7 +1038,7 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
         << "\" for that computation.  Computing the "
            "COMPILE_FEATURES based on the link implementation resulted in a "
            "higher \""
-        << it.first << "_STANDARD\" \"" << standard
+        << it.first << "_STANDARD\" \"" << *standard
         << "\".  "
            "This is not permitted. The COMPILE_FEATURES may not both depend "
            "on "
@@ -1064,10 +1065,10 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
         cmGeneratorTarget::ManagedType::Managed) {
       // add /JMC flags if target property VS_JUST_MY_CODE_DEBUGGING is set
       // to ON
-      if (char const* jmcExprGen =
+      if (cmProp jmcExprGen =
             target->GetProperty("VS_JUST_MY_CODE_DEBUGGING")) {
         std::string isJMCEnabled =
-          cmGeneratorExpression::Evaluate(jmcExprGen, this, config);
+          cmGeneratorExpression::Evaluate(*jmcExprGen, this, config);
         if (cmIsOn(isJMCEnabled)) {
           std::vector<std::string> optVec = cmExpandedList(jmc);
           std::string jmcFlags;
@@ -1510,16 +1511,16 @@ void cmLocalGenerator::GetTargetFlags(
         }
       }
 
-      const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+      cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
       if (targetLinkFlags) {
-        sharedLibFlags += targetLinkFlags;
+        sharedLibFlags += *targetLinkFlags;
         sharedLibFlags += " ";
       }
       if (!configUpper.empty()) {
         targetLinkFlags =
           target->GetProperty(cmStrCat("LINK_FLAGS_", configUpper));
         if (targetLinkFlags) {
-          sharedLibFlags += targetLinkFlags;
+          sharedLibFlags += *targetLinkFlags;
           sharedLibFlags += " ";
         }
       }
@@ -1591,16 +1592,16 @@ void cmLocalGenerator::GetTargetFlags(
         exeFlags += " ";
       }
 
-      const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+      cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
       if (targetLinkFlags) {
-        exeFlags += targetLinkFlags;
+        exeFlags += *targetLinkFlags;
         exeFlags += " ";
       }
       if (!configUpper.empty()) {
         targetLinkFlags =
           target->GetProperty(cmStrCat("LINK_FLAGS_", configUpper));
         if (targetLinkFlags) {
-          exeFlags += targetLinkFlags;
+          exeFlags += *targetLinkFlags;
           exeFlags += " ";
         }
       }
@@ -1975,12 +1976,12 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
                                config);
 
   if (lang == "Swift") {
-    if (const char* v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
+    if (cmProp v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
       if (cmSystemTools::VersionCompare(
             cmSystemTools::OP_GREATER_EQUAL,
             this->Makefile->GetDefinition("CMAKE_Swift_COMPILER_VERSION"),
             "4.2")) {
-        this->AppendFlags(flags, "-swift-version " + std::string(v));
+        this->AppendFlags(flags, "-swift-version " + *v);
       }
     }
   } else if (lang == "CUDA") {
@@ -1989,16 +1990,16 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
 
   // Add MSVC runtime library flags.  This is activated by the presence
   // of a default selection whether or not it is overridden by a property.
-  const char* msvcRuntimeLibraryDefault =
-    this->Makefile->GetDefinition("CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT");
-  if (msvcRuntimeLibraryDefault && *msvcRuntimeLibraryDefault) {
-    const char* msvcRuntimeLibraryValue =
+  cmProp msvcRuntimeLibraryDefault =
+    this->Makefile->GetDef("CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT");
+  if (msvcRuntimeLibraryDefault && !msvcRuntimeLibraryDefault->empty()) {
+    cmProp msvcRuntimeLibraryValue =
       target->GetProperty("MSVC_RUNTIME_LIBRARY");
     if (!msvcRuntimeLibraryValue) {
       msvcRuntimeLibraryValue = msvcRuntimeLibraryDefault;
     }
     std::string const msvcRuntimeLibrary = cmGeneratorExpression::Evaluate(
-      msvcRuntimeLibraryValue, this, config, target);
+      *msvcRuntimeLibraryValue, this, config, target);
     if (!msvcRuntimeLibrary.empty()) {
       if (const char* msvcRuntimeLibraryOptions =
             this->Makefile->GetDefinition(
@@ -2177,13 +2178,13 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
   }
   std::string extProp = lang + "_EXTENSIONS";
   bool ext = true;
-  if (const char* extPropValue = target->GetProperty(extProp)) {
-    if (cmIsOff(extPropValue)) {
+  if (cmProp extPropValue = target->GetProperty(extProp)) {
+    if (cmIsOff(*extPropValue)) {
       ext = false;
     }
   }
   std::string stdProp = lang + "_STANDARD";
-  const char* standardProp = target->GetProperty(stdProp);
+  cmProp standardProp = target->GetProperty(stdProp);
   if (!standardProp) {
     if (ext) {
       // No language standard is specified and extensions are not disabled.
@@ -2205,7 +2206,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
 
   if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED")) {
     std::string option_flag =
-      "CMAKE_" + lang + standardProp + "_" + type + "_COMPILE_OPTION";
+      "CMAKE_" + lang + *standardProp + "_" + type + "_COMPILE_OPTION";
 
     const char* opt =
       target->Target->GetMakefile()->GetDefinition(option_flag);
@@ -2214,7 +2215,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
       e << "Target \"" << target->GetName()
         << "\" requires the language "
            "dialect \""
-        << lang << standardProp << "\" "
+        << lang << *standardProp << "\" "
         << (ext ? "(with compiler extensions)" : "")
         << ", but CMake "
            "does not know the compile flags to use to enable it.";
@@ -2258,7 +2259,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
     langStdMap["CUDA"].emplace_back("03");
   }
 
-  std::string standard(standardProp);
+  std::string standard(*standardProp);
   if (lang == "CUDA" && standard == "98") {
     standard = "03";
   }
@@ -2331,7 +2332,7 @@ static void AddVisibilityCompileOption(std::string& flags,
   }
   std::string flagDefine = lang + "_VISIBILITY_PRESET";
 
-  const char* prop = target->GetProperty(flagDefine);
+  cmProp prop = target->GetProperty(flagDefine);
   if (!prop) {
     return;
   }
@@ -2339,17 +2340,17 @@ static void AddVisibilityCompileOption(std::string& flags,
     *warnCMP0063 += "  " + flagDefine + "\n";
     return;
   }
-  if (strcmp(prop, "hidden") != 0 && strcmp(prop, "default") != 0 &&
-      strcmp(prop, "protected") != 0 && strcmp(prop, "internal") != 0) {
+  if ((*prop != "hidden") && (*prop != "default") && (*prop != "protected") &&
+      (*prop != "internal")) {
     std::ostringstream e;
-    e << "Target " << target->GetName() << " uses unsupported value \"" << prop
-      << "\" for " << flagDefine << "."
+    e << "Target " << target->GetName() << " uses unsupported value \""
+      << *prop << "\" for " << flagDefine << "."
       << " The supported values are: default, hidden, protected, and "
          "internal.";
     cmSystemTools::Error(e.str());
     return;
   }
-  std::string option = std::string(opt) + prop;
+  std::string option = opt + *prop;
   lg->AppendFlags(flags, option);
 }
 
@@ -2616,14 +2617,14 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
           continue;
         }
 
-        const char* pchReuseFrom =
+        cmProp ReuseFrom =
           target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
 
         auto pch_sf = this->Makefile->GetOrCreateSource(
           pchSource, false, cmSourceFileLocationKind::Known);
 
         if (!this->GetGlobalGenerator()->IsXcode()) {
-          if (!pchReuseFrom) {
+          if (!ReuseFrom) {
             target->AddSource(pchSource, true);
           }
 
@@ -2631,11 +2632,11 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
 
           // Exclude the pch files from linking
           if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
-            if (!pchReuseFrom) {
+            if (!ReuseFrom) {
               pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
             } else {
               auto reuseTarget =
-                this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
+                this->GlobalGenerator->FindGeneratorTarget(*ReuseFrom);
 
               if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
 
@@ -2657,22 +2658,22 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
                   const std::string from_file =
                     cmStrCat(reuseTarget->GetLocalGenerator()
                                ->GetCurrentBinaryDirectory(),
-                             "/", pchReuseFrom, ".dir/${PDB_PREFIX}",
-                             pchReuseFrom, extension);
+                             "/", *ReuseFrom, ".dir/${PDB_PREFIX}", *ReuseFrom,
+                             extension);
 
                   const std::string to_dir = cmStrCat(
                     target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
                     "/", target->GetName(), ".dir/${PDB_PREFIX}");
 
                   const std::string to_file =
-                    cmStrCat(to_dir, pchReuseFrom, extension);
+                    cmStrCat(to_dir, *ReuseFrom, extension);
 
                   std::string dest_file = to_file;
 
                   const std::string prefix = target->GetSafeProperty("PREFIX");
                   if (!prefix.empty()) {
                     dest_file =
-                      cmStrCat(to_dir, prefix, pchReuseFrom, extension);
+                      cmStrCat(to_dir, prefix, *ReuseFrom, extension);
                   }
 
                   file << "if (EXISTS \"" << from_file << "\" AND \""
@@ -2702,7 +2703,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
 
                 std::vector<std::string> outputs;
                 outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
-                                           pchReuseFrom, ".pdb"));
+                                           *ReuseFrom, ".pdb"));
 
                 if (this->GetGlobalGenerator()->IsVisualStudio()) {
                   this->AddCustomCommandToTarget(
@@ -2774,12 +2775,14 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
   std::vector<cmSourceFile*> sources;
   target->GetSourceFiles(sources, config);
 
-  auto batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
-  const size_t unityBatchSize =
-    static_cast<size_t>(std::atoi(batchSizeString));
+  cmProp batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
+  const size_t unityBatchSize = batchSizeString
+    ? static_cast<size_t>(std::atoi(batchSizeString->c_str()))
+    : 0;
 
-  auto beforeInclude = target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
-  auto afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
+  cmProp beforeInclude =
+    target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
+  cmProp afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
 
   for (std::string lang : { "C", "CXX" }) {
     std::vector<cmSourceFile*> filtered_sources;
@@ -2824,13 +2827,13 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
           sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
 
           if (beforeInclude) {
-            file << beforeInclude << "\n";
+            file << *beforeInclude << "\n";
           }
 
           file << "#include \"" << sf->ResolveFullPath() << "\"\n";
 
           if (afterInclude) {
-            file << afterInclude << "\n";
+            file << *afterInclude << "\n";
           }
         }
       }
@@ -3190,8 +3193,8 @@ void cmLocalGenerator::GenerateTargetInstallRules(
     }
 
     // Include the user-specified pre-install script for this target.
-    if (const char* preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) {
-      cmInstallScriptGenerator g(preinstall, false, "", false);
+    if (cmProp preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) {
+      cmInstallScriptGenerator g(*preinstall, false, "", false);
       g.Generate(os, config, configurationTypes);
     }
 
@@ -3243,8 +3246,8 @@ void cmLocalGenerator::GenerateTargetInstallRules(
     }
 
     // Include the user-specified post-install script for this target.
-    if (const char* postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) {
-      cmInstallScriptGenerator g(postinstall, false, "", false);
+    if (cmProp postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) {
+      cmInstallScriptGenerator g(*postinstall, false, "", false);
       g.Generate(os, config, configurationTypes);
     }
   }
@@ -3655,8 +3658,8 @@ bool cmLocalGenerator::CheckDefinition(std::string const& define) const
 static void cmLGInfoProp(cmMakefile* mf, cmGeneratorTarget* target,
                          const std::string& prop)
 {
-  if (const char* val = target->GetProperty(prop)) {
-    mf->AddDefinition(prop, val);
+  if (cmProp val = target->GetProperty(prop)) {
+    mf->AddDefinition(prop, *val);
   }
 }
 
@@ -3665,8 +3668,9 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmGeneratorTarget* target,
                                               const std::string& fname)
 {
   // Find the Info.plist template.
-  const char* in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
-  std::string inFile = (in && *in) ? in : "MacOSXBundleInfo.plist.in";
+  cmProp in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
+  std::string inFile =
+    (in && !in->empty()) ? *in : "MacOSXBundleInfo.plist.in";
   if (!cmSystemTools::FileIsFullPath(inFile)) {
     std::string inMod = this->Makefile->GetModulesFile(inFile);
     if (!inMod.empty()) {
@@ -3704,8 +3708,9 @@ void cmLocalGenerator::GenerateFrameworkInfoPList(
   const std::string& fname)
 {
   // Find the Info.plist template.
-  const char* in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
-  std::string inFile = (in && *in) ? in : "MacOSXFrameworkInfo.plist.in";
+  cmProp in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
+  std::string inFile =
+    (in && !in->empty()) ? *in : "MacOSXFrameworkInfo.plist.in";
   if (!cmSystemTools::FileIsFullPath(inFile)) {
     std::string inMod = this->Makefile->GetModulesFile(inFile);
     if (!inMod.empty()) {
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 1401e29..4c7c8c4 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1546,10 +1546,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
       std::vector<std::string> commands;
       std::vector<std::string> depends;
 
-      const char* text = gt->GetProperty("EchoString");
-      if (!text) {
-        text = "Running external command ...";
-      }
+      cmProp p = gt->GetProperty("EchoString");
+      const char* text = p ? p->c_str() : "Running external command ...";
       depends.reserve(gt->GetUtilities().size());
       for (BT<std::pair<std::string, bool>> const& u : gt->GetUtilities()) {
         depends.push_back(u.Value.first);
@@ -1870,9 +1868,9 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
         this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
     cmExpandList(*xform, transformRules);
   }
-  if (const char* xform =
+  if (cmProp xform =
         target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
-    cmExpandList(xform, transformRules);
+    cmExpandList(*xform, transformRules);
   }
   if (!transformRules.empty()) {
     cmakefileStream << "set(CMAKE_INCLUDE_TRANSFORMS\n";
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 8daffa0..e18fac3 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -70,9 +70,9 @@ void cmLocalVisualStudio7Generator::AddHelperCommands()
     if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       continue;
     }
-    const char* path = l->GetProperty("EXTERNAL_MSPROJECT");
+    cmProp path = l->GetProperty("EXTERNAL_MSPROJECT");
     if (path) {
-      this->ReadAndStoreExternalGUID(l->GetName(), path);
+      this->ReadAndStoreExternalGUID(l->GetName(), path->c_str());
     }
   }
 
@@ -778,12 +778,11 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
   fout << "\t\t\t<Tool\n"
        << "\t\t\t\tName=\"" << tool << "\"\n";
   if (this->FortranProject) {
-    const char* target_mod_dir =
-      target->GetProperty("Fortran_MODULE_DIRECTORY");
+    cmProp target_mod_dir = target->GetProperty("Fortran_MODULE_DIRECTORY");
     std::string modDir;
     if (target_mod_dir) {
       modDir = this->MaybeConvertToRelativePath(
-        this->GetCurrentBinaryDirectory(), target_mod_dir);
+        this->GetCurrentBinaryDirectory(), *target_mod_dir);
     } else {
       modDir = ".";
     }
@@ -937,17 +936,17 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
       " " + GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName);
   }
 
-  const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+  cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
   if (targetLinkFlags) {
     extraLinkOptions += " ";
-    extraLinkOptions += targetLinkFlags;
+    extraLinkOptions += *targetLinkFlags;
   }
   std::string configTypeUpper = cmSystemTools::UpperCase(configName);
   std::string linkFlagsConfig = cmStrCat("LINK_FLAGS_", configTypeUpper);
   targetLinkFlags = target->GetProperty(linkFlagsConfig);
   if (targetLinkFlags) {
     extraLinkOptions += " ";
-    extraLinkOptions += targetLinkFlags;
+    extraLinkOptions += *targetLinkFlags;
   }
 
   std::vector<std::string> opts;
@@ -1205,8 +1204,8 @@ void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool(
   std::ostream& fout, std::string const& config, cmGeneratorTarget* target)
 {
   if (this->WindowsCEProject) {
-    const char* dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
-    const char* additionalFiles =
+    cmProp dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
+    cmProp additionalFiles =
       target->GetProperty("DEPLOYMENT_ADDITIONAL_FILES");
 
     if (dir == nullptr && additionalFiles == nullptr) {
@@ -1216,15 +1215,15 @@ void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool(
     fout << "\t\t\t<DeploymentTool\n"
             "\t\t\t\tForceDirty=\"-1\"\n"
             "\t\t\t\tRemoteDirectory=\""
-         << GetEscapedPropertyIfValueNotNULL(dir)
+         << GetEscapedPropertyIfValueNotNULL(dir->c_str())
          << "\"\n"
             "\t\t\t\tRegisterOutput=\"0\"\n"
             "\t\t\t\tAdditionalFiles=\""
-         << GetEscapedPropertyIfValueNotNULL(additionalFiles) << "\"/>\n";
+         << GetEscapedPropertyIfValueNotNULL(additionalFiles->c_str())
+         << "\"/>\n";
 
     if (dir != nullptr) {
-      std::string const exe =
-        dir + std::string("\\") + target->GetFullName(config);
+      std::string const exe = *dir + "\\" + target->GetFullName(config);
 
       fout << "\t\t\t<DebuggerTool\n"
               "\t\t\t\tRemoteExecutable=\""
@@ -1876,20 +1875,20 @@ void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout,
 {
   // if we have all the required Source code control tags
   // then add that to the project
-  const char* vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME");
-  const char* vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH");
-  const char* vsProvider = target->GetProperty("VS_SCC_PROVIDER");
+  cmProp vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME");
+  cmProp vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH");
+  cmProp vsProvider = target->GetProperty("VS_SCC_PROVIDER");
 
   if (vsProvider && vsLocalpath && vsProjectname) {
     /* clang-format off */
-    fout << "\tSccProjectName=\"" << vsProjectname << "\"\n"
-         << "\tSccLocalPath=\"" << vsLocalpath << "\"\n"
-         << "\tSccProvider=\"" << vsProvider << "\"\n";
+    fout << "\tSccProjectName=\"" << *vsProjectname << "\"\n"
+         << "\tSccLocalPath=\"" << *vsLocalpath << "\"\n"
+         << "\tSccProvider=\"" << *vsProvider << "\"\n";
     /* clang-format on */
 
-    const char* vsAuxPath = target->GetProperty("VS_SCC_AUXPATH");
+    cmProp vsAuxPath = target->GetProperty("VS_SCC_AUXPATH");
     if (vsAuxPath) {
-      fout << "\tSccAuxPath=\"" << vsAuxPath << "\"\n";
+      fout << "\tSccAuxPath=\"" << *vsAuxPath << "\"\n";
     }
   }
 }
@@ -1907,10 +1906,8 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
        << "\tProjectCreator=\"Intel Fortran\"\n"
        << "\tVersion=\"" << gg->GetIntelProjectVersion() << "\"\n";
   /* clang-format on */
-  const char* keyword = target->GetProperty("VS_KEYWORD");
-  if (!keyword) {
-    keyword = "Console Application";
-  }
+  cmProp p = target->GetProperty("VS_KEYWORD");
+  const char* keyword = p ? p->c_str() : "Console Application";
   const char* projectType = 0;
   switch (target->GetType()) {
     case cmStateEnums::STATIC_LIBRARY:
@@ -1969,20 +1966,16 @@ void cmLocalVisualStudio7Generator::WriteProjectStart(
        << "\tProjectType=\"Visual C++\"\n";
   /* clang-format on */
   fout << "\tVersion=\"" << (gg->GetVersion() / 10) << ".00\"\n";
-  const char* projLabel = target->GetProperty("PROJECT_LABEL");
-  if (!projLabel) {
-    projLabel = libName.c_str();
-  }
-  const char* keyword = target->GetProperty("VS_KEYWORD");
-  if (!keyword) {
-    keyword = "Win32Proj";
-  }
+  cmProp p = target->GetProperty("PROJECT_LABEL");
+  const std::string projLabel = p ? *p : libName;
+  p = target->GetProperty("VS_KEYWORD");
+  const std::string keyword = p ? *p : "Win32Proj";
   fout << "\tName=\"" << projLabel << "\"\n";
   fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n";
   this->WriteProjectSCC(fout, target);
-  if (const char* targetFrameworkVersion =
+  if (cmProp targetFrameworkVersion =
         target->GetProperty("VS_DOTNET_TARGET_FRAMEWORK_VERSION")) {
-    fout << "\tTargetFrameworkVersion=\"" << targetFrameworkVersion << "\"\n";
+    fout << "\tTargetFrameworkVersion=\"" << *targetFrameworkVersion << "\"\n";
   }
   /* clang-format off */
   fout << "\tKeyword=\"" << keyword << "\">\n"
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 267d5e1..45c84ee 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -184,9 +184,9 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
   }
 
   // Look for additional files registered for cleaning in this target.
-  if (const char* prop_value =
+  if (cmProp prop_value =
         this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
-    std::vector<std::string> const files = evaluatedFiles(prop_value);
+    std::vector<std::string> const files = evaluatedFiles(*prop_value);
     // For relative path support
     std::string const& binaryDir =
       this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -797,25 +797,24 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
         (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
          lang == "OBJC" || lang == "OBJCXX")) {
       std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
-      const char* clauncher =
-        this->GeneratorTarget->GetProperty(clauncher_prop);
-      if (clauncher && *clauncher) {
-        compilerLauncher = clauncher;
+      cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
+      if (clauncher && !clauncher->empty()) {
+        compilerLauncher = *clauncher;
       }
     }
 
     // Maybe insert an include-what-you-use runner.
     if (!compileCommands.empty() && (lang == "C" || lang == "CXX")) {
       std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
-      const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+      cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
       std::string const tidy_prop = lang + "_CLANG_TIDY";
-      const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+      cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
       std::string const cpplint_prop = lang + "_CPPLINT";
-      const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+      cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
       std::string const cppcheck_prop = lang + "_CPPCHECK";
-      const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
-      if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
-          (cppcheck && *cppcheck)) {
+      cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+      if ((iwyu && !iwyu->empty()) || (tidy && !tidy->empty()) ||
+          (cpplint && !cpplint->empty()) || (cppcheck && !cppcheck->empty())) {
         std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_co_compile";
         if (!compilerLauncher.empty()) {
           // In __run_co_compile case the launcher command is supplied
@@ -824,11 +823,11 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
           run_iwyu += this->LocalGenerator->EscapeForShell(compilerLauncher);
           compilerLauncher.clear();
         }
-        if (iwyu && *iwyu) {
+        if (iwyu && !iwyu->empty()) {
           run_iwyu += " --iwyu=";
-          run_iwyu += this->LocalGenerator->EscapeForShell(iwyu);
+          run_iwyu += this->LocalGenerator->EscapeForShell(*iwyu);
         }
-        if (tidy && *tidy) {
+        if (tidy && !tidy->empty()) {
           run_iwyu += " --tidy=";
           const char* driverMode = this->Makefile->GetDefinition(
             "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
@@ -836,18 +835,18 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
             driverMode = lang == "C" ? "gcc" : "g++";
           }
           run_iwyu += this->LocalGenerator->EscapeForShell(
-            cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode));
+            cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
         }
-        if (cpplint && *cpplint) {
+        if (cpplint && !cpplint->empty()) {
           run_iwyu += " --cpplint=";
-          run_iwyu += this->LocalGenerator->EscapeForShell(cpplint);
+          run_iwyu += this->LocalGenerator->EscapeForShell(*cpplint);
         }
-        if (cppcheck && *cppcheck) {
+        if (cppcheck && !cppcheck->empty()) {
           run_iwyu += " --cppcheck=";
-          run_iwyu += this->LocalGenerator->EscapeForShell(cppcheck);
+          run_iwyu += this->LocalGenerator->EscapeForShell(*cppcheck);
         }
-        if ((tidy && *tidy) || (cpplint && *cpplint) ||
-            (cppcheck && *cppcheck)) {
+        if ((tidy && !tidy->empty()) || (cpplint && !cpplint->empty()) ||
+            (cppcheck && !cppcheck->empty())) {
           run_iwyu += " --source=";
           run_iwyu += sourceFile;
         }
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 49e8af9..db069ed 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -847,8 +847,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
     }();
 
     vars["SWIFT_MODULE_NAME"] = [gt]() -> std::string {
-      if (const char* name = gt->GetProperty("Swift_MODULE_NAME")) {
-        return name;
+      if (cmProp name = gt->GetProperty("Swift_MODULE_NAME")) {
+        return *name;
       }
       return gt->GetName();
     }();
@@ -856,15 +856,15 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
     vars["SWIFT_MODULE"] = [this](const std::string& module) -> std::string {
       std::string directory =
         this->GetLocalGenerator()->GetCurrentBinaryDirectory();
-      if (const char* prop = this->GetGeneratorTarget()->GetProperty(
+      if (cmProp prop = this->GetGeneratorTarget()->GetProperty(
             "Swift_MODULE_DIRECTORY")) {
-        directory = prop;
+        directory = *prop;
       }
 
       std::string name = module + ".swiftmodule";
-      if (const char* prop =
+      if (cmProp prop =
             this->GetGeneratorTarget()->GetProperty("Swift_MODULE")) {
-        name = prop;
+        name = *prop;
       }
 
       return this->GetLocalGenerator()->ConvertToOutputFormat(
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 701c44f..0606484 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -746,24 +746,24 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
       (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
        lang == "OBJC" || lang == "OBJCXX")) {
     std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER");
-    const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
-    if (clauncher && *clauncher) {
-      compilerLauncher = clauncher;
+    cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
+    if (clauncher && !clauncher->empty()) {
+      compilerLauncher = *clauncher;
     }
   }
 
   // Maybe insert an include-what-you-use runner.
   if (!compileCmds.empty() && (lang == "C" || lang == "CXX")) {
     std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
-    const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+    cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
     std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
-    const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+    cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
     std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
-    const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+    cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
     std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
-    const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
-    if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
-        (cppcheck && *cppcheck)) {
+    cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+    if ((iwyu && !iwyu->empty()) || (tidy && !tidy->empty()) ||
+        (cpplint && !cpplint->empty()) || (cppcheck && !cppcheck->empty())) {
       std::string run_iwyu = cmStrCat(cmakeCmd, " -E __run_co_compile");
       if (!compilerLauncher.empty()) {
         // In __run_co_compile case the launcher command is supplied
@@ -773,11 +773,11 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
                    this->LocalGenerator->EscapeForShell(compilerLauncher));
         compilerLauncher.clear();
       }
-      if (iwyu && *iwyu) {
+      if (iwyu && !iwyu->empty()) {
         run_iwyu += cmStrCat(" --iwyu=",
-                             this->GetLocalGenerator()->EscapeForShell(iwyu));
+                             this->GetLocalGenerator()->EscapeForShell(*iwyu));
       }
-      if (tidy && *tidy) {
+      if (tidy && !tidy->empty()) {
         run_iwyu += " --tidy=";
         const char* driverMode = this->Makefile->GetDefinition(
           cmStrCat("CMAKE_", lang, "_CLANG_TIDY_DRIVER_MODE"));
@@ -785,18 +785,19 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
           driverMode = lang == "C" ? "gcc" : "g++";
         }
         run_iwyu += this->GetLocalGenerator()->EscapeForShell(
-          cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode));
+          cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
       }
-      if (cpplint && *cpplint) {
+      if (cpplint && !cpplint->empty()) {
         run_iwyu += cmStrCat(
-          " --cpplint=", this->GetLocalGenerator()->EscapeForShell(cpplint));
+          " --cpplint=", this->GetLocalGenerator()->EscapeForShell(*cpplint));
       }
-      if (cppcheck && *cppcheck) {
-        run_iwyu += cmStrCat(
-          " --cppcheck=", this->GetLocalGenerator()->EscapeForShell(cppcheck));
+      if (cppcheck && !cppcheck->empty()) {
+        run_iwyu +=
+          cmStrCat(" --cppcheck=",
+                   this->GetLocalGenerator()->EscapeForShell(*cppcheck));
       }
-      if ((tidy && *tidy) || (cpplint && *cpplint) ||
-          (cppcheck && *cppcheck)) {
+      if ((tidy && !tidy->empty()) || (cpplint && !cpplint->empty()) ||
+          (cppcheck && !cppcheck->empty())) {
         run_iwyu += " --source=$in";
       }
       run_iwyu += " -- ";
@@ -976,8 +977,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
                "output-file-map.json");
     std::string const targetSwiftDepsPath = [this, config]() -> std::string {
       cmGeneratorTarget const* target = this->GeneratorTarget;
-      if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
-        return name;
+      if (cmProp name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
+        return *name;
       }
       return this->ConvertToNinjaPath(
         cmStrCat(target->GetSupportDirectory(), '/', config, '/',
@@ -1444,11 +1445,11 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
 
 void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
 {
-  if (const char* prop_value =
+  if (cmProp prop_value =
         this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
     cmLocalNinjaGenerator* lg = this->LocalGenerator;
     std::vector<std::string> cleanFiles;
-    cmExpandList(cmGeneratorExpression::Evaluate(prop_value, lg, config,
+    cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, lg, config,
                                                  this->GeneratorTarget),
                  cleanFiles);
     std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
@@ -1534,9 +1535,9 @@ void cmNinjaTargetGenerator::addPoolNinjaVariable(
   const std::string& pool_property, cmGeneratorTarget* target,
   cmNinjaVars& vars)
 {
-  const char* pool = target->GetProperty(pool_property);
+  cmProp pool = target->GetProperty(pool_property);
   if (pool) {
-    vars["pool"] = pool;
+    vars["pool"] = *pool;
   }
 }
 
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index a42d65d..134924e 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -110,9 +110,9 @@ void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
     std::string command =
       lg->BuildCommandLine(commands, "utility", this->GeneratorTarget);
     std::string desc;
-    const char* echoStr = genTarget->GetProperty("EchoString");
+    cmProp echoStr = genTarget->GetProperty("EchoString");
     if (echoStr) {
-      desc = echoStr;
+      desc = *echoStr;
     } else {
       desc = "Running utility command for " + this->GetTargetName();
     }
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index b0a7c30..fa523cc 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -339,21 +339,18 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
 
   // Targets FOLDER
   {
-    cmProp prop =
+    cmProp folder =
       this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
-    if (prop == nullptr) {
-      prop = this->Makefile->GetState()->GetGlobalProperty(
+    if (folder == nullptr) {
+      folder = this->Makefile->GetState()->GetGlobalProperty(
         "AUTOGEN_TARGETS_FOLDER");
     }
-    const char* folder;
     // Inherit FOLDER property from target (#13688)
-    if (prop == nullptr) {
+    if (folder == nullptr) {
       folder = this->GenTarget->GetProperty("FOLDER");
-    } else {
-      folder = prop->c_str();
     }
     if (folder != nullptr) {
-      this->TargetsFolder = folder;
+      this->TargetsFolder = *folder;
     }
   }
 
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 1142dbd..025a7b3 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -100,9 +100,9 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
     exe = target->GetFullPath(config);
 
     // Prepend with the emulator when cross compiling if required.
-    const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
-    if (emulator != nullptr && *emulator) {
-      std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
+    cmProp emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
+    if (emulator != nullptr && !emulator->empty()) {
+      std::vector<std::string> emulatorWithArgs = cmExpandedList(*emulator);
       std::string emulatorExe(emulatorWithArgs[0]);
       cmSystemTools::ConvertToUnixSlashes(emulatorExe);
       os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 5f79eb0..9c2b302 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -431,32 +431,32 @@ void cmVisualStudio10TargetGenerator::Generate()
         this->VerifyNecessaryFiles();
       }
 
-      const char* vsProjectTypes =
+      cmProp vsProjectTypes =
         this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES");
       if (vsProjectTypes) {
         const char* tagName = "ProjectTypes";
         if (this->ProjectType == csproj) {
           tagName = "ProjectTypeGuids";
         }
-        e1.Element(tagName, vsProjectTypes);
+        e1.Element(tagName, *vsProjectTypes);
       }
 
-      const char* vsProjectName =
+      cmProp vsProjectName =
         this->GeneratorTarget->GetProperty("VS_SCC_PROJECTNAME");
-      const char* vsLocalPath =
+      cmProp vsLocalPath =
         this->GeneratorTarget->GetProperty("VS_SCC_LOCALPATH");
-      const char* vsProvider =
+      cmProp vsProvider =
         this->GeneratorTarget->GetProperty("VS_SCC_PROVIDER");
 
       if (vsProjectName && vsLocalPath && vsProvider) {
-        e1.Element("SccProjectName", vsProjectName);
-        e1.Element("SccLocalPath", vsLocalPath);
-        e1.Element("SccProvider", vsProvider);
+        e1.Element("SccProjectName", *vsProjectName);
+        e1.Element("SccLocalPath", *vsLocalPath);
+        e1.Element("SccProvider", *vsProvider);
 
-        const char* vsAuxPath =
+        cmProp vsAuxPath =
           this->GeneratorTarget->GetProperty("VS_SCC_AUXPATH");
         if (vsAuxPath) {
-          e1.Element("SccAuxPath", vsAuxPath);
+          e1.Element("SccAuxPath", *vsAuxPath);
         }
       }
 
@@ -464,45 +464,44 @@ void cmVisualStudio10TargetGenerator::Generate()
         e1.Element("WinMDAssembly", "true");
       }
 
-      const char* vsGlobalKeyword =
+      cmProp vsGlobalKeyword =
         this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD");
       if (!vsGlobalKeyword) {
         e1.Element("Keyword", "Win32Proj");
       } else {
-        e1.Element("Keyword", vsGlobalKeyword);
+        e1.Element("Keyword", *vsGlobalKeyword);
       }
 
-      const char* vsGlobalRootNamespace =
+      cmProp vsGlobalRootNamespace =
         this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE");
       if (vsGlobalRootNamespace) {
-        e1.Element("RootNamespace", vsGlobalRootNamespace);
+        e1.Element("RootNamespace", *vsGlobalRootNamespace);
       }
 
       e1.Element("Platform", this->Platform);
-      const char* projLabel =
-        this->GeneratorTarget->GetProperty("PROJECT_LABEL");
+      cmProp projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL");
       if (!projLabel) {
-        projLabel = this->Name.c_str();
+        projLabel = &this->Name;
       }
-      e1.Element("ProjectName", projLabel);
+      e1.Element("ProjectName", *projLabel);
       {
-        const char* targetFramework =
+        cmProp targetFramework =
           this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK");
         if (targetFramework) {
-          if (std::strchr(targetFramework, ';') != nullptr) {
-            e1.Element("TargetFrameworks", targetFramework);
+          if (std::strchr(targetFramework->c_str(), ';') != nullptr) {
+            e1.Element("TargetFrameworks", *targetFramework);
           } else {
-            e1.Element("TargetFramework", targetFramework);
+            e1.Element("TargetFramework", *targetFramework);
           }
         } else {
           // TODO: add deprecation warning for VS_* property?
-          const char* targetFrameworkVersion =
-            this->GeneratorTarget->GetProperty(
-              "VS_DOTNET_TARGET_FRAMEWORK_VERSION");
-          if (!targetFrameworkVersion) {
-            targetFrameworkVersion = this->GeneratorTarget->GetProperty(
+          cmProp p = this->GeneratorTarget->GetProperty(
+            "VS_DOTNET_TARGET_FRAMEWORK_VERSION");
+          if (!p) {
+            p = this->GeneratorTarget->GetProperty(
               "DOTNET_TARGET_FRAMEWORK_VERSION");
           }
+          const char* targetFrameworkVersion = p ? p->c_str() : nullptr;
           if (!targetFrameworkVersion && this->ProjectType == csproj &&
               this->GlobalGenerator->TargetsWindowsCE() &&
               this->GlobalGenerator->GetVersion() ==
@@ -521,18 +520,15 @@ void cmVisualStudio10TargetGenerator::Generate()
         }
         if (this->ProjectType == csproj &&
             this->GlobalGenerator->TargetsWindowsCE()) {
-          const char* targetFrameworkId = this->GeneratorTarget->GetProperty(
+          cmProp targetFrameworkId = this->GeneratorTarget->GetProperty(
             "VS_TARGET_FRAMEWORK_IDENTIFIER");
-          if (!targetFrameworkId) {
-            targetFrameworkId = "WindowsEmbeddedCompact";
-          }
-          e1.Element("TargetFrameworkIdentifier", targetFrameworkId);
-          const char* targetFrameworkVer = this->GeneratorTarget->GetProperty(
+          e1.Element("TargetFrameworkIdentifier",
+                     targetFrameworkId ? *targetFrameworkId
+                                       : "WindowsEmbeddedCompact");
+          cmProp targetFrameworkVer = this->GeneratorTarget->GetProperty(
             "VS_TARGET_FRAMEWORKS_TARGET_VERSION");
-          if (!targetFrameworkVer) {
-            targetFrameworkVer = "v8.0";
-          }
-          e1.Element("TargetFrameworkTargetsVersion", targetFrameworkVer);
+          e1.Element("TargetFrameworkTargetsVersion",
+                     targetFrameworkVer ? *targetFrameworkVer : "v8.0");
         }
         if (!this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString()
                .empty()) {
@@ -568,10 +564,10 @@ void cmVisualStudio10TargetGenerator::Generate()
             globalKey == "ROOTNAMESPACE" || globalKey == "KEYWORD") {
           continue;
         }
-        const char* value = this->GeneratorTarget->GetProperty(keyIt);
+        cmProp value = this->GeneratorTarget->GetProperty(keyIt);
         if (!value)
           continue;
-        e1.Element(globalKey, value);
+        e1.Element(globalKey, *value);
       }
 
       if (this->Managed) {
@@ -676,9 +672,8 @@ void cmVisualStudio10TargetGenerator::Generate()
           props = VS10_CSharp_USER_PROPS;
           break;
       }
-      if (const char* p =
-            this->GeneratorTarget->GetProperty("VS_USER_PROPS")) {
-        props = p;
+      if (cmProp p = this->GeneratorTarget->GetProperty("VS_USER_PROPS")) {
+        props = *p;
       }
       if (!props.empty()) {
         ConvertToWindowsSlash(props);
@@ -784,9 +779,9 @@ void cmVisualStudio10TargetGenerator::Generate()
 void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
 {
   std::vector<std::string> packageReferences;
-  if (const char* vsPackageReferences =
+  if (cmProp vsPackageReferences =
         this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) {
-    cmExpandList(vsPackageReferences, packageReferences);
+    cmExpandList(*vsPackageReferences, packageReferences);
   }
   if (!packageReferences.empty()) {
     Elem e1(e0, "ItemGroup");
@@ -804,9 +799,9 @@ void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
 void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
 {
   std::vector<std::string> references;
-  if (const char* vsDotNetReferences =
+  if (cmProp vsDotNetReferences =
         this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) {
-    cmExpandList(vsDotNetReferences, references);
+    cmExpandList(*vsDotNetReferences, references);
   }
   cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
   for (auto const& i : props.GetList()) {
@@ -863,9 +858,9 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference(
   e2.Element("ReferenceOutputAssembly", "true");
   if (!hint.empty()) {
     const char* privateReference = "True";
-    if (const char* value = this->GeneratorTarget->GetProperty(
+    if (cmProp value = this->GeneratorTarget->GetProperty(
           "VS_DOTNET_REFERENCES_COPY_LOCAL")) {
-      if (cmIsOff(value)) {
+      if (cmIsOff(*value)) {
         privateReference = "False";
       }
     }
@@ -1082,9 +1077,9 @@ void cmVisualStudio10TargetGenerator::WriteTargetsFileReferences(Elem& e1)
 void cmVisualStudio10TargetGenerator::WriteWinRTReferences(Elem& e0)
 {
   std::vector<std::string> references;
-  if (const char* vsWinRTReferences =
+  if (cmProp vsWinRTReferences =
         this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES")) {
-    cmExpandList(vsWinRTReferences, references);
+    cmExpandList(*vsWinRTReferences, references);
   }
 
   if (this->GlobalGenerator->TargetsWindowsPhone() &&
@@ -1125,9 +1120,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
 
     if (this->ProjectType != csproj) {
       std::string configType;
-      if (const char* vsConfigurationType =
+      if (cmProp vsConfigurationType =
             this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) {
-        configType = cmGeneratorExpression::Evaluate(vsConfigurationType,
+        configType = cmGeneratorExpression::Evaluate(*vsConfigurationType,
                                                      this->LocalGenerator, c);
       } else {
         switch (this->GeneratorTarget->GetType()) {
@@ -1183,9 +1178,9 @@ void cmVisualStudio10TargetGenerator::WriteCEDebugProjectConfigurationValues(
   if (!this->GlobalGenerator->TargetsWindowsCE()) {
     return;
   }
-  const char* additionalFiles =
+  cmProp additionalFiles =
     this->GeneratorTarget->GetProperty("DEPLOYMENT_ADDITIONAL_FILES");
-  const char* remoteDirectory =
+  cmProp remoteDirectory =
     this->GeneratorTarget->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
   if (!(additionalFiles || remoteDirectory)) {
     return;
@@ -1195,10 +1190,10 @@ void cmVisualStudio10TargetGenerator::WriteCEDebugProjectConfigurationValues(
     e1.Attribute("Condition", this->CalcCondition(c));
 
     if (remoteDirectory) {
-      e1.Element("RemoteDirectory", remoteDirectory);
+      e1.Element("RemoteDirectory", *remoteDirectory);
     }
     if (additionalFiles) {
-      e1.Element("CEAdditionalFiles", additionalFiles);
+      e1.Element("CEAdditionalFiles", *additionalFiles);
     }
   }
 }
@@ -1236,9 +1231,9 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues(
   } else {
     e1.Element("CharacterSet", "MultiByte");
   }
-  if (const char* projectToolsetOverride =
+  if (cmProp projectToolsetOverride =
         this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
-    e1.Element("PlatformToolset", projectToolsetOverride);
+    e1.Element("PlatformToolset", *projectToolsetOverride);
   } else if (const char* toolset = gg->GetPlatformToolset()) {
     e1.Element("PlatformToolset", toolset);
   }
@@ -1282,9 +1277,9 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
     o.RemoveFlag("Platform");
   }
 
-  if (const char* projectToolsetOverride =
+  if (cmProp projectToolsetOverride =
         this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
-    e1.Element("PlatformToolset", projectToolsetOverride);
+    e1.Element("PlatformToolset", *projectToolsetOverride);
   } else if (const char* toolset = gg->GetPlatformToolset()) {
     e1.Element("PlatformToolset", toolset);
   }
@@ -1293,8 +1288,8 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
     cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX");
   std::string assemblyName = this->GeneratorTarget->GetOutputName(
     config, cmStateEnums::RuntimeBinaryArtifact);
-  if (const char* postfix = this->GeneratorTarget->GetProperty(postfixName)) {
-    assemblyName += postfix;
+  if (cmProp postfix = this->GeneratorTarget->GetProperty(postfixName)) {
+    assemblyName += *postfix;
   }
   e1.Element("AssemblyName", assemblyName);
 
@@ -1314,22 +1309,20 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues(
   cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
   const char* toolset = gg->GetPlatformToolset();
   e1.Element("NdkToolchainVersion", toolset ? toolset : "Default");
-  if (const char* minApi =
-        this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) {
-    e1.Element("AndroidMinAPI", "android-" + std::string(minApi));
+  if (cmProp minApi = this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) {
+    e1.Element("AndroidMinAPI", "android-" + *minApi);
   }
-  if (const char* api = this->GeneratorTarget->GetProperty("ANDROID_API")) {
-    e1.Element("AndroidTargetAPI", "android-" + std::string(api));
+  if (cmProp api = this->GeneratorTarget->GetProperty("ANDROID_API")) {
+    e1.Element("AndroidTargetAPI", "android-" + *api);
   }
 
-  if (const char* cpuArch =
-        this->GeneratorTarget->GetProperty("ANDROID_ARCH")) {
-    e1.Element("AndroidArch", cpuArch);
+  if (cmProp cpuArch = this->GeneratorTarget->GetProperty("ANDROID_ARCH")) {
+    e1.Element("AndroidArch", *cpuArch);
   }
 
-  if (const char* stlType =
+  if (cmProp stlType =
         this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) {
-    e1.Element("AndroidStlType", stlType);
+    e1.Element("AndroidStlType", *stlType);
   }
 }
 
@@ -2512,34 +2505,34 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
     const std::string cond = this->CalcCondition(config);
 
     if (ttype <= cmStateEnums::UTILITY) {
-      if (const char* workingDir = this->GeneratorTarget->GetProperty(
+      if (cmProp workingDir = this->GeneratorTarget->GetProperty(
             "VS_DEBUGGER_WORKING_DIRECTORY")) {
         std::string genWorkingDir = cmGeneratorExpression::Evaluate(
-          workingDir, this->LocalGenerator, config);
+          *workingDir, this->LocalGenerator, config);
         e1.WritePlatformConfigTag("LocalDebuggerWorkingDirectory", cond,
                                   genWorkingDir);
       }
 
-      if (const char* environment =
+      if (cmProp environment =
             this->GeneratorTarget->GetProperty("VS_DEBUGGER_ENVIRONMENT")) {
         std::string genEnvironment = cmGeneratorExpression::Evaluate(
-          environment, this->LocalGenerator, config);
+          *environment, this->LocalGenerator, config);
         e1.WritePlatformConfigTag("LocalDebuggerEnvironment", cond,
                                   genEnvironment);
       }
 
-      if (const char* debuggerCommand =
+      if (cmProp debuggerCommand =
             this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) {
         std::string genDebuggerCommand = cmGeneratorExpression::Evaluate(
-          debuggerCommand, this->LocalGenerator, config);
+          *debuggerCommand, this->LocalGenerator, config);
         e1.WritePlatformConfigTag("LocalDebuggerCommand", cond,
                                   genDebuggerCommand);
       }
 
-      if (const char* commandArguments = this->GeneratorTarget->GetProperty(
+      if (cmProp commandArguments = this->GeneratorTarget->GetProperty(
             "VS_DEBUGGER_COMMAND_ARGUMENTS")) {
         std::string genCommandArguments = cmGeneratorExpression::Evaluate(
-          commandArguments, this->LocalGenerator, config);
+          *commandArguments, this->LocalGenerator, config);
         e1.WritePlatformConfigTag("LocalDebuggerCommandArguments", cond,
                                   genCommandArguments);
       }
@@ -2799,9 +2792,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
         this->Makefile->IssueMessage(MessageType::WARNING, message);
       }
     }
-    if (auto* clr =
+    if (cmProp clr =
           this->GeneratorTarget->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
-      std::string clrString = clr;
+      std::string clrString = *clr;
       if (!clrString.empty()) {
         clrString = ":" + clrString;
       }
@@ -2919,9 +2912,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
   oh.OutputPreprocessorDefinitions(this->LangForClCompile);
 
   if (this->NsightTegra) {
-    if (const char* processMax =
+    if (cmProp processMax =
           this->GeneratorTarget->GetProperty("ANDROID_PROCESS_MAX")) {
-      e2.Element("ProcessMax", processMax);
+      e2.Element("ProcessMax", *processMax);
     }
   }
 
@@ -3466,7 +3459,7 @@ void cmVisualStudio10TargetGenerator::WriteManifestOptions(
   std::vector<cmSourceFile const*> manifest_srcs;
   this->GeneratorTarget->GetManifests(manifest_srcs, config);
 
-  const char* dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE");
+  cmProp dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE");
 
   if (!manifest_srcs.empty() || dpiAware) {
     Elem e2(e1, "Manifest");
@@ -3480,15 +3473,14 @@ void cmVisualStudio10TargetGenerator::WriteManifestOptions(
       e2.Element("AdditionalManifestFiles", oss.str());
     }
     if (dpiAware) {
-      if (!strcmp(dpiAware, "PerMonitor")) {
+      if (*dpiAware == "PerMonitor") {
         e2.Element("EnableDpiAwareness", "PerMonitorHighDPIAware");
-      } else if (cmIsOn(dpiAware)) {
+      } else if (cmIsOn(*dpiAware)) {
         e2.Element("EnableDpiAwareness", "true");
-      } else if (cmIsOff(dpiAware)) {
+      } else if (cmIsOff(*dpiAware)) {
         e2.Element("EnableDpiAwareness", "false");
       } else {
-        cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " +
-                             std::string(dpiAware));
+        cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " + *dpiAware);
       }
     }
   }
@@ -3528,51 +3520,51 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
     e2.Element("EnableProGuard", "true");
   }
 
-  if (const char* proGuardConfigLocation =
+  if (cmProp proGuardConfigLocation =
         this->GeneratorTarget->GetProperty("ANDROID_PROGUARD_CONFIG_PATH")) {
-    e2.Element("ProGuardConfigLocation", proGuardConfigLocation);
+    e2.Element("ProGuardConfigLocation", *proGuardConfigLocation);
   }
 
-  if (const char* securePropertiesLocation =
+  if (cmProp securePropertiesLocation =
         this->GeneratorTarget->GetProperty("ANDROID_SECURE_PROPS_PATH")) {
-    e2.Element("SecurePropertiesLocation", securePropertiesLocation);
+    e2.Element("SecurePropertiesLocation", *securePropertiesLocation);
   }
 
-  if (const char* nativeLibDirectoriesExpression =
+  if (cmProp nativeLibDirectoriesExpression =
         this->GeneratorTarget->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES")) {
     std::string nativeLibDirs = cmGeneratorExpression::Evaluate(
-      nativeLibDirectoriesExpression, this->LocalGenerator, configName);
+      *nativeLibDirectoriesExpression, this->LocalGenerator, configName);
     e2.Element("NativeLibDirectories", nativeLibDirs);
   }
 
-  if (const char* nativeLibDependenciesExpression =
+  if (cmProp nativeLibDependenciesExpression =
         this->GeneratorTarget->GetProperty(
           "ANDROID_NATIVE_LIB_DEPENDENCIES")) {
     std::string nativeLibDeps = cmGeneratorExpression::Evaluate(
-      nativeLibDependenciesExpression, this->LocalGenerator, configName);
+      *nativeLibDependenciesExpression, this->LocalGenerator, configName);
     e2.Element("NativeLibDependencies", nativeLibDeps);
   }
 
-  if (const char* javaSourceDir =
+  if (cmProp javaSourceDir =
         this->GeneratorTarget->GetProperty("ANDROID_JAVA_SOURCE_DIR")) {
-    e2.Element("JavaSourceDir", javaSourceDir);
+    e2.Element("JavaSourceDir", *javaSourceDir);
   }
 
-  if (const char* jarDirectoriesExpression =
+  if (cmProp jarDirectoriesExpression =
         this->GeneratorTarget->GetProperty("ANDROID_JAR_DIRECTORIES")) {
     std::string jarDirectories = cmGeneratorExpression::Evaluate(
-      jarDirectoriesExpression, this->LocalGenerator, configName);
+      *jarDirectoriesExpression, this->LocalGenerator, configName);
     e2.Element("JarDirectories", jarDirectories);
   }
 
-  if (const char* jarDeps =
+  if (cmProp jarDeps =
         this->GeneratorTarget->GetProperty("ANDROID_JAR_DEPENDENCIES")) {
-    e2.Element("JarDependencies", jarDeps);
+    e2.Element("JarDependencies", *jarDeps);
   }
 
-  if (const char* assetsDirectories =
+  if (cmProp assetsDirectories =
         this->GeneratorTarget->GetProperty("ANDROID_ASSETS_DIRECTORIES")) {
-    e2.Element("AssetsDirectories", assetsDirectories);
+    e2.Element("AssetsDirectories", *assetsDirectories);
   }
 
   {
@@ -3581,10 +3573,10 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
     e2.Element("AndroidManifestLocation", manifest_xml);
   }
 
-  if (const char* antAdditionalOptions =
+  if (cmProp antAdditionalOptions =
         this->GeneratorTarget->GetProperty("ANDROID_ANT_ADDITIONAL_OPTIONS")) {
     e2.Element("AdditionalOptions",
-               std::string(antAdditionalOptions) + " %(AdditionalOptions)");
+               *antAdditionalOptions + " %(AdditionalOptions)");
   }
 }
 
@@ -3636,17 +3628,15 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
   std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
   flags += " ";
   flags += this->Makefile->GetRequiredDefinition(linkFlagVar);
-  const char* targetLinkFlags =
-    this->GeneratorTarget->GetProperty("LINK_FLAGS");
+  cmProp targetLinkFlags = this->GeneratorTarget->GetProperty("LINK_FLAGS");
   if (targetLinkFlags) {
     flags += " ";
-    flags += targetLinkFlags;
+    flags += *targetLinkFlags;
   }
   std::string flagsProp = cmStrCat("LINK_FLAGS_", CONFIG);
-  if (const char* flagsConfig =
-        this->GeneratorTarget->GetProperty(flagsProp)) {
+  if (cmProp flagsConfig = this->GeneratorTarget->GetProperty(flagsProp)) {
     flags += " ";
-    flags += flagsConfig;
+    flags += *flagsConfig;
   }
 
   std::vector<std::string> opts;
@@ -4125,9 +4115,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
     cmLocalGenerator* lg = dt->GetLocalGenerator();
     std::string name = dt->GetName();
     std::string path;
-    const char* p = dt->GetProperty("EXTERNAL_MSPROJECT");
+    cmProp p = dt->GetProperty("EXTERNAL_MSPROJECT");
     if (p) {
-      path = p;
+      path = *p;
     } else {
       path = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', dt->GetName(),
                       computeProjectFileExtension(dt));
@@ -4155,17 +4145,17 @@ void cmVisualStudio10TargetGenerator::WritePlatformExtensions(Elem& e1)
   // This only applies to Windows 10 apps
   if (this->GlobalGenerator->TargetsWindowsStore() &&
       cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) {
-    const char* desktopExtensionsVersion =
+    cmProp desktopExtensionsVersion =
       this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
     if (desktopExtensionsVersion) {
       this->WriteSinglePlatformExtension(e1, "WindowsDesktop",
-                                         desktopExtensionsVersion);
+                                         *desktopExtensionsVersion);
     }
-    const char* mobileExtensionsVersion =
+    cmProp mobileExtensionsVersion =
       this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
     if (mobileExtensionsVersion) {
       this->WriteSinglePlatformExtension(e1, "WindowsMobile",
-                                         mobileExtensionsVersion);
+                                         *mobileExtensionsVersion);
     }
   }
 }
@@ -4190,9 +4180,9 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
 {
   std::vector<std::string> sdkReferences;
   std::unique_ptr<Elem> spe1;
-  if (const char* vsSDKReferences =
+  if (cmProp vsSDKReferences =
         this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) {
-    cmExpandList(vsSDKReferences, sdkReferences);
+    cmExpandList(*vsSDKReferences, sdkReferences);
     spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
     for (std::string const& ri : sdkReferences) {
       Elem(*spe1, "SDKReference").Attribute("Include", ri);
@@ -4202,11 +4192,11 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
   // This only applies to Windows 10 apps
   if (this->GlobalGenerator->TargetsWindowsStore() &&
       cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) {
-    const char* desktopExtensionsVersion =
+    cmProp desktopExtensionsVersion =
       this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
-    const char* mobileExtensionsVersion =
+    cmProp mobileExtensionsVersion =
       this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
-    const char* iotExtensionsVersion =
+    cmProp iotExtensionsVersion =
       this->GeneratorTarget->GetProperty("VS_IOT_EXTENSIONS_VERSION");
 
     if (desktopExtensionsVersion || mobileExtensionsVersion ||
@@ -4216,15 +4206,15 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
       }
       if (desktopExtensionsVersion) {
         this->WriteSingleSDKReference(*spe1, "WindowsDesktop",
-                                      desktopExtensionsVersion);
+                                      *desktopExtensionsVersion);
       }
       if (mobileExtensionsVersion) {
         this->WriteSingleSDKReference(*spe1, "WindowsMobile",
-                                      mobileExtensionsVersion);
+                                      *mobileExtensionsVersion);
       }
       if (iotExtensionsVersion) {
         this->WriteSingleSDKReference(*spe1, "WindowsIoT",
-                                      iotExtensionsVersion);
+                                      *iotExtensionsVersion);
       }
     }
   }
@@ -4375,10 +4365,10 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
   if (!targetPlatformVersion.empty()) {
     e1.Element("WindowsTargetPlatformVersion", targetPlatformVersion);
   }
-  const char* targetPlatformMinVersion = this->GeneratorTarget->GetProperty(
+  cmProp targetPlatformMinVersion = this->GeneratorTarget->GetProperty(
     "VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION");
   if (targetPlatformMinVersion) {
-    e1.Element("WindowsTargetPlatformMinVersion", targetPlatformMinVersion);
+    e1.Element("WindowsTargetPlatformMinVersion", *targetPlatformMinVersion);
   } else if (isWindowsStore && rev == "10.0") {
     // If the min version is not set, then use the TargetPlatformVersion
     if (!targetPlatformVersion.empty()) {
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 4004b66..7775f62 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -157,12 +157,11 @@ void cmVisualStudioGeneratorOptions::FixCudaRuntime(cmGeneratorTarget* target)
     this->FlagMap.find("CudaRuntime");
   if (i == this->FlagMap.end()) {
     // User didn't provide am override so get the property value
-    const char* runtimeLibraryValue =
-      target->GetProperty("CUDA_RUNTIME_LIBRARY");
+    cmProp runtimeLibraryValue = target->GetProperty("CUDA_RUNTIME_LIBRARY");
     if (runtimeLibraryValue) {
       std::string cudaRuntime =
         cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
-          runtimeLibraryValue, this->LocalGenerator, this->Configuration,
+          *runtimeLibraryValue, this->LocalGenerator, this->Configuration,
           target));
       if (cudaRuntime == "STATIC") {
         this->AddFlag("CudaRuntime", "Static");
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index 1b437e9..aab367a 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -204,14 +204,14 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
 
   // Info tab begin
 
-  if (const char* exe =
+  if (cmProp exe =
         this->Target->GetTarget()->GetProperty("XCODE_SCHEME_EXECUTABLE")) {
 
     xout.StartElement("PathRunnable");
     xout.BreakAttributes();
 
     xout.Attribute("runnableDebuggingMode", "0");
-    xout.Attribute("FilePath", exe);
+    xout.Attribute("FilePath", *exe);
 
     xout.EndElement(); // PathRunnable
   }
@@ -220,9 +220,9 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
 
   // Arguments tab begin
 
-  if (const char* argList =
+  if (cmProp argList =
         this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) {
-    std::vector<std::string> arguments = cmExpandedList(argList);
+    std::vector<std::string> arguments = cmExpandedList(*argList);
     if (!arguments.empty()) {
       xout.StartElement("CommandLineArguments");
 
@@ -240,9 +240,9 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
     }
   }
 
-  if (const char* envList =
+  if (cmProp envList =
         this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) {
-    std::vector<std::string> envs = cmExpandedList(envList);
+    std::vector<std::string> envs = cmExpandedList(*envList);
     if (!envs.empty()) {
       xout.StartElement("EnvironmentVariables");
 
@@ -323,8 +323,9 @@ bool cmXCodeScheme::WriteLaunchActionBooleanAttribute(
   cmXMLWriter& xout, const std::string& attrName, const std::string& varName,
   bool defaultValue)
 {
-  auto property = Target->GetTarget()->GetProperty(varName);
-  bool isOn = (property == nullptr && defaultValue) || cmIsOn(property);
+  cmProp property = Target->GetTarget()->GetProperty(varName);
+  bool isOn =
+    (property == nullptr && defaultValue) || (property && cmIsOn(*property));
 
   if (isOn) {
     xout.Attribute(attrName.c_str(), "YES");
-- 
cgit v0.12