cmGlobalVisualStudioGenerator: Adopt some solution generation methods

All versions of VS we still support use the Solution model.
This commit is contained in:
Brad King
2025-09-15 15:07:06 -04:00
parent d52eb1d083
commit 76266f9df6
5 changed files with 119 additions and 112 deletions

View File

@@ -533,20 +533,6 @@ void cmGlobalVisualStudio7Generator::WriteFoldersContent(
}
}
std::string cmGlobalVisualStudio7Generator::ConvertToSolutionPath(
std::string const& path) const
{
// Convert to backslashes. Do not use ConvertToOutputPath because
// we will add quoting ourselves, and we know these projects always
// use windows slashes.
std::string d = path;
std::string::size_type pos = 0;
while ((pos = d.find('/', pos)) != std::string::npos) {
d[pos++] = '\\';
}
return d;
}
void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
std::ostream& fout, cmLocalGenerator* root) const
{
@@ -619,29 +605,6 @@ void cmGlobalVisualStudio7Generator::WriteSLNFooter(std::ostream& fout) const
fout << "EndGlobal\n";
}
std::string cmGlobalVisualStudio7Generator::GetGUID(
std::string const& name) const
{
std::string const& guidStoreName = cmStrCat(name, "_GUID_CMAKE");
if (cmValue storedGUID =
this->CMakeInstance->GetCacheDefinition(guidStoreName)) {
return *storedGUID;
}
// Compute a GUID that is deterministic but unique to the build tree.
std::string input =
cmStrCat(this->CMakeInstance->GetState()->GetBinaryDirectory(), '|', name);
cmUuid uuidGenerator;
std::vector<unsigned char> uuidNamespace;
uuidGenerator.StringToBinary("ee30c4be-5192-4fb0-b335-722a2dffe760",
uuidNamespace);
std::string guid = uuidGenerator.FromMd5(uuidNamespace, input);
return cmSystemTools::UpperCase(guid);
}
void cmGlobalVisualStudio7Generator::AppendDirectoryForConfig(
std::string const& prefix, std::string const& config,
std::string const& suffix, std::string& dir)
@@ -651,63 +614,6 @@ void cmGlobalVisualStudio7Generator::AppendDirectoryForConfig(
}
}
std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
std::vector<std::string> const& configs,
OrderedTargetDependSet const& projectTargets,
cmGeneratorTarget const* target) const
{
std::set<std::string> activeConfigs;
// if it is a utility target then only make it part of the
// default build if another target depends on it
int type = target->GetType();
if (type == cmStateEnums::GLOBAL_TARGET) {
std::vector<std::string> targetNames;
targetNames.push_back("INSTALL");
targetNames.push_back("PACKAGE");
for (std::string const& t : targetNames) {
// check if target <t> is part of default build
if (target->GetName() == t) {
std::string const propertyName =
cmStrCat("CMAKE_VS_INCLUDE_", t, "_TO_DEFAULT_BUILD");
// inspect CMAKE_VS_INCLUDE_<t>_TO_DEFAULT_BUILD properties
for (std::string const& i : configs) {
cmValue propertyValue =
target->Target->GetMakefile()->GetDefinition(propertyName);
if (propertyValue &&
cmIsOn(cmGeneratorExpression::Evaluate(
*propertyValue, target->GetLocalGenerator(), i))) {
activeConfigs.insert(i);
}
}
}
}
return activeConfigs;
}
if (type == cmStateEnums::UTILITY &&
!this->IsDependedOn(projectTargets, target)) {
return activeConfigs;
}
// inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
for (std::string const& i : configs) {
if (target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i).IsOff()) {
activeConfigs.insert(i);
}
}
return activeConfigs;
}
bool cmGlobalVisualStudio7Generator::IsDependedOn(
OrderedTargetDependSet const& projectTargets,
cmGeneratorTarget const* gtIn) const
{
return std::any_of(projectTargets.begin(), projectTargets.end(),
[this, gtIn](cmTargetDepend const& l) {
TargetDependSet const& tgtdeps =
this->GetTargetDirectDepends(l);
return tgtdeps.count(gtIn);
});
}
std::string cmGlobalVisualStudio7Generator::Encoding()
{
return "UTF-8";

View File

@@ -82,9 +82,6 @@ public:
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
//! Lookup a stored GUID or compute one deterministically.
std::string GetGUID(std::string const& name) const;
/** Append the subdirectory for the given configuration. */
void AppendDirectoryForConfig(std::string const& prefix,
std::string const& config,
@@ -176,16 +173,6 @@ protected:
cmValue typeGuid,
std::set<BT<std::pair<std::string, bool>>> const& dependencies) const = 0;
std::string ConvertToSolutionPath(std::string const& path) const;
std::set<std::string> IsPartOfDefaultBuild(
std::vector<std::string> const& configs,
OrderedTargetDependSet const& projectTargets,
cmGeneratorTarget const* target) const;
bool IsDependedOn(OrderedTargetDependSet const& projectTargets,
cmGeneratorTarget const* target) const;
std::map<std::string, std::string> GUIDMap;
virtual void WriteFolders(std::ostream& fout,
VSFolders const& vsFolders) const;
virtual void WriteFoldersContent(std::ostream& fout,

View File

@@ -64,12 +64,10 @@ protected:
bool AddCheckTarget();
/** Return true if the configuration needs to be deployed */
virtual bool NeedsDeploy(cmGeneratorTarget const& target,
char const* config) const;
bool NeedsDeploy(cmGeneratorTarget const& target,
char const* config) const override;
/** Returns true if the target system support debugging deployment. */
virtual bool TargetSystemSupportsDeployment() const;
bool TargetSystemSupportsDeployment() const override;
static cmIDEFlagTable const* GetExtraFlagTableVS8();
void WriteSolutionConfigurations(

View File

@@ -3,6 +3,7 @@
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudioGenerator.h"
#include <algorithm>
#include <cassert>
#include <future>
#include <iostream>
@@ -34,6 +35,7 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmUuid.h"
#include "cmake.h"
cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator(cmake* cm)
@@ -810,3 +812,97 @@ bool cmGlobalVisualStudioGenerator::Open(std::string const& bindir,
return std::async(std::launch::async, OpenSolution, sln).get();
}
std::string cmGlobalVisualStudioGenerator::ConvertToSolutionPath(
std::string const& path) const
{
// Convert to backslashes. Do not use ConvertToOutputPath because
// we will add quoting ourselves, and we know these projects always
// use windows slashes.
std::string d = path;
std::string::size_type pos = 0;
while ((pos = d.find('/', pos)) != std::string::npos) {
d[pos++] = '\\';
}
return d;
}
bool cmGlobalVisualStudioGenerator::IsDependedOn(
OrderedTargetDependSet const& projectTargets,
cmGeneratorTarget const* gtIn) const
{
return std::any_of(projectTargets.begin(), projectTargets.end(),
[this, gtIn](cmTargetDepend const& l) {
TargetDependSet const& tgtdeps =
this->GetTargetDirectDepends(l);
return tgtdeps.count(gtIn);
});
}
std::set<std::string> cmGlobalVisualStudioGenerator::IsPartOfDefaultBuild(
std::vector<std::string> const& configs,
OrderedTargetDependSet const& projectTargets,
cmGeneratorTarget const* target) const
{
std::set<std::string> activeConfigs;
// if it is a utility target then only make it part of the
// default build if another target depends on it
int type = target->GetType();
if (type == cmStateEnums::GLOBAL_TARGET) {
std::vector<std::string> targetNames;
targetNames.push_back("INSTALL");
targetNames.push_back("PACKAGE");
for (std::string const& t : targetNames) {
// check if target <t> is part of default build
if (target->GetName() == t) {
std::string const propertyName =
cmStrCat("CMAKE_VS_INCLUDE_", t, "_TO_DEFAULT_BUILD");
// inspect CMAKE_VS_INCLUDE_<t>_TO_DEFAULT_BUILD properties
for (std::string const& i : configs) {
cmValue propertyValue =
target->Target->GetMakefile()->GetDefinition(propertyName);
if (propertyValue &&
cmIsOn(cmGeneratorExpression::Evaluate(
*propertyValue, target->GetLocalGenerator(), i))) {
activeConfigs.insert(i);
}
}
}
}
return activeConfigs;
}
if (type == cmStateEnums::UTILITY &&
!this->IsDependedOn(projectTargets, target)) {
return activeConfigs;
}
// inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
for (std::string const& i : configs) {
if (target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i).IsOff()) {
activeConfigs.insert(i);
}
}
return activeConfigs;
}
std::string cmGlobalVisualStudioGenerator::GetGUID(
std::string const& name) const
{
std::string const& guidStoreName = cmStrCat(name, "_GUID_CMAKE");
if (cmValue storedGUID =
this->CMakeInstance->GetCacheDefinition(guidStoreName)) {
return *storedGUID;
}
// Compute a GUID that is deterministic but unique to the build tree.
std::string input =
cmStrCat(this->CMakeInstance->GetState()->GetBinaryDirectory(), '|', name);
cmUuid uuidGenerator;
std::vector<unsigned char> uuidNamespace;
uuidGenerator.StringToBinary("ee30c4be-5192-4fb0-b335-722a2dffe760",
uuidNamespace);
std::string guid = uuidGenerator.FromMd5(uuidNamespace, input);
return cmSystemTools::UpperCase(guid);
}

View File

@@ -159,6 +159,9 @@ public:
bool IsVisualStudio() const override { return true; }
//! Lookup a stored GUID or compute one deterministically.
std::string GetGUID(std::string const& name) const;
protected:
cmGlobalVisualStudioGenerator(cmake* cm);
@@ -181,6 +184,23 @@ protected:
std::string GeneratorPlatform;
std::string DefaultPlatformName;
std::string ConvertToSolutionPath(std::string const& path) const;
/** Return true if the configuration needs to be deployed */
virtual bool NeedsDeploy(cmGeneratorTarget const& target,
char const* config) const = 0;
/** Returns true if the target system support debugging deployment. */
virtual bool TargetSystemSupportsDeployment() const = 0;
std::set<std::string> IsPartOfDefaultBuild(
std::vector<std::string> const& configs,
OrderedTargetDependSet const& projectTargets,
cmGeneratorTarget const* target) const;
bool IsDependedOn(OrderedTargetDependSet const& projectTargets,
cmGeneratorTarget const* target) const;
std::map<std::string, std::string> GUIDMap;
private:
virtual std::string GetVSMakeProgram() = 0;
void PrintCompilerAdvice(std::ostream&, std::string const&,