mirror of
https://github.com/reactos/CMake.git
synced 2025-02-20 11:52:04 +00:00
VS: Find the MSBuild value for VCTargetsPath
Run MSBuild on a simple `.vcxproj` file to extract the location of the toolset definitions. This will later be useful for looking at available BuildCustomizations.
This commit is contained in:
parent
0a312e2271
commit
83bf980c96
@ -15,10 +15,15 @@
|
||||
#include "cmVS10MASMFlagTable.h"
|
||||
#include "cmVS10NASMFlagTable.h"
|
||||
#include "cmVS10RCFlagTable.h"
|
||||
#include "cmVersion.h"
|
||||
#include "cmVisualStudioSlnData.h"
|
||||
#include "cmVisualStudioSlnParser.h"
|
||||
#include "cmXMLWriter.h"
|
||||
#include "cmake.h"
|
||||
|
||||
#include <cmsys/FStream.hxx>
|
||||
#include <cmsys/RegularExpression.hxx>
|
||||
|
||||
static const char vs10generatorName[] = "Visual Studio 10 2010";
|
||||
|
||||
// Map generator name without year to name with year.
|
||||
@ -170,6 +175,11 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
|
||||
if (!this->ParseGeneratorToolset(ts, mf)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this->FindVCTargetsPath(mf)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const char* toolset = this->GetPlatformToolset()) {
|
||||
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET", toolset);
|
||||
}
|
||||
@ -507,6 +517,208 @@ std::string cmGlobalVisualStudio10Generator::FindDevEnvCommand()
|
||||
return this->cmGlobalVisualStudio71Generator::FindDevEnvCommand();
|
||||
}
|
||||
|
||||
bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
|
||||
{
|
||||
// Skip this in special cases within our own test suite.
|
||||
if (this->GetPlatformName() == "Test Platform" ||
|
||||
this->GetPlatformToolsetString() == "Test Toolset") {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string wd;
|
||||
if (!this->ConfiguredFilesPath.empty()) {
|
||||
// In a try-compile we are given the outer CMakeFiles directory.
|
||||
wd = this->ConfiguredFilesPath;
|
||||
} else {
|
||||
wd = this->GetCMakeInstance()->GetHomeOutputDirectory();
|
||||
wd += cmake::GetCMakeFilesDirectory();
|
||||
}
|
||||
wd += "/";
|
||||
wd += cmVersion::GetCMakeVersion();
|
||||
|
||||
// We record the result persistently in a file.
|
||||
std::string const txt = wd + "/VCTargetsPath.txt";
|
||||
|
||||
// If we have a recorded result, use it.
|
||||
{
|
||||
cmsys::ifstream fin(txt.c_str());
|
||||
if (fin && cmSystemTools::GetLineFromStream(fin, this->VCTargetsPath) &&
|
||||
cmSystemTools::FileIsDirectory(this->VCTargetsPath)) {
|
||||
cmSystemTools::ConvertToUnixSlashes(this->VCTargetsPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare the work directory.
|
||||
if (!cmSystemTools::MakeDirectory(wd)) {
|
||||
std::string e = "Failed to make directory:\n " + wd;
|
||||
mf->IssueMessage(cmake::FATAL_ERROR, e.c_str());
|
||||
cmSystemTools::SetFatalErrorOccured();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate a project file for MSBuild to tell us the VCTargetsPath value.
|
||||
std::string const vcxproj = "VCTargetsPath.vcxproj";
|
||||
{
|
||||
std::string const vcxprojAbs = wd + "/" + vcxproj;
|
||||
cmsys::ofstream fout(vcxprojAbs.c_str());
|
||||
cmXMLWriter xw(fout);
|
||||
|
||||
/* clang-format off */
|
||||
xw.StartDocument();
|
||||
xw.StartElement("Project");
|
||||
xw.Attribute("DefaultTargets", "Build");
|
||||
xw.Attribute("ToolsVersion", "4.0");
|
||||
xw.Attribute("xmlns",
|
||||
"http://schemas.microsoft.com/developer/msbuild/2003");
|
||||
if (this->IsNsightTegra()) {
|
||||
xw.StartElement("PropertyGroup");
|
||||
xw.Attribute("Label", "NsightTegraProject");
|
||||
xw.StartElement("NsightTegraProjectRevisionNumber");
|
||||
xw.Content("6");
|
||||
xw.EndElement(); // NsightTegraProjectRevisionNumber
|
||||
xw.EndElement(); // PropertyGroup
|
||||
}
|
||||
xw.StartElement("ItemGroup");
|
||||
xw.Attribute("Label", "ProjectConfigurations");
|
||||
xw.StartElement("ProjectConfiguration");
|
||||
xw.Attribute("Include", "Debug|" + this->GetPlatformName());
|
||||
xw.StartElement("Configuration");
|
||||
xw.Content("Debug");
|
||||
xw.EndElement(); // Configuration
|
||||
xw.StartElement("Platform");
|
||||
xw.Content(this->GetPlatformName());
|
||||
xw.EndElement(); // Platform
|
||||
xw.EndElement(); // ProjectConfiguration
|
||||
xw.EndElement(); // ItemGroup
|
||||
xw.StartElement("PropertyGroup");
|
||||
xw.Attribute("Label", "Globals");
|
||||
xw.StartElement("ProjectGUID");
|
||||
xw.Content("{F3FC6D86-508D-3FB1-96D2-995F08B142EC}");
|
||||
xw.EndElement(); // ProjectGUID
|
||||
xw.StartElement("Keyword");
|
||||
xw.Content("Win32Proj");
|
||||
xw.EndElement(); // Keyword
|
||||
xw.StartElement("Platform");
|
||||
xw.Content(this->GetPlatformName());
|
||||
xw.EndElement(); // Platform
|
||||
if (this->GetSystemName() == "WindowsPhone") {
|
||||
xw.StartElement("ApplicationType");
|
||||
xw.Content("Windows Phone");
|
||||
xw.EndElement(); // ApplicationType
|
||||
xw.StartElement("ApplicationTypeRevision");
|
||||
xw.Content(this->GetSystemVersion());
|
||||
xw.EndElement(); // ApplicationTypeRevision
|
||||
} else if (this->GetSystemName() == "WindowsStore") {
|
||||
xw.StartElement("ApplicationType");
|
||||
xw.Content("Windows Store");
|
||||
xw.EndElement(); // ApplicationType
|
||||
xw.StartElement("ApplicationTypeRevision");
|
||||
xw.Content(this->GetSystemVersion());
|
||||
xw.EndElement(); // ApplicationTypeRevision
|
||||
}
|
||||
if (!this->WindowsTargetPlatformVersion.empty()) {
|
||||
xw.StartElement("WindowsTargetPlatformVersion");
|
||||
xw.Content(this->WindowsTargetPlatformVersion);
|
||||
xw.EndElement(); // WindowsTargetPlatformVersion
|
||||
}
|
||||
if (this->GetPlatformName() == "ARM") {
|
||||
xw.StartElement("WindowsSDKDesktopARMSupport");
|
||||
xw.Content("true");
|
||||
xw.EndElement(); // WindowsSDKDesktopARMSupport
|
||||
}
|
||||
xw.EndElement(); // PropertyGroup
|
||||
xw.StartElement("Import");
|
||||
xw.Attribute("Project",
|
||||
"$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
|
||||
xw.EndElement(); // Import
|
||||
if (!this->GeneratorToolsetHostArchitecture.empty()) {
|
||||
xw.StartElement("PropertyGroup");
|
||||
xw.StartElement("PreferredToolArchitecture");
|
||||
xw.Content(this->GeneratorToolsetHostArchitecture);
|
||||
xw.EndElement(); // PreferredToolArchitecture
|
||||
xw.EndElement(); // PropertyGroup
|
||||
}
|
||||
xw.StartElement("PropertyGroup");
|
||||
xw.Attribute("Label", "Configuration");
|
||||
xw.StartElement("ConfigurationType");
|
||||
if (this->IsNsightTegra()) {
|
||||
// Tegra-Android platform does not understand "Utility".
|
||||
xw.Content("StaticLibrary");
|
||||
} else {
|
||||
xw.Content("Utility");
|
||||
}
|
||||
xw.EndElement(); // ConfigurationType
|
||||
xw.StartElement("CharacterSet");
|
||||
xw.Content("MultiByte");
|
||||
xw.EndElement(); // CharacterSet
|
||||
if (this->IsNsightTegra()) {
|
||||
xw.StartElement("NdkToolchainVersion");
|
||||
xw.Content(this->GetPlatformToolsetString());
|
||||
xw.EndElement(); // NdkToolchainVersion
|
||||
} else {
|
||||
xw.StartElement("PlatformToolset");
|
||||
xw.Content(this->GetPlatformToolsetString());
|
||||
xw.EndElement(); // PlatformToolset
|
||||
}
|
||||
xw.EndElement(); // PropertyGroup
|
||||
xw.StartElement("Import");
|
||||
xw.Attribute("Project", "$(VCTargetsPath)\\Microsoft.Cpp.props");
|
||||
xw.EndElement(); // Import
|
||||
xw.StartElement("ItemDefinitionGroup");
|
||||
xw.StartElement("PostBuildEvent");
|
||||
xw.StartElement("Command");
|
||||
xw.Content("echo VCTargetsPath=$(VCTargetsPath)");
|
||||
xw.EndElement(); // Command
|
||||
xw.EndElement(); // PostBuildEvent
|
||||
xw.EndElement(); // ItemDefinitionGroup
|
||||
xw.StartElement("Import");
|
||||
xw.Attribute("Project",
|
||||
"$(VCTargetsPath)\\Microsoft.Cpp.targets");
|
||||
xw.EndElement(); // Import
|
||||
xw.EndElement(); // Project
|
||||
xw.EndDocument();
|
||||
/* clang-format on */
|
||||
}
|
||||
|
||||
std::vector<std::string> cmd;
|
||||
cmd.push_back(this->GetMSBuildCommand());
|
||||
cmd.push_back(vcxproj);
|
||||
cmd.push_back(std::string("/p:VisualStudioVersion=") +
|
||||
this->GetIDEVersion());
|
||||
std::string out;
|
||||
int ret = 0;
|
||||
cmsys::RegularExpression regex("\n *VCTargetsPath=([^%\r\n]+)[\r\n]");
|
||||
if (!cmSystemTools::RunSingleCommand(cmd, &out, &out, &ret, wd.c_str(),
|
||||
cmSystemTools::OUTPUT_NONE) ||
|
||||
ret != 0 || !regex.find(out)) {
|
||||
cmSystemTools::ReplaceString(out, "\n", "\n ");
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e <<
|
||||
"Failed to run MSBuild command:\n"
|
||||
" " << cmd[0] << "\n"
|
||||
"to get the value of VCTargetsPath:\n"
|
||||
" " << out << "\n"
|
||||
;
|
||||
/* clang-format on */
|
||||
if (ret != 0) {
|
||||
e << "Exit code: " << ret << "\n";
|
||||
}
|
||||
mf->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
|
||||
cmSystemTools::SetFatalErrorOccured();
|
||||
return false;
|
||||
}
|
||||
this->VCTargetsPath = regex.match(1);
|
||||
cmSystemTools::ConvertToUnixSlashes(this->VCTargetsPath);
|
||||
|
||||
{
|
||||
cmsys::ofstream fout(txt.c_str());
|
||||
fout << this->VCTargetsPath << "\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
|
||||
std::vector<std::string>& makeCommand, const std::string& makeProgram,
|
||||
const std::string& projectName, const std::string& projectDir,
|
||||
|
@ -160,6 +160,9 @@ private:
|
||||
|
||||
bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
|
||||
|
||||
std::string VCTargetsPath;
|
||||
bool FindVCTargetsPath(cmMakefile* mf);
|
||||
|
||||
// We do not use the reload macros for VS >= 10.
|
||||
virtual std::string GetUserMacrosDirectory() { return ""; }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user