summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalVisualStudioVersionedGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmGlobalVisualStudioVersionedGenerator.cxx')
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx124
1 files changed, 95 insertions, 29 deletions
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index bc38335..7e36881 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -25,50 +25,100 @@
#include "cmVSSetupHelper.h"
#include "cmake.h"
-#if defined(_M_ARM64)
-# define HOST_PLATFORM_NAME "ARM64"
-# define HOST_TOOLS_ARCH ""
-#elif defined(_M_ARM)
-# define HOST_PLATFORM_NAME "ARM"
-# define HOST_TOOLS_ARCH ""
-#elif defined(_M_IA64)
-# define HOST_PLATFORM_NAME "Itanium"
-# define HOST_TOOLS_ARCH ""
-#elif defined(_WIN64)
-# define HOST_PLATFORM_NAME "x64"
-# define HOST_TOOLS_ARCH "x64"
-#else
+#ifndef IMAGE_FILE_MACHINE_ARM64
+# define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian
+#endif
+
static bool VSIsWow64()
{
BOOL isWow64 = false;
return IsWow64Process(GetCurrentProcess(), &isWow64) && isWow64;
}
+
+static bool VSIsArm64Host()
+{
+ typedef BOOL(WINAPI * CM_ISWOW64PROCESS2)(
+ HANDLE hProcess, USHORT * pProcessMachine, USHORT * pNativeMachine);
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+# define CM_VS_GCC_DIAGNOSTIC_PUSHED
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
+ static const CM_ISWOW64PROCESS2 s_IsWow64Process2Impl =
+ (CM_ISWOW64PROCESS2)GetProcAddress(
+ GetModuleHandleW(L"api-ms-win-core-wow64-l1-1-1.dll"),
+ "IsWow64Process2");
+#ifdef CM_VS_GCC_DIAGNOSTIC_PUSHED
+# pragma GCC diagnostic pop
+# undef CM_VS_GCC_DIAGNOSTIC_PUSHED
+#endif
+
+ USHORT processMachine, nativeMachine;
+
+ return s_IsWow64Process2Impl != nullptr &&
+ s_IsWow64Process2Impl(GetCurrentProcess(), &processMachine,
+ &nativeMachine) &&
+ nativeMachine == IMAGE_FILE_MACHINE_ARM64;
+}
+
+static bool VSHasDotNETFrameworkArm64()
+{
+ std::string dotNetArm64;
+ return cmSystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\.NETFramework;InstallRootArm64",
+ dotNetArm64, cmSystemTools::KeyWOW64_64);
+}
+
+static bool VSIsWindows11OrGreater()
+{
+ cmSystemTools::WindowsVersion const windowsVersion =
+ cmSystemTools::GetWindowsVersion();
+ return (windowsVersion.dwMajorVersion > 10 ||
+ (windowsVersion.dwMajorVersion == 10 &&
+ windowsVersion.dwMinorVersion > 0) ||
+ (windowsVersion.dwMajorVersion == 10 &&
+ windowsVersion.dwMinorVersion == 0 &&
+ windowsVersion.dwBuildNumber >= 22000));
+}
static std::string VSHostPlatformName()
{
-#ifdef HOST_PLATFORM_NAME
- return HOST_PLATFORM_NAME;
-#else
- if (VSIsWow64()) {
+ if (VSIsArm64Host()) {
+ return "ARM64";
+ } else if (VSIsWow64()) {
return "x64";
} else {
+#if defined(_M_ARM)
+ return "ARM";
+#elif defined(_M_IA64)
+ return "Itanium";
+#elif defined(_WIN64)
+ return "x64";
+#else
return "Win32";
- }
#endif
+ }
}
-static std::string VSHostArchitecture()
+static std::string VSHostArchitecture(
+ cmGlobalVisualStudioGenerator::VSVersion v)
{
-#ifdef HOST_TOOLS_ARCH
- return HOST_TOOLS_ARCH;
-#else
- if (VSIsWow64()) {
+ if (VSIsArm64Host()) {
+ return v >= cmGlobalVisualStudioGenerator::VSVersion::VS17 ? "ARM64" : "";
+ } else if (VSIsWow64()) {
return "x64";
} else {
+#if defined(_M_ARM)
+ return "";
+#elif defined(_M_IA64)
+ return "";
+#elif defined(_WIN64)
+ return "x64";
+#else
return "x86";
- }
#endif
+ }
}
static unsigned int VSVersionToMajor(
@@ -433,7 +483,8 @@ cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16) {
this->DefaultPlatformName = VSHostPlatformName();
- this->DefaultPlatformToolsetHostArchitecture = VSHostArchitecture();
+ this->DefaultPlatformToolsetHostArchitecture =
+ VSHostArchitecture(this->Version);
}
if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17) {
// FIXME: Search for an existing framework? Under '%ProgramFiles(x86)%',
@@ -881,7 +932,7 @@ cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommandEarly(cmMakefile* mf)
{
std::string instance = mf->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE");
if (!this->SetGeneratorInstance(instance, mf)) {
- cmSystemTools::SetFatalErrorOccured();
+ cmSystemTools::SetFatalErrorOccurred();
return {};
}
return this->cmGlobalVisualStudio14Generator::FindMSBuildCommandEarly(mf);
@@ -895,9 +946,24 @@ std::string cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommand()
std::string vs;
if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) {
if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17) {
- msbuild = vs + "/MSBuild/Current/Bin/amd64/MSBuild.exe";
- if (cmSystemTools::FileExists(msbuild)) {
- return msbuild;
+ if (VSIsArm64Host()) {
+ if (VSHasDotNETFrameworkArm64()) {
+ msbuild = vs + "/MSBuild/Current/Bin/arm64/MSBuild.exe";
+ if (cmSystemTools::FileExists(msbuild)) {
+ return msbuild;
+ }
+ }
+ if (VSIsWindows11OrGreater()) {
+ msbuild = vs + "/MSBuild/Current/Bin/amd64/MSBuild.exe";
+ if (cmSystemTools::FileExists(msbuild)) {
+ return msbuild;
+ }
+ }
+ } else {
+ msbuild = vs + "/MSBuild/Current/Bin/amd64/MSBuild.exe";
+ if (cmSystemTools::FileExists(msbuild)) {
+ return msbuild;
+ }
}
}
msbuild = vs + "/MSBuild/Current/Bin/MSBuild.exe";