Browse Source

Merge topic 'vs-host-arch'

0fd742a6ff VS: Teach VS 2019 generator to select host tools matching host arch
17cef3806d VS: Add support for explicit 32-bit toolset selection via host=x86
bf774e521b VS: Remove stray semicolons from VS 2019 implementation
142e67eac6 VS: Use internal abstraction for VCTargetsPath host arch

Acked-by: Kitware Robot <[email protected]>
Merge-request: !2870
Brad King 6 years ago
parent
commit
fa7077e741

+ 4 - 3
Help/generator/VS_TOOLSET_HOST_ARCH.txt

@@ -1,6 +1,7 @@
 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 a ``host=x64`` option to the toolset specification.
+(independent of the architecture they target).
+|VS_TOOLSET_HOST_ARCH_DEFAULT|
+One may explicitly request use of either the 32-bit or 64-bit host tools
+by adding either ``host=x86`` or ``host=x64`` to the toolset specification.
 See the :variable:`CMAKE_GENERATOR_TOOLSET` variable for details.

+ 3 - 0
Help/generator/Visual Studio 12 2013.rst

@@ -42,4 +42,7 @@ The ``v120`` toolset that comes with Visual Studio 12 2013 is selected by
 default.  The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
 via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
 
+.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
+   By default this generator uses the 32-bit variant even on a 64-bit host.
+
 .. include:: VS_TOOLSET_HOST_ARCH.txt

+ 3 - 0
Help/generator/Visual Studio 14 2015.rst

@@ -39,4 +39,7 @@ The ``v140`` toolset that comes with Visual Studio 14 2015 is selected by
 default.  The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
 via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
 
+.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
+   By default this generator uses the 32-bit variant even on a 64-bit host.
+
 .. include:: VS_TOOLSET_HOST_ARCH.txt

+ 3 - 0
Help/generator/Visual Studio 15 2017.rst

@@ -56,4 +56,7 @@ The ``v141`` toolset that comes with Visual Studio 15 2017 is selected by
 default.  The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
 via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
 
+.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
+   By default this generator uses the 32-bit variant even on a 64-bit host.
+
 .. include:: VS_TOOLSET_HOST_ARCH.txt

+ 4 - 0
Help/generator/Visual Studio 16 2019.rst

@@ -46,4 +46,8 @@ The ``v142`` toolset that comes with Visual Studio 16 2019 is selected by
 default.  The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
 via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
 
+.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
+   By default this generator uses the 64-bit variant on x64 hosts and
+   the 32-bit variant otherwise.
+
 .. include:: VS_TOOLSET_HOST_ARCH.txt

+ 2 - 1
Help/release/dev/vs2019.rst

@@ -10,4 +10,5 @@ vs2019
   in the generator name.  Instead :variable:`CMAKE_GENERATOR_PLATFORM`
   must be used, e.g. through the ``-A`` command-line option.  Furthermore,
   the default target platform (architecture) is now based on the *host*
-  platform.
+  platform.  The VS host toolset selection is now based on the host
+  architecture as well.

+ 2 - 2
Help/variable/CMAKE_GENERATOR_TOOLSET.rst

@@ -44,8 +44,8 @@ Supported pairs are:
   and above with the CUDA toolkit VS integration installed.
   See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_CUDA` variable.
 
-``host=x64``
-  Request use of the native ``x64`` toolchain on ``x64`` hosts.
+``host=<arch>``
+  Specify the host tools architecture as ``x64`` or ``x86``.
   Supported by VS 2013 and above.
   See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE`
   variable.

+ 5 - 5
Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst

@@ -3,8 +3,8 @@ 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=x64``
-value in the :variable:`CMAKE_GENERATOR_TOOLSET` option.  CMake provides
-the selected toolchain architecture preference in this variable (either
-``x64`` or empty).
+The :ref:`Visual Studio Generators` for VS 2013 and above support using
+either the 32-bit or 64-bit host toolchains by specifying a ``host=x86``
+or ``host=x64`` value in the :variable:`CMAKE_GENERATOR_TOOLSET` option.
+CMake provides the selected toolchain architecture preference in this
+variable (``x86``, ``x64``, or empty).

+ 20 - 5
Source/cmGlobalVisualStudio10Generator.cxx

@@ -606,11 +606,27 @@ cmGlobalVisualStudio10Generator::GetPlatformToolsetVersionString() const
 
 const char*
 cmGlobalVisualStudio10Generator::GetPlatformToolsetHostArchitecture() const
+{
+  std::string const& hostArch =
+    this->GetPlatformToolsetHostArchitectureString();
+  if (hostArch.empty()) {
+    return nullptr;
+  }
+  return hostArch.c_str();
+}
+
+std::string const&
+cmGlobalVisualStudio10Generator::GetPlatformToolsetHostArchitectureString()
+  const
 {
   if (!this->GeneratorToolsetHostArchitecture.empty()) {
-    return this->GeneratorToolsetHostArchitecture.c_str();
+    return this->GeneratorToolsetHostArchitecture;
   }
-  return nullptr;
+  if (!this->DefaultPlatformToolsetHostArchitecture.empty()) {
+    return this->DefaultPlatformToolsetHostArchitecture;
+  }
+  static std::string const empty;
+  return empty;
 }
 
 const char* cmGlobalVisualStudio10Generator::GetPlatformToolsetCuda() const
@@ -786,10 +802,9 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
     }
     cmXMLElement(eprj, "Import")
       .Attribute("Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
-    if (!this->GeneratorToolsetHostArchitecture.empty()) {
+    if (const char* hostArch = this->GetPlatformToolsetHostArchitecture()) {
       cmXMLElement epg(eprj, "PropertyGroup");
-      cmXMLElement(epg, "PreferredToolArchitecture")
-        .Content(this->GeneratorToolsetHostArchitecture);
+      cmXMLElement(epg, "PreferredToolArchitecture").Content(hostArch);
     }
     {
       cmXMLElement epg(eprj, "PropertyGroup");

+ 2 - 0
Source/cmGlobalVisualStudio10Generator.h

@@ -58,6 +58,7 @@ public:
 
   /** The toolset host architecture name (e.g. x64 for 64-bit host tools).  */
   const char* GetPlatformToolsetHostArchitecture() const;
+  std::string const& GetPlatformToolsetHostArchitectureString() const;
 
   /** The cuda toolset version.  */
   const char* GetPlatformToolsetCuda() const;
@@ -152,6 +153,7 @@ protected:
   std::string GeneratorToolsetHostArchitecture;
   std::string GeneratorToolsetCuda;
   std::string DefaultPlatformToolset;
+  std::string DefaultPlatformToolsetHostArchitecture;
   std::string WindowsTargetPlatformVersion;
   std::string SystemName;
   std::string SystemVersion;

+ 2 - 2
Source/cmGlobalVisualStudio12Generator.cxx

@@ -126,8 +126,8 @@ bool cmGlobalVisualStudio12Generator::MatchesGeneratorName(
 bool cmGlobalVisualStudio12Generator::ProcessGeneratorToolsetField(
   std::string const& key, std::string const& value)
 {
-  if (key == "host" && value == "x64") {
-    this->GeneratorToolsetHostArchitecture = "x64";
+  if (key == "host" && (value == "x64" || value == "x86")) {
+    this->GeneratorToolsetHostArchitecture = value;
     return true;
   }
   return this->cmGlobalVisualStudio11Generator::ProcessGeneratorToolsetField(

+ 21 - 3
Source/cmGlobalVisualStudioVersionedGenerator.cxx

@@ -10,11 +10,14 @@
 #include "cmake.h"
 
 #if defined(_M_ARM64)
-#  define HOST_PLATFORM_NAME "ARM64";
+#  define HOST_PLATFORM_NAME "ARM64"
+#  define HOST_TOOLS_ARCH ""
 #elif defined(_M_ARM)
-#  define HOST_PLATFORM_NAME "ARM";
+#  define HOST_PLATFORM_NAME "ARM"
+#  define HOST_TOOLS_ARCH ""
 #elif defined(_M_IA64)
-#  define HOST_PLATFORM_NAME "Itanium";
+#  define HOST_PLATFORM_NAME "Itanium"
+#  define HOST_TOOLS_ARCH ""
 #else
 #  include "cmsys/SystemInformation.hxx"
 #endif
@@ -33,6 +36,20 @@ static std::string VSHostPlatformName()
 #endif
 }
 
+static std::string VSHostArchitecture()
+{
+#ifdef HOST_TOOLS_ARCH
+  return HOST_TOOLS_ARCH;
+#else
+  cmsys::SystemInformation info;
+  if (info.Is64Bits()) {
+    return "x64";
+  } else {
+    return "x86";
+  }
+#endif
+}
+
 static unsigned int VSVersionToMajor(
   cmGlobalVisualStudioGenerator::VSVersion v)
 {
@@ -262,6 +279,7 @@ cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
   this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
   if (this->Version >= cmGlobalVisualStudioGenerator::VS16) {
     this->DefaultPlatformName = VSHostPlatformName();
+    this->DefaultPlatformToolsetHostArchitecture = VSHostArchitecture();
   }
 }
 

+ 1 - 1
Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice-stderr.txt

@@ -5,6 +5,6 @@ CMake Error at CMakeLists.txt:[0-9]+ \(project\):
 
   given toolset specification
 
-    Test Toolset,host=x64,host=x64
+    Test Toolset,host=x64,host=x86
 
   that contains duplicate field key 'host'\.$

+ 5 - 3
Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake

@@ -16,14 +16,16 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
     set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64")
     run_cmake(TestToolsetHostArchBoth)
     set(RunCMake_GENERATOR_TOOLSET ",host=x64")
-    run_cmake(TestToolsetHostArchOnly)
+    run_cmake(TestToolsetHostArchOnly_x64)
     set(RunCMake_GENERATOR_TOOLSET "host=x64")
-    run_cmake(TestToolsetHostArchOnly)
+    run_cmake(TestToolsetHostArchOnly_x64)
+    set(RunCMake_GENERATOR_TOOLSET "host=x86")
+    run_cmake(TestToolsetHostArchOnly_x86)
     set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
     run_cmake(TestToolsetHostArchNone)
     set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x65")
     run_cmake(BadToolsetHostArch)
-    set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64,host=x64")
+    set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64,host=x86")
     run_cmake(BadToolsetHostArchTwice)
     if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[56]")
       set(RunCMake_GENERATOR_TOOLSET "Test Toolset,version=Test Toolset Version")

+ 1 - 1
Tests/RunCMake/GeneratorToolset/TestToolsetHostArchNone-stdout.txt

@@ -1,2 +1,2 @@
 -- CMAKE_VS_PLATFORM_TOOLSET='Test Toolset'
--- CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE=''
+-- CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE='.*'

+ 13 - 0
Tests/RunCMake/GeneratorToolset/TestToolsetHostArchNone.cmake

@@ -1,2 +1,15 @@
 message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
 message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE='${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}'")
+
+if(CMAKE_GENERATOR MATCHES "Visual Studio 1[6]")
+  cmake_host_system_information(RESULT is_64_bit QUERY IS_64BIT)
+  if(is_64_bit)
+    if(NOT "${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}" STREQUAL "x64")
+      message(FATAL_ERROR "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE is not 'x64' as expected.")
+    endif()
+  endif()
+else()
+  if(NOT "${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}" STREQUAL "")
+    message(FATAL_ERROR "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE is not empty as expected.")
+  endif()
+endif()

+ 0 - 0
Tests/RunCMake/GeneratorToolset/TestToolsetHostArchOnly-stdout.txt → Tests/RunCMake/GeneratorToolset/TestToolsetHostArchOnly_x64-stdout.txt


+ 0 - 0
Tests/RunCMake/GeneratorToolset/TestToolsetHostArchOnly.cmake → Tests/RunCMake/GeneratorToolset/TestToolsetHostArchOnly_x64.cmake


+ 2 - 0
Tests/RunCMake/GeneratorToolset/TestToolsetHostArchOnly_x86-stdout.txt

@@ -0,0 +1,2 @@
+-- CMAKE_VS_PLATFORM_TOOLSET='v[0-9]+'
+-- CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE='x86'

+ 2 - 0
Tests/RunCMake/GeneratorToolset/TestToolsetHostArchOnly_x86.cmake

@@ -0,0 +1,2 @@
+message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
+message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE='${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}'")