mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-15 20:46:37 +08:00
VS: Handle build target correct for .NET SDK style projects with Any CPU
* Extend Visual Studio solution parser for reading build target * Map solution build target to project build target (especially for Any CPU) * Use C++ <optional> template instead of pointer return value for cmSlnData::GetProjectByGUID
This commit is contained in:
@@ -1134,7 +1134,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
|
|||||||
slnFile += ".sln";
|
slnFile += ".sln";
|
||||||
cmVisualStudioSlnParser parser;
|
cmVisualStudioSlnParser parser;
|
||||||
if (parser.ParseFile(slnFile, slnData,
|
if (parser.ParseFile(slnFile, slnData,
|
||||||
cmVisualStudioSlnParser::DataGroupProjects)) {
|
cmVisualStudioSlnParser::DataGroupAll)) {
|
||||||
std::vector<cmSlnProjectEntry> slnProjects = slnData.GetProjects();
|
std::vector<cmSlnProjectEntry> slnProjects = slnData.GetProjects();
|
||||||
for (cmSlnProjectEntry const& project : slnProjects) {
|
for (cmSlnProjectEntry const& project : slnProjects) {
|
||||||
if (useDevEnv) {
|
if (useDevEnv) {
|
||||||
@@ -1170,15 +1170,17 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
|
|||||||
GeneratedMakeCommand makeCommand;
|
GeneratedMakeCommand makeCommand;
|
||||||
makeCommand.RequiresOutputForward = requiresOutputForward;
|
makeCommand.RequiresOutputForward = requiresOutputForward;
|
||||||
makeCommand.Add(makeProgramSelected);
|
makeCommand.Add(makeProgramSelected);
|
||||||
|
cm::optional<cmSlnProjectEntry> proj = cm::nullopt;
|
||||||
|
|
||||||
if (tname == "clean") {
|
if (tname == "clean") {
|
||||||
makeCommand.Add(std::string(projectName) + ".sln");
|
makeCommand.Add(cmStrCat(projectName, ".sln"));
|
||||||
makeCommand.Add("/t:Clean");
|
makeCommand.Add("/t:Clean");
|
||||||
} else {
|
} else {
|
||||||
std::string targetProject = cmStrCat(tname, ".vcxproj");
|
std::string targetProject = cmStrCat(tname, ".vcxproj");
|
||||||
|
proj = slnData.GetProjectByName(tname);
|
||||||
if (targetProject.find('/') == std::string::npos) {
|
if (targetProject.find('/') == std::string::npos) {
|
||||||
// it might be in a subdir
|
// it might be in a subdir
|
||||||
if (cmSlnProjectEntry const* proj = slnData.GetProjectByName(tname)) {
|
if (proj) {
|
||||||
targetProject = proj->GetRelativePath();
|
targetProject = proj->GetRelativePath();
|
||||||
cmSystemTools::ConvertToUnixSlashes(targetProject);
|
cmSystemTools::ConvertToUnixSlashes(targetProject);
|
||||||
}
|
}
|
||||||
@@ -1243,22 +1245,33 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string configArg = "/p:Configuration=";
|
std::string plainConfig = config;
|
||||||
if (!config.empty()) {
|
if (config.empty()) {
|
||||||
configArg += config;
|
plainConfig = "Debug";
|
||||||
} else {
|
|
||||||
configArg += "Debug";
|
|
||||||
}
|
}
|
||||||
makeCommand.Add(configArg);
|
|
||||||
makeCommand.Add(std::string("/p:Platform=") + this->GetPlatformName());
|
std::string platform = GetPlatformName();
|
||||||
makeCommand.Add(std::string("/p:VisualStudioVersion=") +
|
if (proj) {
|
||||||
this->GetIDEVersion());
|
std::string extension =
|
||||||
|
cmSystemTools::GetFilenameLastExtension(proj->GetRelativePath());
|
||||||
|
extension = cmSystemTools::LowerCase(extension);
|
||||||
|
if (extension.compare(".csproj") == 0) {
|
||||||
|
// Use correct platform name
|
||||||
|
platform =
|
||||||
|
slnData.GetConfigurationTarget(tname, plainConfig, platform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeCommand.Add(cmStrCat("/p:Configuration=", plainConfig));
|
||||||
|
makeCommand.Add(cmStrCat("/p:Platform=", platform));
|
||||||
|
makeCommand.Add(
|
||||||
|
cmStrCat("/p:VisualStudioVersion=", this->GetIDEVersion()));
|
||||||
|
|
||||||
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
|
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
|
||||||
if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
|
if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
|
||||||
makeCommand.Add("/m");
|
makeCommand.Add("/m");
|
||||||
} else {
|
} else {
|
||||||
makeCommand.Add(std::string("/m:") + std::to_string(jobs));
|
makeCommand.Add(cmStrCat("/m:", std::to_string(jobs)));
|
||||||
}
|
}
|
||||||
// Having msbuild.exe and cl.exe using multiple jobs is discouraged
|
// Having msbuild.exe and cl.exe using multiple jobs is discouraged
|
||||||
makeCommand.Add("/p:CL_MPCount=1");
|
makeCommand.Add("/p:CL_MPCount=1");
|
||||||
@@ -1266,7 +1279,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
|
|||||||
|
|
||||||
// Respect the verbosity: 'n' normal will show build commands
|
// Respect the verbosity: 'n' normal will show build commands
|
||||||
// 'm' minimal only the build step's title
|
// 'm' minimal only the build step's title
|
||||||
makeCommand.Add(std::string("/v:") + ((verbose) ? "n" : "m"));
|
makeCommand.Add(cmStrCat("/v:", ((verbose) ? "n" : "m")));
|
||||||
makeCommand.Add(makeOptions.begin(), makeOptions.end());
|
makeCommand.Add(makeOptions.begin(), makeOptions.end());
|
||||||
makeCommands.emplace_back(std::move(makeCommand));
|
makeCommands.emplace_back(std::move(makeCommand));
|
||||||
}
|
}
|
||||||
|
@@ -5,24 +5,39 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
const cmSlnProjectEntry* cmSlnData::GetProjectByGUID(
|
#include "cmSystemTools.h"
|
||||||
|
|
||||||
|
void cmSlnProjectEntry::AddProjectConfiguration(
|
||||||
|
const std::string& solutionConfiguration,
|
||||||
|
const std::string& projectConfiguration)
|
||||||
|
{
|
||||||
|
projectConfigurationMap[solutionConfiguration] = projectConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string cmSlnProjectEntry::GetProjectConfiguration(
|
||||||
|
const std::string& solutionConfiguration)
|
||||||
|
{
|
||||||
|
return projectConfigurationMap[solutionConfiguration];
|
||||||
|
}
|
||||||
|
|
||||||
|
const cm::optional<cmSlnProjectEntry> cmSlnData::GetProjectByGUID(
|
||||||
const std::string& projectGUID) const
|
const std::string& projectGUID) const
|
||||||
{
|
{
|
||||||
ProjectStorage::const_iterator it(ProjectsByGUID.find(projectGUID));
|
ProjectStorage::const_iterator it(ProjectsByGUID.find(projectGUID));
|
||||||
if (it != ProjectsByGUID.end())
|
if (it != ProjectsByGUID.end())
|
||||||
return &it->second;
|
return it->second;
|
||||||
else
|
else
|
||||||
return NULL;
|
return cm::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmSlnProjectEntry* cmSlnData::GetProjectByName(
|
const cm::optional<cmSlnProjectEntry> cmSlnData::GetProjectByName(
|
||||||
const std::string& projectName) const
|
const std::string& projectName) const
|
||||||
{
|
{
|
||||||
ProjectStringIndex::const_iterator it(ProjectNameIndex.find(projectName));
|
ProjectStringIndex::const_iterator it(ProjectNameIndex.find(projectName));
|
||||||
if (it != ProjectNameIndex.end())
|
if (it != ProjectNameIndex.end())
|
||||||
return &it->second->second;
|
return it->second->second;
|
||||||
else
|
else
|
||||||
return NULL;
|
return cm::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<cmSlnProjectEntry> cmSlnData::GetProjects() const
|
std::vector<cmSlnProjectEntry> cmSlnData::GetProjects() const
|
||||||
@@ -50,3 +65,24 @@ cmSlnProjectEntry* cmSlnData::AddProject(
|
|||||||
ProjectNameIndex[projectName] = it;
|
ProjectNameIndex[projectName] = it;
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string cmSlnData::GetConfigurationTarget(
|
||||||
|
const std::string& projectName, const std::string& solutionConfiguration,
|
||||||
|
const std::string& platformName)
|
||||||
|
{
|
||||||
|
std::string solutionTarget = solutionConfiguration + "|" + platformName;
|
||||||
|
cm::optional<cmSlnProjectEntry> project = GetProjectByName(projectName);
|
||||||
|
if (!project)
|
||||||
|
return platformName;
|
||||||
|
|
||||||
|
std::string projectTarget = project->GetProjectConfiguration(solutionTarget);
|
||||||
|
if (projectTarget.empty())
|
||||||
|
return platformName;
|
||||||
|
|
||||||
|
std::vector<std::string> targetElements =
|
||||||
|
cmSystemTools::SplitString(projectTarget, '|');
|
||||||
|
if (targetElements.size() != 2)
|
||||||
|
return platformName;
|
||||||
|
|
||||||
|
return targetElements[1];
|
||||||
|
}
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cm/optional>
|
||||||
|
|
||||||
class cmSlnProjectEntry
|
class cmSlnProjectEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -24,8 +26,15 @@ public:
|
|||||||
std::string GetName() const { return Name; }
|
std::string GetName() const { return Name; }
|
||||||
std::string GetRelativePath() const { return RelativePath; }
|
std::string GetRelativePath() const { return RelativePath; }
|
||||||
|
|
||||||
|
void AddProjectConfiguration(const std::string& solutionConfiguration,
|
||||||
|
const std::string& projectConfiguration);
|
||||||
|
|
||||||
|
std::string GetProjectConfiguration(
|
||||||
|
const std::string& solutionConfiguration);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string Guid, Name, RelativePath;
|
std::string Guid, Name, RelativePath;
|
||||||
|
std::map<std::string, std::string> projectConfigurationMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
class cmSlnData
|
class cmSlnData
|
||||||
@@ -47,10 +56,10 @@ public:
|
|||||||
minimumVisualStudioVersion = version;
|
minimumVisualStudioVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmSlnProjectEntry* GetProjectByGUID(
|
const cm::optional<cmSlnProjectEntry> GetProjectByGUID(
|
||||||
const std::string& projectGUID) const;
|
const std::string& projectGUID) const;
|
||||||
|
|
||||||
const cmSlnProjectEntry* GetProjectByName(
|
const cm::optional<cmSlnProjectEntry> GetProjectByName(
|
||||||
const std::string& projectName) const;
|
const std::string& projectName) const;
|
||||||
|
|
||||||
std::vector<cmSlnProjectEntry> GetProjects() const;
|
std::vector<cmSlnProjectEntry> GetProjects() const;
|
||||||
@@ -59,10 +68,20 @@ public:
|
|||||||
const std::string& projectName,
|
const std::string& projectName,
|
||||||
const std::string& projectRelativePath);
|
const std::string& projectRelativePath);
|
||||||
|
|
||||||
|
void AddConfiguration(const std::string& configuration)
|
||||||
|
{
|
||||||
|
solutionConfigurations.push_back(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetConfigurationTarget(const std::string& projectName,
|
||||||
|
const std::string& solutionConfiguration,
|
||||||
|
const std::string& platformName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string visualStudioVersion, minimumVisualStudioVersion;
|
std::string visualStudioVersion, minimumVisualStudioVersion;
|
||||||
using ProjectStorage = std::map<std::string, cmSlnProjectEntry>;
|
using ProjectStorage = std::map<std::string, cmSlnProjectEntry>;
|
||||||
ProjectStorage ProjectsByGUID;
|
ProjectStorage ProjectsByGUID;
|
||||||
using ProjectStringIndex = std::map<std::string, ProjectStorage::iterator>;
|
using ProjectStringIndex = std::map<std::string, ProjectStorage::iterator>;
|
||||||
ProjectStringIndex ProjectNameIndex;
|
ProjectStringIndex ProjectNameIndex;
|
||||||
|
std::vector<std::string> solutionConfigurations;
|
||||||
};
|
};
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include "cmsys/FStream.hxx"
|
#include "cmsys/FStream.hxx"
|
||||||
|
|
||||||
#include "cmStringAlgorithms.h"
|
#include "cmStringAlgorithms.h"
|
||||||
|
#include "cmSystemTools.h"
|
||||||
#include "cmVisualStudioSlnData.h"
|
#include "cmVisualStudioSlnData.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -294,10 +295,9 @@ bool cmVisualStudioSlnParser::State::Process(
|
|||||||
case FileStateSolutionConfigurations:
|
case FileStateSolutionConfigurations:
|
||||||
if (line.GetTag().compare("EndGlobalSection") == 0)
|
if (line.GetTag().compare("EndGlobalSection") == 0)
|
||||||
this->Stack.pop();
|
this->Stack.pop();
|
||||||
else if (line.IsKeyValuePair())
|
else if (line.IsKeyValuePair()) {
|
||||||
// implement configuration storing here, once needed
|
output.AddConfiguration(line.GetValue(0));
|
||||||
;
|
} else {
|
||||||
else {
|
|
||||||
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
|
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -305,10 +305,30 @@ bool cmVisualStudioSlnParser::State::Process(
|
|||||||
case FileStateProjectConfigurations:
|
case FileStateProjectConfigurations:
|
||||||
if (line.GetTag().compare("EndGlobalSection") == 0)
|
if (line.GetTag().compare("EndGlobalSection") == 0)
|
||||||
this->Stack.pop();
|
this->Stack.pop();
|
||||||
else if (line.IsKeyValuePair())
|
else if (line.IsKeyValuePair()) {
|
||||||
// implement configuration storing here, once needed
|
std::vector<std::string> tagElements =
|
||||||
;
|
cmSystemTools::SplitString(line.GetTag(), '.');
|
||||||
else {
|
if (tagElements.size() != 3 && tagElements.size() != 4) {
|
||||||
|
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string guid = tagElements[0];
|
||||||
|
std::string solutionConfiguration = tagElements[1];
|
||||||
|
std::string activeBuild = tagElements[2];
|
||||||
|
cm::optional<cmSlnProjectEntry> projectEntry =
|
||||||
|
output.GetProjectByGUID(guid);
|
||||||
|
|
||||||
|
if (!projectEntry) {
|
||||||
|
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeBuild.compare("ActiveCfg") == 0) {
|
||||||
|
projectEntry->AddProjectConfiguration(solutionConfiguration,
|
||||||
|
line.GetValue(0));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
|
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -459,8 +479,7 @@ bool cmVisualStudioSlnParser::GetParseHadBOM() const
|
|||||||
bool cmVisualStudioSlnParser::IsDataGroupSetSupported(
|
bool cmVisualStudioSlnParser::IsDataGroupSetSupported(
|
||||||
DataGroupSet dataGroups) const
|
DataGroupSet dataGroups) const
|
||||||
{
|
{
|
||||||
return (dataGroups & DataGroupProjects) == dataGroups;
|
return (dataGroups & DataGroupProjects) != 0;
|
||||||
// only supporting DataGroupProjects for now
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmVisualStudioSlnParser::ParseImpl(std::istream& input, cmSlnData& output,
|
bool cmVisualStudioSlnParser::ParseImpl(std::istream& input, cmSlnData& output,
|
||||||
|
Reference in New Issue
Block a user