Commit d079e71c authored by Brad King's avatar Brad King

VS: Provide an option to use x64 host tools

Visual Studio provides toolchains that are themselves built for 32-bit
or 64-bit host architectures.  By default it uses the 32-bit tools, but
it can be told to prefer the 64-bit tools on 64-bit hosts.  Extend the
`CMAKE_GENERATOR_TOOLSET` specification to provide a way to request
use of the 64-bit host tools.

Closes: #15622
parent 779939a0
Pipeline #31008 passed with stage
For each toolset that comes with this version of Visual Studio, there are
variants that are themselves compiled for 32-bit (x86) and 64-bit (x64) hosts
(independent of the architecture they target). By default Visual Studio
chooses the 32-bit variant even on a 64-bit host. One may request use of the
64-bit host tools by adding ``host=x64`` to the toolset specification:
``host=x64``
Select the 64-bit variant of the default toolset.
``<toolset>,host=x64``
Select the 64-bit variant of the ``<toolset>`` toolset.
...@@ -24,3 +24,5 @@ Toolset Selection ...@@ -24,3 +24,5 @@ Toolset Selection
The ``v120`` toolset that comes with Visual Studio 12 2013 is selected by The ``v120`` toolset that comes with Visual Studio 12 2013 is selected by
default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
via the :manual:`cmake(1)` ``-T`` option, to specify another toolset. via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
.. include:: VS_TOOLSET_HOST_ARCH.txt
...@@ -21,3 +21,5 @@ Toolset Selection ...@@ -21,3 +21,5 @@ Toolset Selection
The ``v140`` toolset that comes with Visual Studio 14 2015 is selected by The ``v140`` toolset that comes with Visual Studio 14 2015 is selected by
default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
via the :manual:`cmake(1)` ``-T`` option, to specify another toolset. via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
.. include:: VS_TOOLSET_HOST_ARCH.txt
...@@ -21,3 +21,5 @@ Toolset Selection ...@@ -21,3 +21,5 @@ Toolset Selection
The ``v141`` toolset that comes with Visual Studio 15 is selected by The ``v141`` toolset that comes with Visual Studio 15 is selected by
default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
via the :manual:`cmake(1)` ``-T`` option, to specify another toolset. via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
.. include:: VS_TOOLSET_HOST_ARCH.txt
...@@ -82,6 +82,7 @@ Variables that Provide Information ...@@ -82,6 +82,7 @@ Variables that Provide Information
/variable/CMAKE_VS_NsightTegra_VERSION /variable/CMAKE_VS_NsightTegra_VERSION
/variable/CMAKE_VS_PLATFORM_NAME /variable/CMAKE_VS_PLATFORM_NAME
/variable/CMAKE_VS_PLATFORM_TOOLSET /variable/CMAKE_VS_PLATFORM_TOOLSET
/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE
/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION /variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
/variable/CMAKE_XCODE_PLATFORM_TOOLSET /variable/CMAKE_XCODE_PLATFORM_TOOLSET
/variable/PROJECT_BINARY_DIR /variable/PROJECT_BINARY_DIR
......
vs-host-x64-tools
-----------------
* The :ref:`Visual Studio Generators` for VS 2013 and above learned to
support a ``host=x64`` option in the :variable:`CMAKE_GENERATOR_TOOLSET`
value (e.g. via the :manual:`cmake(1)` ``-T`` option) to request use
of a VS 64-bit toolchain on 64-bit hosts.
CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE
-------------------------------------------
Visual Studio preferred tool architecture.
The :ref:`Visual Studio Generators` for VS 2013 and above support optional
selection of a 64-bit toolchain on 64-bit hosts by specifying a ``host=64``
value in the :variable:`CMAKE_GENERATOR_TOOLSET` option. CMake provides
the selected toolchain architecture preference in this variable (either
``x64`` or empty).
...@@ -182,6 +182,11 @@ Id flags: ${testflags} ...@@ -182,6 +182,11 @@ Id flags: ${testflags}
else() else()
set(id_toolset "") set(id_toolset "")
endif() endif()
if(CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE)
set(id_PreferredToolArchitecture "<PreferredToolArchitecture>${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}</PreferredToolArchitecture>")
else()
set(id_PreferredToolArchitecture "")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone") if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
set(id_system "<ApplicationType>Windows Phone</ApplicationType>") set(id_system "<ApplicationType>Windows Phone</ApplicationType>")
elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
@id_WindowsSDKDesktopARMSupport@ @id_WindowsSDKDesktopARMSupport@
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup>
@id_PreferredToolArchitecture@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
@id_toolset@ @id_toolset@
......
...@@ -145,10 +145,36 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset( ...@@ -145,10 +145,36 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
return false; return false;
} }
this->GeneratorToolset = ts; if (!this->ParseGeneratorToolset(ts, mf)) {
return false;
}
if (const char* toolset = this->GetPlatformToolset()) { if (const char* toolset = this->GetPlatformToolset()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET", toolset); mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET", toolset);
} }
if (const char* hostArch = this->GetPlatformToolsetHostArchitecture()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE", hostArch);
}
return true;
}
bool cmGlobalVisualStudio10Generator::ParseGeneratorToolset(
std::string const& ts, cmMakefile* mf)
{
if (ts.find_first_of(",=") != ts.npos) {
std::ostringstream e;
/* clang-format off */
e <<
"Generator\n"
" " << this->GetName() << "\n"
"does not recognize the toolset\n"
" " << ts << "\n"
"that was specified.";
/* clang-format on */
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
return false;
}
this->GeneratorToolset = ts;
return true; return true;
} }
...@@ -322,6 +348,15 @@ const char* cmGlobalVisualStudio10Generator::GetPlatformToolset() const ...@@ -322,6 +348,15 @@ const char* cmGlobalVisualStudio10Generator::GetPlatformToolset() const
return 0; return 0;
} }
const char*
cmGlobalVisualStudio10Generator::GetPlatformToolsetHostArchitecture() const
{
if (!this->GeneratorToolsetHostArchitecture.empty()) {
return this->GeneratorToolsetHostArchitecture.c_str();
}
return CM_NULLPTR;
}
void cmGlobalVisualStudio10Generator::FindMakeProgram(cmMakefile* mf) void cmGlobalVisualStudio10Generator::FindMakeProgram(cmMakefile* mf)
{ {
this->cmGlobalVisualStudio8Generator::FindMakeProgram(mf); this->cmGlobalVisualStudio8Generator::FindMakeProgram(mf);
......
...@@ -22,6 +22,7 @@ public: ...@@ -22,6 +22,7 @@ public:
virtual bool SetSystemName(std::string const& s, cmMakefile* mf); virtual bool SetSystemName(std::string const& s, cmMakefile* mf);
virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf); virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf); virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
virtual bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
virtual void GenerateBuildCommand( virtual void GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram, std::vector<std::string>& makeCommand, const std::string& makeProgram,
...@@ -48,6 +49,9 @@ public: ...@@ -48,6 +49,9 @@ public:
/** The toolset name for the target platform. */ /** The toolset name for the target platform. */
const char* GetPlatformToolset() const; const char* GetPlatformToolset() const;
/** The toolset host architecture name (e.g. x64 for 64-bit host tools). */
const char* GetPlatformToolsetHostArchitecture() const;
/** Return the CMAKE_SYSTEM_NAME. */ /** Return the CMAKE_SYSTEM_NAME. */
std::string const& GetSystemName() const { return this->SystemName; } std::string const& GetSystemName() const { return this->SystemName; }
...@@ -101,6 +105,7 @@ protected: ...@@ -101,6 +105,7 @@ protected:
std::string const& GetMSBuildCommand(); std::string const& GetMSBuildCommand();
std::string GeneratorToolset; std::string GeneratorToolset;
std::string GeneratorToolsetHostArchitecture;
std::string DefaultPlatformToolset; std::string DefaultPlatformToolset;
std::string WindowsTargetPlatformVersion; std::string WindowsTargetPlatformVersion;
std::string SystemName; std::string SystemName;
......
...@@ -96,6 +96,21 @@ bool cmGlobalVisualStudio12Generator::MatchesGeneratorName( ...@@ -96,6 +96,21 @@ bool cmGlobalVisualStudio12Generator::MatchesGeneratorName(
return false; return false;
} }
bool cmGlobalVisualStudio12Generator::ParseGeneratorToolset(
std::string const& ts, cmMakefile* mf)
{
std::string::size_type ts_end = ts.size();
if (cmHasLiteralSuffix(ts, ",host=x64")) {
this->GeneratorToolsetHostArchitecture = "x64";
ts_end -= 9;
} else if (ts == "host=x64") {
this->GeneratorToolsetHostArchitecture = "x64";
ts_end = 0;
}
return this->cmGlobalVisualStudio11Generator::ParseGeneratorToolset(
ts.substr(0, ts_end), mf);
}
bool cmGlobalVisualStudio12Generator::InitializeWindowsPhone(cmMakefile* mf) bool cmGlobalVisualStudio12Generator::InitializeWindowsPhone(cmMakefile* mf)
{ {
if (!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) { if (!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) {
......
...@@ -22,6 +22,9 @@ public: ...@@ -22,6 +22,9 @@ public:
// version number // version number
virtual const char* GetToolsVersion() { return "12.0"; } virtual const char* GetToolsVersion() { return "12.0"; }
protected: protected:
bool ParseGeneratorToolset(std::string const& ts,
cmMakefile* mf) CM_OVERRIDE;
virtual bool InitializeWindowsPhone(cmMakefile* mf); virtual bool InitializeWindowsPhone(cmMakefile* mf);
virtual bool InitializeWindowsStore(cmMakefile* mf); virtual bool InitializeWindowsStore(cmMakefile* mf);
virtual bool SelectWindowsPhoneToolset(std::string& toolset) const; virtual bool SelectWindowsPhoneToolset(std::string& toolset) const;
......
...@@ -220,6 +220,19 @@ bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts, ...@@ -220,6 +220,19 @@ bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
cmMakefile* mf) cmMakefile* mf)
{ {
if (this->XcodeVersion >= 30) { if (this->XcodeVersion >= 30) {
if (ts.find_first_of(",=") != ts.npos) {
std::ostringstream e;
/* clang-format off */
e <<
"Generator\n"
" " << this->GetName() << "\n"
"does not recognize the toolset\n"
" " << ts << "\n"
"that was specified.";
/* clang-format on */
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
return false;
}
this->GeneratorToolset = ts; this->GeneratorToolset = ts;
if (!this->GeneratorToolset.empty()) { if (!this->GeneratorToolset.empty()) {
mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET", mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET",
......
...@@ -322,6 +322,15 @@ void cmVisualStudio10TargetGenerator::Generate() ...@@ -322,6 +322,15 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WriteString("</PropertyGroup>\n", 1); this->WriteString("</PropertyGroup>\n", 1);
} }
if (const char* hostArch =
this->GlobalGenerator->GetPlatformToolsetHostArchitecture()) {
this->WriteString("<PropertyGroup>\n", 1);
this->WriteString("<PreferredToolArchitecture>", 2);
(*this->BuildFileStream) << cmVS10EscapeXML(hostArch)
<< "</PreferredToolArchitecture>\n";
this->WriteString("</PropertyGroup>\n", 1);
}
this->WriteProjectConfigurations(); this->WriteProjectConfigurations();
this->WriteString("<PropertyGroup Label=\"Globals\">\n", 1); this->WriteString("<PropertyGroup Label=\"Globals\">\n", 1);
this->WriteString("<ProjectGUID>", 2); this->WriteString("<ProjectGUID>", 2);
......
CMake Error at CMakeLists.txt:[0-9]+ \(project\):
Generator
.*
does not recognize the toolset
Test Toolset,host=x6[45]
that was specified\.$
message(FATAL_ERROR "This should not be reached!")
...@@ -6,6 +6,21 @@ run_cmake(NoToolset) ...@@ -6,6 +6,21 @@ run_cmake(NoToolset)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]|Xcode" AND NOT XCODE_BELOW_3) if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]|Xcode" AND NOT XCODE_BELOW_3)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset") set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
run_cmake(TestToolset) run_cmake(TestToolset)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[245]")
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64")
run_cmake(TestToolsetHostArchBoth)
set(RunCMake_GENERATOR_TOOLSET ",host=x64")
run_cmake(TestToolsetHostArchOnly)
set(RunCMake_GENERATOR_TOOLSET "host=x64")
run_cmake(TestToolsetHostArchOnly)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
run_cmake(TestToolsetHostArchNone)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x65")
run_cmake(BadToolsetHostArch)
else()
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64")
run_cmake(BadToolsetHostArch)
endif()
else() else()
set(RunCMake_GENERATOR_TOOLSET "Bad Toolset") set(RunCMake_GENERATOR_TOOLSET "Bad Toolset")
run_cmake(BadToolset) run_cmake(BadToolset)
......
-- CMAKE_VS_PLATFORM_TOOLSET='Test Toolset'
-- CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE='x64'
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE='${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}'")
-- CMAKE_VS_PLATFORM_TOOLSET='Test Toolset'
-- CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE=''
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE='${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}'")
-- CMAKE_VS_PLATFORM_TOOLSET='v[0-9]+'
-- CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE='x64'
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE='${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}'")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment