Browse Source

Merge pull request #55778 from aaronfranke/use-arch-btw

[skip ci]
Rémi Verschelde 3 years ago
parent
commit
c7eb423eeb

+ 4 - 4
.github/workflows/android_builds.yml

@@ -38,19 +38,19 @@ jobs:
       - name: Setup python and scons
       - name: Setup python and scons
         uses: ./.github/actions/godot-deps
         uses: ./.github/actions/godot-deps
 
 
-      - name: Compilation (armv7)
+      - name: Compilation (arm32)
         uses: ./.github/actions/godot-build
         uses: ./.github/actions/godot-build
         with:
         with:
-          sconsflags: ${{ env.SCONSFLAGS }} android_arch=armv7
+          sconsflags: ${{ env.SCONSFLAGS }} arch=arm32
           platform: android
           platform: android
           target: release
           target: release
           tools: false
           tools: false
           tests: false
           tests: false
 
 
-      - name: Compilation (arm64v8)
+      - name: Compilation (arm64)
         uses: ./.github/actions/godot-build
         uses: ./.github/actions/godot-build
         with:
         with:
-          sconsflags: ${{ env.SCONSFLAGS }} android_arch=arm64v8
+          sconsflags: ${{ env.SCONSFLAGS }} arch=arm64
           platform: android
           platform: android
           target: release
           target: release
           tools: false
           tools: false

+ 1 - 1
.github/workflows/ios_builds.yml

@@ -26,7 +26,7 @@ jobs:
       - name: Setup python and scons
       - name: Setup python and scons
         uses: ./.github/actions/godot-deps
         uses: ./.github/actions/godot-deps
 
 
-      - name: Compilation (arm64v8)
+      - name: Compilation (arm64)
         uses: ./.github/actions/godot-build
         uses: ./.github/actions/godot-build
         with:
         with:
           sconsflags: ${{ env.SCONSFLAGS }}
           sconsflags: ${{ env.SCONSFLAGS }}

+ 3 - 3
.github/workflows/linux_builds.yml

@@ -28,7 +28,7 @@ jobs:
             tests: false # Disabled due freeze caused by mix Mono build and CI
             tests: false # Disabled due freeze caused by mix Mono build and CI
             sconsflags: module_mono_enabled=yes
             sconsflags: module_mono_enabled=yes
             doc-test: true
             doc-test: true
-            bin: "./bin/godot.linuxbsd.opt.tools.64.mono"
+            bin: "./bin/godot.linuxbsd.opt.tools.x86_64.mono"
             build-mono: true
             build-mono: true
             proj-conv: true
             proj-conv: true
             artifact: true
             artifact: true
@@ -43,7 +43,7 @@ jobs:
             # Can be turned off for PRs that intentionally break compat with godot-cpp,
             # Can be turned off for PRs that intentionally break compat with godot-cpp,
             # until both the upstream PR and the matching godot-cpp changes are merged.
             # until both the upstream PR and the matching godot-cpp changes are merged.
             godot-cpp-test: true
             godot-cpp-test: true
-            bin: "./bin/godot.linuxbsd.double.tools.64.san"
+            bin: "./bin/godot.linuxbsd.double.tools.x86_64.san"
             build-mono: false
             build-mono: false
             # Skip 2GiB artifact speeding up action.
             # Skip 2GiB artifact speeding up action.
             artifact: false
             artifact: false
@@ -54,7 +54,7 @@ jobs:
             tools: true
             tools: true
             tests: true
             tests: true
             sconsflags: use_asan=yes use_ubsan=yes use_llvm=yes linker=lld
             sconsflags: use_asan=yes use_ubsan=yes use_llvm=yes linker=lld
-            bin: "./bin/godot.linuxbsd.tools.64.llvm.san"
+            bin: "./bin/godot.linuxbsd.tools.x86_64.llvm.san"
             build-mono: false
             build-mono: false
             # Skip 2GiB artifact speeding up action.
             # Skip 2GiB artifact speeding up action.
             artifact: false
             artifact: false

+ 1 - 1
.github/workflows/macos_builds.yml

@@ -24,7 +24,7 @@ jobs:
             target: release_debug
             target: release_debug
             tools: true
             tools: true
             tests: true
             tests: true
-            bin: "./bin/godot.macos.opt.tools.64"
+            bin: "./bin/godot.macos.opt.tools.x86_64"
 
 
           - name: Template (target=release, tools=no)
           - name: Template (target=release, tools=no)
             cache-name: macos-template
             cache-name: macos-template

+ 1 - 1
.github/workflows/windows_builds.yml

@@ -29,7 +29,7 @@ jobs:
             tests: true
             tests: true
             # Skip debug symbols, they're way too big with MSVC.
             # Skip debug symbols, they're way too big with MSVC.
             sconsflags: debug_symbols=no
             sconsflags: debug_symbols=no
-            bin: "./bin/godot.windows.opt.tools.64.exe"
+            bin: "./bin/godot.windows.opt.tools.x86_64.exe"
 
 
           - name: Template (target=release, tools=no)
           - name: Template (target=release, tools=no)
             cache-name: windows-template
             cache-name: windows-template

+ 1 - 1
CONTRIBUTING.md

@@ -37,7 +37,7 @@ Godot runs on a large variety of platforms and operating systems and devices.
 
 
 For bugs that are likely OS-specific and/or graphics-related, please also specify:
 For bugs that are likely OS-specific and/or graphics-related, please also specify:
 
 
-- Device (CPU model including architecture, e.g. x86, x86_64, ARM, etc.)
+- Device (CPU model including architecture, e.g. x86_64, arm64, etc.)
 - GPU model (and the driver version in use if you know it)
 - GPU model (and the driver version in use if you know it)
 
 
 **Bug reports not including the required information may be closed at the
 **Bug reports not including the required information may be closed at the

+ 10 - 11
SConstruct

@@ -55,6 +55,7 @@ _helper_module("modules.modules_builders", "modules/modules_builders.py")
 import methods
 import methods
 import glsl_builders
 import glsl_builders
 import gles3_builders
 import gles3_builders
+from platform_methods import architectures, architecture_aliases
 
 
 if methods.get_cmdline_bool("tools", True):
 if methods.get_cmdline_bool("tools", True):
     _helper_module("editor.editor_builders", "editor/editor_builders.py")
     _helper_module("editor.editor_builders", "editor/editor_builders.py")
@@ -161,12 +162,11 @@ if profile:
 opts = Variables(customs, ARGUMENTS)
 opts = Variables(customs, ARGUMENTS)
 
 
 # Target build options
 # Target build options
-opts.Add("p", "Platform (alias for 'platform')", "")
 opts.Add("platform", "Target platform (%s)" % ("|".join(platform_list),), "")
 opts.Add("platform", "Target platform (%s)" % ("|".join(platform_list),), "")
+opts.Add("p", "Platform (alias for 'platform')", "")
 opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True))
 opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True))
 opts.Add(EnumVariable("target", "Compilation target", "debug", ("debug", "release_debug", "release")))
 opts.Add(EnumVariable("target", "Compilation target", "debug", ("debug", "release_debug", "release")))
-opts.Add("arch", "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", "")
-opts.Add(EnumVariable("bits", "Target platform bits", "default", ("default", "32", "64")))
+opts.Add(EnumVariable("arch", "CPU architecture", "auto", ["auto"] + architectures, architecture_aliases))
 opts.Add(EnumVariable("float", "Floating-point precision", "default", ("default", "32", "64")))
 opts.Add(EnumVariable("float", "Floating-point precision", "default", ("default", "32", "64")))
 opts.Add(EnumVariable("optimize", "Optimization type", "speed", ("speed", "size", "none")))
 opts.Add(EnumVariable("optimize", "Optimization type", "speed", ("speed", "size", "none")))
 opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False))
 opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False))
@@ -502,12 +502,17 @@ if selected_platform in platform_list:
     # Platform specific flags
     # Platform specific flags
     flag_list = platform_flags[selected_platform]
     flag_list = platform_flags[selected_platform]
     for f in flag_list:
     for f in flag_list:
-        if not (f[0] in ARGUMENTS):  # allow command line to override platform flags
+        if not (f[0] in ARGUMENTS) or ARGUMENTS[f[0]] == "auto":  # Allow command line to override platform flags
             env[f[0]] = f[1]
             env[f[0]] = f[1]
 
 
     # Must happen after the flags' definition, so that they can be used by platform detect
     # Must happen after the flags' definition, so that they can be used by platform detect
     detect.configure(env)
     detect.configure(env)
 
 
+    print(
+        'Building for platform "%s", architecture "%s", %s, target "%s".'
+        % (selected_platform, env["arch"], "editor" if env["tools"] else "template", env["target"])
+    )
+
     # Set our C and C++ standard requirements.
     # Set our C and C++ standard requirements.
     # C++17 is required as we need guaranteed copy elision as per GH-36436.
     # C++17 is required as we need guaranteed copy elision as per GH-36436.
     # Prepending to make it possible to override.
     # Prepending to make it possible to override.
@@ -693,13 +698,7 @@ if selected_platform in platform_list:
             )
             )
             suffix += ".debug"
             suffix += ".debug"
 
 
-    if env["arch"] != "":
-        suffix += "." + env["arch"]
-    elif env["bits"] == "32":
-        suffix += ".32"
-    elif env["bits"] == "64":
-        suffix += ".64"
-
+    suffix += "." + env["arch"]
     suffix += env.extra_suffix
     suffix += env.extra_suffix
 
 
     sys.path.remove(tmppath)
     sys.path.remove(tmppath)

+ 1 - 1
drivers/png/SCsub

@@ -37,7 +37,7 @@ if env["builtin_libpng"]:
     import os
     import os
 
 
     # Enable ARM NEON instructions on 32-bit Android to compile more optimized code.
     # Enable ARM NEON instructions on 32-bit Android to compile more optimized code.
-    use_neon = "android_arch" in env and env["android_arch"] == "armv7" and os.name != "nt"
+    use_neon = env["platform"] == "android" and env["arch"] == "arm32" and os.name != "nt"
     if use_neon:
     if use_neon:
         env_png.Append(CPPDEFINES=[("PNG_ARM_NEON_OPT", 2)])
         env_png.Append(CPPDEFINES=[("PNG_ARM_NEON_OPT", 2)])
     else:
     else:

+ 1 - 1
methods.py

@@ -540,7 +540,7 @@ def detect_visual_c_compiler_version(tools_env):
     # and not scons setup environment (env)... so make sure you call the right environment on it or it will fail to detect
     # and not scons setup environment (env)... so make sure you call the right environment on it or it will fail to detect
     # the proper vc version that will be called
     # the proper vc version that will be called
 
 
-    # There is no flag to give to visual c compilers to set the architecture, i.e. scons bits argument (32,64,ARM etc)
+    # There is no flag to give to visual c compilers to set the architecture, i.e. scons arch argument (x86_32, x86_64, arm64, etc.).
     # There are many different cl.exe files that are run, and each one compiles & links to a different architecture
     # There are many different cl.exe files that are run, and each one compiles & links to a different architecture
     # As far as I know, the only way to figure out what compiler will be run when Scons calls cl.exe via Program()
     # As far as I know, the only way to figure out what compiler will be run when Scons calls cl.exe via Program()
     # is to check the PATH variable and figure out which one will be called first. Code below does that and returns:
     # is to check the PATH variable and figure out which one will be called first. Code below does that and returns:

+ 1 - 8
modules/denoise/config.py

@@ -5,14 +5,7 @@ def can_build(env, platform):
     # as doing lightmap generation and denoising on Android or HTML5
     # as doing lightmap generation and denoising on Android or HTML5
     # would be a bit far-fetched.
     # would be a bit far-fetched.
     desktop_platforms = ["linuxbsd", "macos", "windows"]
     desktop_platforms = ["linuxbsd", "macos", "windows"]
-    supported_arch = env["bits"] == "64"
-    if env["arch"] == "arm64":
-        supported_arch = False
-    if env["arch"].startswith("ppc"):
-        supported_arch = False
-    if env["arch"].startswith("rv"):
-        supported_arch = False
-    return env["tools"] and platform in desktop_platforms and supported_arch
+    return env["tools"] and platform in desktop_platforms and env["arch"] == "x86_64"
 
 
 
 
 def configure(env):
 def configure(env):

+ 10 - 14
modules/mono/build_scripts/mono_configure.py

@@ -18,7 +18,7 @@ def configure(env, env_mono):
     # is_android = env["platform"] == "android"
     # is_android = env["platform"] == "android"
     # is_javascript = env["platform"] == "javascript"
     # is_javascript = env["platform"] == "javascript"
     # is_ios = env["platform"] == "ios"
     # is_ios = env["platform"] == "ios"
-    # is_ios_sim = is_ios and env["arch"] in ["x86", "x86_64"]
+    # is_ios_sim = is_ios and env["arch"] in ["x86_32", "x86_64"]
 
 
     tools_enabled = env["tools"]
     tools_enabled = env["tools"]
 
 
@@ -128,26 +128,22 @@ def find_dotnet_app_host_dir(env):
 
 
 
 
 def determine_runtime_identifier(env):
 def determine_runtime_identifier(env):
+    # The keys are Godot's names, the values are the Microsoft's names.
+    # List: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
     names_map = {
     names_map = {
         "windows": "win",
         "windows": "win",
         "macos": "osx",
         "macos": "osx",
         "linuxbsd": "linux",
         "linuxbsd": "linux",
     }
     }
-
-    # .NET RID architectures: x86, x64, arm, or arm64
-
+    arch_map = {
+        "x86_64": "x64",
+        "x86_32": "x86",
+        "arm64": "arm64",
+        "arm32": "arm",
+    }
     platform = env["platform"]
     platform = env["platform"]
-
     if is_desktop(platform):
     if is_desktop(platform):
-        if env["arch"] in ["arm", "arm32"]:
-            rid = "arm"
-        elif env["arch"] == "arm64":
-            rid = "arm64"
-        else:
-            bits = env["bits"]
-            bit_arch_map = {"64": "x64", "32": "x86"}
-            rid = bit_arch_map[bits]
-        return "%s-%s" % (names_map[platform], rid)
+        return "%s-%s" % (names_map[platform], arch_map[env["arch"]])
     else:
     else:
         raise NotImplementedError()
         raise NotImplementedError()
 
 

+ 24 - 20
modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs

@@ -75,8 +75,17 @@ namespace GodotTools.Export
             }
             }
             else
             else
             {
             {
-                string bits = features.Contains("64") ? "64" : features.Contains("32") ? "32" : null;
-                CompileAssembliesForDesktop(exporter, platform, isDebug, bits, aotOpts, aotTempDir, outputDataDir, assembliesPrepared, bclDir);
+                string arch = "";
+                if (features.Contains("x86_64")) {
+                    arch = "x86_64";
+                } else if (features.Contains("x86_32")) {
+                    arch = "x86_32";
+                } else if (features.Contains("arm64")) {
+                    arch = "arm64";
+                } else if (features.Contains("arm32")) {
+                    arch = "arm32";
+                }
+                CompileAssembliesForDesktop(exporter, platform, isDebug, arch, aotOpts, aotTempDir, outputDataDir, assembliesPrepared, bclDir);
             }
             }
         }
         }
 
 
@@ -112,7 +121,7 @@ namespace GodotTools.Export
             }
             }
         }
         }
 
 
-        public static void CompileAssembliesForDesktop(ExportPlugin exporter, string platform, bool isDebug, string bits, AotOptions aotOpts, string aotTempDir, string outputDataDir, IDictionary<string, string> assemblies, string bclDir)
+        public static void CompileAssembliesForDesktop(ExportPlugin exporter, string platform, bool isDebug, string arch, AotOptions aotOpts, string aotTempDir, string outputDataDir, IDictionary<string, string> assemblies, string bclDir)
         {
         {
             foreach (var assembly in assemblies)
             foreach (var assembly in assemblies)
             {
             {
@@ -126,9 +135,9 @@ namespace GodotTools.Export
                 string outputFileName = assemblyName + ".dll" + outputFileExtension;
                 string outputFileName = assemblyName + ".dll" + outputFileExtension;
                 string tempOutputFilePath = Path.Combine(aotTempDir, outputFileName);
                 string tempOutputFilePath = Path.Combine(aotTempDir, outputFileName);
 
 
-                var compilerArgs = GetAotCompilerArgs(platform, isDebug, bits, aotOpts, assemblyPath, tempOutputFilePath);
+                var compilerArgs = GetAotCompilerArgs(platform, isDebug, arch, aotOpts, assemblyPath, tempOutputFilePath);
 
 
-                string compilerDirPath = GetMonoCrossDesktopDirName(platform, bits);
+                string compilerDirPath = GetMonoCrossDesktopDirName(platform, arch);
 
 
                 ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir);
                 ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir);
 
 
@@ -432,9 +441,9 @@ MONO_AOT_MODE_LAST = 1000,
 
 
                 var androidToolPrefixes = new Dictionary<string, string>
                 var androidToolPrefixes = new Dictionary<string, string>
                 {
                 {
-                    ["armeabi-v7a"] = "arm-linux-androideabi-",
-                    ["arm64-v8a"] = "aarch64-linux-android-",
-                    ["x86"] = "i686-linux-android-",
+                    ["arm32"] = "arm-linux-androideabi-",
+                    ["arm64"] = "aarch64-linux-android-",
+                    ["x86_32"] = "i686-linux-android-",
                     ["x86_64"] = "x86_64-linux-android-"
                     ["x86_64"] = "x86_64-linux-android-"
                 };
                 };
 
 
@@ -547,9 +556,9 @@ MONO_AOT_MODE_LAST = 1000,
         {
         {
             var androidAbis = new[]
             var androidAbis = new[]
             {
             {
-                "armeabi-v7a",
-                "arm64-v8a",
-                "x86",
+                "arm32",
+                "arm64",
+                "x86_32",
                 "x86_64"
                 "x86_64"
             };
             };
 
 
@@ -560,9 +569,9 @@ MONO_AOT_MODE_LAST = 1000,
         {
         {
             var abiArchs = new Dictionary<string, string>
             var abiArchs = new Dictionary<string, string>
             {
             {
-                ["armeabi-v7a"] = "armv7",
-                ["arm64-v8a"] = "aarch64-v8a",
-                ["x86"] = "i686",
+                ["arm32"] = "armv7",
+                ["arm64"] = "aarch64-v8a",
+                ["x86_32"] = "i686",
                 ["x86_64"] = "x86_64"
                 ["x86_64"] = "x86_64"
             };
             };
 
 
@@ -571,30 +580,25 @@ MONO_AOT_MODE_LAST = 1000,
             return $"{arch}-linux-android";
             return $"{arch}-linux-android";
         }
         }
 
 
-        private static string GetMonoCrossDesktopDirName(string platform, string bits)
+        private static string GetMonoCrossDesktopDirName(string platform, string arch)
         {
         {
             switch (platform)
             switch (platform)
             {
             {
                 case OS.Platforms.Windows:
                 case OS.Platforms.Windows:
                 case OS.Platforms.UWP:
                 case OS.Platforms.UWP:
                 {
                 {
-                    string arch = bits == "64" ? "x86_64" : "i686";
                     return $"windows-{arch}";
                     return $"windows-{arch}";
                 }
                 }
                 case OS.Platforms.MacOS:
                 case OS.Platforms.MacOS:
                 {
                 {
-                    Debug.Assert(bits == null || bits == "64");
-                    string arch = "x86_64";
                     return $"{platform}-{arch}";
                     return $"{platform}-{arch}";
                 }
                 }
                 case OS.Platforms.LinuxBSD:
                 case OS.Platforms.LinuxBSD:
                 {
                 {
-                    string arch = bits == "64" ? "x86_64" : "i686";
                     return $"linux-{arch}";
                     return $"linux-{arch}";
                 }
                 }
                 case OS.Platforms.Haiku:
                 case OS.Platforms.Haiku:
                 {
                 {
-                    string arch = bits == "64" ? "x86_64" : "i686";
                     return $"{platform}-{arch}";
                     return $"{platform}-{arch}";
                 }
                 }
                 default:
                 default:

+ 2 - 2
modules/raycast/SCsub

@@ -66,7 +66,7 @@ if env["builtin_embree"]:
     env_raycast.Append(CPPDEFINES=["EMBREE_TARGET_SSE2", "EMBREE_LOWEST_ISA", "TASKING_INTERNAL", "NDEBUG"])
     env_raycast.Append(CPPDEFINES=["EMBREE_TARGET_SSE2", "EMBREE_LOWEST_ISA", "TASKING_INTERNAL", "NDEBUG"])
 
 
     if not env.msvc:
     if not env.msvc:
-        if env["arch"] in ["x86", "x86_64"]:
+        if env["arch"] == "x86_64":
             env_raycast.Append(CPPFLAGS=["-msse2", "-mxsave"])
             env_raycast.Append(CPPFLAGS=["-msse2", "-mxsave"])
 
 
         if env["platform"] == "windows":
         if env["platform"] == "windows":
@@ -83,7 +83,7 @@ if env["builtin_embree"]:
     env_thirdparty.disable_warnings()
     env_thirdparty.disable_warnings()
     env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
     env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
 
 
-    if not env["arch"] in ["x86", "x86_64"] or env.msvc:
+    if env["arch"] == "arm64" or env.msvc:
         # Embree needs those, it will automatically use SSE2NEON in ARM
         # Embree needs those, it will automatically use SSE2NEON in ARM
         env_thirdparty.Append(CPPDEFINES=["__SSE2__", "__SSE__"])
         env_thirdparty.Append(CPPDEFINES=["__SSE2__", "__SSE__"])
 
 

+ 2 - 14
modules/raycast/config.py

@@ -1,18 +1,6 @@
 def can_build(env, platform):
 def can_build(env, platform):
-    # Depends on Embree library, which only supports x86_64 and aarch64.
-    if env["arch"].startswith("rv") or env["arch"].startswith("ppc"):
-        return False
-
-    if platform == "android":
-        return env["android_arch"] in ["arm64v8", "x86_64"]
-
-    if platform == "javascript":
-        return False  # No SIMD support yet
-
-    if env["bits"] == "32":
-        return False
-
-    return True
+    # Depends on Embree library, which only supports x86_64 and arm64.
+    return env["arch"] in ["x86_64", "arm64"]
 
 
 
 
 def configure(env):
 def configure(env):

+ 4 - 4
platform/android/SCsub

@@ -41,13 +41,13 @@ lib = env_android.add_shared_library("#bin/libgodot", [android_objects], SHLIBSU
 env.Depends(lib, thirdparty_obj)
 env.Depends(lib, thirdparty_obj)
 
 
 lib_arch_dir = ""
 lib_arch_dir = ""
-if env["android_arch"] == "armv7":
+if env["arch"] == "arm32":
     lib_arch_dir = "armeabi-v7a"
     lib_arch_dir = "armeabi-v7a"
-elif env["android_arch"] == "arm64v8":
+elif env["arch"] == "arm64":
     lib_arch_dir = "arm64-v8a"
     lib_arch_dir = "arm64-v8a"
-elif env["android_arch"] == "x86":
+elif env["arch"] == "x86_32":
     lib_arch_dir = "x86"
     lib_arch_dir = "x86"
-elif env["android_arch"] == "x86_64":
+elif env["arch"] == "x86_64":
     lib_arch_dir = "x86_64"
     lib_arch_dir = "x86_64"
 else:
 else:
     print("WARN: Architecture not suitable for embedding into APK; keeping .so at \\bin")
     print("WARN: Architecture not suitable for embedding into APK; keeping .so at \\bin")

+ 23 - 21
platform/android/detect.py

@@ -22,7 +22,6 @@ def get_opts():
     return [
     return [
         ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_env_android_sdk_root()),
         ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_env_android_sdk_root()),
         ("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"),
         ("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"),
-        EnumVariable("android_arch", "Target architecture", "arm64v8", ("armv7", "arm64v8", "x86", "x86_64")),
     ]
     ]
 
 
 
 
@@ -46,6 +45,7 @@ def get_ndk_version():
 
 
 def get_flags():
 def get_flags():
     return [
     return [
+        ("arch", "arm64"),  # Default for convenience.
         ("tools", False),
         ("tools", False),
     ]
     ]
 
 
@@ -75,35 +75,37 @@ def install_ndk_if_needed(env):
 
 
 
 
 def configure(env):
 def configure(env):
+    # Validate arch.
+    supported_arches = ["x86_32", "x86_64", "arm32", "arm64"]
+    if env["arch"] not in supported_arches:
+        print(
+            'Unsupported CPU architecture "%s" for Android. Supported architectures are: %s.'
+            % (env["arch"], ", ".join(supported_arches))
+        )
+        sys.exit()
+
     install_ndk_if_needed(env)
     install_ndk_if_needed(env)
     ndk_root = env["ANDROID_NDK_ROOT"]
     ndk_root = env["ANDROID_NDK_ROOT"]
 
 
     # Architecture
     # Architecture
 
 
-    if env["android_arch"] not in ["armv7", "arm64v8", "x86", "x86_64"]:
-        env["android_arch"] = "arm64v8"
-
-    print("Building for Android, platform " + env["ndk_platform"] + " (" + env["android_arch"] + ")")
-
-    if get_min_sdk_version(env["ndk_platform"]) < 21:
-        if env["android_arch"] == "x86_64" or env["android_arch"] == "arm64v8":
-            print(
-                "WARNING: android_arch="
-                + env["android_arch"]
-                + " is not supported by ndk_platform lower than android-21; setting ndk_platform=android-21"
-            )
-            env["ndk_platform"] = "android-21"
+    if get_min_sdk_version(env["ndk_platform"]) < 21 and env["arch"] in ["x86_64", "arm64"]:
+        print(
+            'WARNING: arch="%s" is not supported with "ndk_platform" lower than "android-21". Forcing platform 21.'
+            % env["arch"]
+        )
+        env["ndk_platform"] = "android-21"
 
 
-    if env["android_arch"] == "armv7":
+    if env["arch"] == "arm32":
         target_triple = "armv7a-linux-androideabi"
         target_triple = "armv7a-linux-androideabi"
         env.extra_suffix = ".armv7" + env.extra_suffix
         env.extra_suffix = ".armv7" + env.extra_suffix
-    elif env["android_arch"] == "arm64v8":
+    elif env["arch"] == "arm64":
         target_triple = "aarch64-linux-android"
         target_triple = "aarch64-linux-android"
         env.extra_suffix = ".armv8" + env.extra_suffix
         env.extra_suffix = ".armv8" + env.extra_suffix
-    elif env["android_arch"] == "x86":
+    elif env["arch"] == "x86_32":
         target_triple = "i686-linux-android"
         target_triple = "i686-linux-android"
         env.extra_suffix = ".x86" + env.extra_suffix
         env.extra_suffix = ".x86" + env.extra_suffix
-    elif env["android_arch"] == "x86_64":
+    elif env["arch"] == "x86_64":
         target_triple = "x86_64-linux-android"
         target_triple = "x86_64-linux-android"
         env.extra_suffix = ".x86_64" + env.extra_suffix
         env.extra_suffix = ".x86_64" + env.extra_suffix
 
 
@@ -176,14 +178,14 @@ def configure(env):
     if get_min_sdk_version(env["ndk_platform"]) >= 24:
     if get_min_sdk_version(env["ndk_platform"]) >= 24:
         env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)])
         env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)])
 
 
-    if env["android_arch"] == "x86":
+    if env["arch"] == "x86_32":
         # The NDK adds this if targeting API < 24, so we can drop it when Godot targets it at least
         # The NDK adds this if targeting API < 24, so we can drop it when Godot targets it at least
         env.Append(CCFLAGS=["-mstackrealign"])
         env.Append(CCFLAGS=["-mstackrealign"])
-    elif env["android_arch"] == "armv7":
+    elif env["arch"] == "arm32":
         env.Append(CCFLAGS="-march=armv7-a -mfloat-abi=softfp".split())
         env.Append(CCFLAGS="-march=armv7-a -mfloat-abi=softfp".split())
         env.Append(CPPDEFINES=["__ARM_ARCH_7__", "__ARM_ARCH_7A__"])
         env.Append(CPPDEFINES=["__ARM_ARCH_7__", "__ARM_ARCH_7A__"])
         env.Append(CPPDEFINES=["__ARM_NEON__"])
         env.Append(CPPDEFINES=["__ARM_NEON__"])
-    elif env["android_arch"] == "arm64v8":
+    elif env["arch"] == "arm64":
         env.Append(CCFLAGS=["-mfix-cortex-a53-835769"])
         env.Append(CCFLAGS=["-mfix-cortex-a53-835769"])
         env.Append(CPPDEFINES=["__ARM_ARCH_8A__"])
         env.Append(CPPDEFINES=["__ARM_ARCH_8A__"])
 
 

+ 4 - 4
platform/android/export/export_plugin.cpp

@@ -588,9 +588,9 @@ zip_fileinfo EditorExportPlatformAndroid::get_zip_fileinfo() {
 
 
 Vector<String> EditorExportPlatformAndroid::get_abis() {
 Vector<String> EditorExportPlatformAndroid::get_abis() {
 	Vector<String> abis;
 	Vector<String> abis;
-	abis.push_back("armeabi-v7a");
-	abis.push_back("arm64-v8a");
-	abis.push_back("x86");
+	abis.push_back("arm32");
+	abis.push_back("arm64");
+	abis.push_back("x86_32");
 	abis.push_back("x86_64");
 	abis.push_back("x86_64");
 	return abis;
 	return abis;
 }
 }
@@ -1710,7 +1710,7 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
 		const String abi = abis[i];
 		const String abi = abis[i];
 		// All Android devices supporting Vulkan run 64-bit Android,
 		// All Android devices supporting Vulkan run 64-bit Android,
 		// so there is usually no point in exporting for 32-bit Android.
 		// so there is usually no point in exporting for 32-bit Android.
-		const bool is_default = abi == "arm64-v8a";
+		const bool is_default = abi == "arm64";
 		r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("architectures"), abi)), is_default));
 		r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("architectures"), abi)), is_default));
 	}
 	}
 
 

+ 2 - 2
platform/android/java/build.gradle

@@ -28,7 +28,7 @@ allprojects {
 }
 }
 
 
 ext {
 ext {
-    supportedAbis = ["armv7", "arm64v8", "x86", "x86_64"]
+    supportedAbis = ["arm32", "arm64", "x86_32", "x86_64"]
     supportedTargetsMap = [release: "release", dev: "debug", debug: "release_debug"]
     supportedTargetsMap = [release: "release", dev: "debug", debug: "release_debug"]
     supportedFlavors = ["editor", "template"]
     supportedFlavors = ["editor", "template"]
 
 
@@ -37,7 +37,7 @@ ext {
     // If building manually on the command line, it's recommended to use the
     // If building manually on the command line, it's recommended to use the
     // `./gradlew generateGodotTemplates` build command instead after running the `scons` command(s).
     // `./gradlew generateGodotTemplates` build command instead after running the `scons` command(s).
     // The {selectedAbis} values must be from the {supportedAbis} values.
     // The {selectedAbis} values must be from the {supportedAbis} values.
-    selectedAbis = ["arm64v8"]
+    selectedAbis = ["arm64"]
 }
 }
 
 
 def rootDir = "../../.."
 def rootDir = "../../.."

+ 1 - 1
platform/android/java/lib/build.gradle

@@ -159,7 +159,7 @@ android {
             def taskName = getSconsTaskName(flavorName, buildType, selectedAbi)
             def taskName = getSconsTaskName(flavorName, buildType, selectedAbi)
             tasks.create(name: taskName, type: Exec) {
             tasks.create(name: taskName, type: Exec) {
                 executable sconsExecutableFile.absolutePath
                 executable sconsExecutableFile.absolutePath
-                args "--directory=${pathToRootDir}", "platform=android", "tools=${toolsFlag}", "target=${sconsTarget}", "android_arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors()
+                args "--directory=${pathToRootDir}", "platform=android", "tools=${toolsFlag}", "target=${sconsTarget}", "arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors()
             }
             }
 
 
             // Schedule the tasks so the generated libs are present before the aar file is packaged.
             // Schedule the tasks so the generated libs are present before the aar file is packaged.

+ 3 - 3
platform/android/os_android.cpp

@@ -370,15 +370,15 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) {
 		return true;
 		return true;
 	}
 	}
 #if defined(__aarch64__)
 #if defined(__aarch64__)
-	if (p_feature == "arm64-v8a") {
+	if (p_feature == "arm64-v8a" || p_feature == "arm64") {
 		return true;
 		return true;
 	}
 	}
 #elif defined(__ARM_ARCH_7A__)
 #elif defined(__ARM_ARCH_7A__)
-	if (p_feature == "armeabi-v7a" || p_feature == "armeabi") {
+	if (p_feature == "armeabi-v7a" || p_feature == "armeabi" || p_feature == "arm32") {
 		return true;
 		return true;
 	}
 	}
 #elif defined(__arm__)
 #elif defined(__arm__)
-	if (p_feature == "armeabi") {
+	if (p_feature == "armeabi" || p_feature == "arm") {
 		return true;
 		return true;
 	}
 	}
 #endif
 #endif

+ 10 - 5
platform/ios/detect.py

@@ -36,12 +36,22 @@ def get_opts():
 
 
 def get_flags():
 def get_flags():
     return [
     return [
+        ("arch", "arm64"),  # Default for convenience.
         ("tools", False),
         ("tools", False),
         ("use_volk", False),
         ("use_volk", False),
     ]
     ]
 
 
 
 
 def configure(env):
 def configure(env):
+    # Validate arch.
+    supported_arches = ["x86_64", "arm64"]
+    if env["arch"] not in supported_arches:
+        print(
+            'Unsupported CPU architecture "%s" for iOS. Supported architectures are: %s.'
+            % (env["arch"], ", ".join(supported_arches))
+        )
+        sys.exit()
+
     ## Build type
     ## Build type
 
 
     if env["target"].startswith("release"):
     if env["target"].startswith("release"):
@@ -64,11 +74,6 @@ def configure(env):
         env.Append(CCFLAGS=["-flto"])
         env.Append(CCFLAGS=["-flto"])
         env.Append(LINKFLAGS=["-flto"])
         env.Append(LINKFLAGS=["-flto"])
 
 
-    ## Architecture
-    env["bits"] = "64"
-    if env["arch"] != "x86_64":
-        env["arch"] = "arm64"
-
     ## Compiler configuration
     ## Compiler configuration
 
 
     # Save this in environment for use by other modules
     # Save this in environment for use by other modules

+ 10 - 0
platform/javascript/detect.py

@@ -46,6 +46,7 @@ def get_opts():
 
 
 def get_flags():
 def get_flags():
     return [
     return [
+        ("arch", "wasm32"),
         ("tools", False),
         ("tools", False),
         ("builtin_pcre2_with_jit", False),
         ("builtin_pcre2_with_jit", False),
         ("vulkan", False),
         ("vulkan", False),
@@ -53,6 +54,15 @@ def get_flags():
 
 
 
 
 def configure(env):
 def configure(env):
+    # Validate arch.
+    supported_arches = ["wasm32"]
+    if env["arch"] not in supported_arches:
+        print(
+            'Unsupported CPU architecture "%s" for iOS. Supported architectures are: %s.'
+            % (env["arch"], ", ".join(supported_arches))
+        )
+        sys.exit()
+
     try:
     try:
         env["initial_memory"] = int(env["initial_memory"])
         env["initial_memory"] = int(env["initial_memory"])
     except Exception:
     except Exception:

+ 19 - 23
platform/linuxbsd/detect.py

@@ -2,6 +2,7 @@ import os
 import platform
 import platform
 import sys
 import sys
 from methods import get_compiler_version, using_gcc
 from methods import get_compiler_version, using_gcc
+from platform_methods import detect_arch
 
 
 
 
 def is_active():
 def is_active():
@@ -52,10 +53,21 @@ def get_opts():
 
 
 
 
 def get_flags():
 def get_flags():
-    return []
+    return [
+        ("arch", detect_arch()),
+    ]
 
 
 
 
 def configure(env):
 def configure(env):
+    # Validate arch.
+    supported_arches = ["x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc32", "ppc64"]
+    if env["arch"] not in supported_arches:
+        print(
+            'Unsupported CPU architecture "%s" for Linux / *BSD. Supported architectures are: %s.'
+            % (env["arch"], ", ".join(supported_arches))
+        )
+        sys.exit()
+
     ## Build type
     ## Build type
 
 
     if env["target"] == "release":
     if env["target"] == "release":
@@ -80,23 +92,7 @@ def configure(env):
         env.Prepend(CCFLAGS=["-g3"])
         env.Prepend(CCFLAGS=["-g3"])
         env.Append(LINKFLAGS=["-rdynamic"])
         env.Append(LINKFLAGS=["-rdynamic"])
 
 
-    ## Architecture
-
-    is64 = sys.maxsize > 2**32
-    if env["bits"] == "default":
-        env["bits"] = "64" if is64 else "32"
-
-    machines = {
-        "riscv64": "rv64",
-        "ppc64le": "ppc64",
-        "ppc64": "ppc64",
-        "ppcle": "ppc",
-        "ppc": "ppc",
-    }
-
-    if env["arch"] == "" and platform.machine() in machines:
-        env["arch"] = machines[platform.machine()]
-
+    # CPU architecture flags.
     if env["arch"] == "rv64":
     if env["arch"] == "rv64":
         # G = General-purpose extensions, C = Compression extension (very common).
         # G = General-purpose extensions, C = Compression extension (very common).
         env.Append(CCFLAGS=["-march=rv64gc"])
         env.Append(CCFLAGS=["-march=rv64gc"])
@@ -262,8 +258,7 @@ def configure(env):
         env["builtin_libvorbis"] = False  # Needed to link against system libtheora
         env["builtin_libvorbis"] = False  # Needed to link against system libtheora
         env.ParseConfig("pkg-config theora theoradec --cflags --libs")
         env.ParseConfig("pkg-config theora theoradec --cflags --libs")
     else:
     else:
-        list_of_x86 = ["x86_64", "x86", "i386", "i586"]
-        if any(platform.machine() in s for s in list_of_x86):
+        if env["arch"] in ["x86_64", "x86_32"]:
             env["x86_libtheora_opt_gcc"] = True
             env["x86_libtheora_opt_gcc"] = True
 
 
     if not env["builtin_libvorbis"]:
     if not env["builtin_libvorbis"]:
@@ -405,11 +400,12 @@ def configure(env):
                 env.Append(LINKFLAGS=["-T", "platform/linuxbsd/pck_embed.legacy.ld"])
                 env.Append(LINKFLAGS=["-T", "platform/linuxbsd/pck_embed.legacy.ld"])
 
 
     ## Cross-compilation
     ## Cross-compilation
-
-    if is64 and env["bits"] == "32":
+    # TODO: Support cross-compilation on architectures other than x86.
+    host_is_64_bit = sys.maxsize > 2**32
+    if host_is_64_bit and env["arch"] == "x86_32":
         env.Append(CCFLAGS=["-m32"])
         env.Append(CCFLAGS=["-m32"])
         env.Append(LINKFLAGS=["-m32", "-L/usr/lib/i386-linux-gnu"])
         env.Append(LINKFLAGS=["-m32", "-L/usr/lib/i386-linux-gnu"])
-    elif not is64 and env["bits"] == "64":
+    elif not host_is_64_bit and env["arch"] == "x86_64":
         env.Append(CCFLAGS=["-m64"])
         env.Append(CCFLAGS=["-m64"])
         env.Append(LINKFLAGS=["-m64", "-L/usr/lib/i686-linux-gnu"])
         env.Append(LINKFLAGS=["-m64", "-L/usr/lib/i686-linux-gnu"])
 
 

+ 17 - 12
platform/macos/detect.py

@@ -1,6 +1,7 @@
 import os
 import os
 import sys
 import sys
 from methods import detect_darwin_sdk_path
 from methods import detect_darwin_sdk_path
+from platform_methods import detect_arch
 
 
 
 
 def is_active():
 def is_active():
@@ -37,6 +38,7 @@ def get_opts():
 
 
 def get_flags():
 def get_flags():
     return [
     return [
+        ("arch", detect_arch()),
         ("use_volk", False),
         ("use_volk", False),
     ]
     ]
 
 
@@ -71,6 +73,15 @@ def get_mvk_sdk_path():
 
 
 
 
 def configure(env):
 def configure(env):
+    # Validate arch.
+    supported_arches = ["x86_64", "arm64"]
+    if env["arch"] not in supported_arches:
+        print(
+            'Unsupported CPU architecture "%s" for macOS. Supported architectures are: %s.'
+            % (env["arch"], ", ".join(supported_arches))
+        )
+        sys.exit()
+
     ## Build type
     ## Build type
 
 
     if env["target"] == "release":
     if env["target"] == "release":
@@ -96,25 +107,20 @@ def configure(env):
         env.Prepend(CCFLAGS=["-g3"])
         env.Prepend(CCFLAGS=["-g3"])
         env.Prepend(LINKFLAGS=["-Xlinker", "-no_deduplicate"])
         env.Prepend(LINKFLAGS=["-Xlinker", "-no_deduplicate"])
 
 
-    ## Architecture
-
-    # macOS no longer runs on 32-bit since 10.7 which is unsupported since 2014
-    # As such, we only support 64-bit
-    env["bits"] = "64"
-
     ## Compiler configuration
     ## Compiler configuration
 
 
     # Save this in environment for use by other modules
     # Save this in environment for use by other modules
     if "OSXCROSS_ROOT" in os.environ:
     if "OSXCROSS_ROOT" in os.environ:
         env["osxcross"] = True
         env["osxcross"] = True
 
 
+    # CPU architecture.
     if env["arch"] == "arm64":
     if env["arch"] == "arm64":
-        print("Building for macOS 11.0+, platform arm64.")
+        print("Building for macOS 11.0+.")
         env.Append(ASFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
         env.Append(ASFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
         env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
         env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
         env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
         env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
-    else:
-        print("Building for macOS 10.12+, platform x86_64.")
+    elif env["arch"] == "x86_64":
+        print("Building for macOS 10.12+.")
         env.Append(ASFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
         env.Append(ASFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
         env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
         env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
         env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
         env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
@@ -185,9 +191,8 @@ def configure(env):
 
 
     ## Dependencies
     ## Dependencies
 
 
-    if env["builtin_libtheora"]:
-        if env["arch"] != "arm64":
-            env["x86_libtheora_opt_gcc"] = True
+    if env["builtin_libtheora"] and env["arch"] == "x86_64":
+        env["x86_libtheora_opt_gcc"] = True
 
 
     ## Flags
     ## Flags
 
 

+ 19 - 20
platform/uwp/detect.py

@@ -1,6 +1,7 @@
 import methods
 import methods
 import os
 import os
 import sys
 import sys
+from platform_methods import detect_arch
 
 
 
 
 def is_active():
 def is_active():
@@ -31,6 +32,7 @@ def get_opts():
 
 
 def get_flags():
 def get_flags():
     return [
     return [
+        ("arch", detect_arch()),
         ("tools", False),
         ("tools", False),
         ("xaudio2", True),
         ("xaudio2", True),
         ("builtin_pcre2_with_jit", False),
         ("builtin_pcre2_with_jit", False),
@@ -38,19 +40,17 @@ def get_flags():
 
 
 
 
 def configure(env):
 def configure(env):
-    env.msvc = True
-
-    if env["bits"] != "default":
-        print("Error: bits argument is disabled for MSVC")
+    # Validate arch.
+    supported_arches = ["x86_32", "x86_64", "arm32"]
+    if env["arch"] not in supported_arches:
         print(
         print(
-            """
-            Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console
-            (or Visual Studio settings) that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits
-            argument (example: scons p=uwp) and SCons will attempt to detect what MSVC compiler will be executed and inform you.
-            """
+            'Unsupported CPU architecture "%s" for UWP. Supported architectures are: %s.'
+            % (env["arch"], ", ".join(supported_arches))
         )
         )
         sys.exit()
         sys.exit()
 
 
+    env.msvc = True
+
     ## Build type
     ## Build type
 
 
     if env["target"] == "release":
     if env["target"] == "release":
@@ -101,11 +101,10 @@ def configure(env):
 
 
     arch = ""
     arch = ""
     if str(os.getenv("Platform")).lower() == "arm":
     if str(os.getenv("Platform")).lower() == "arm":
-
-        print("Compiled program architecture will be an ARM executable. (forcing bits=32).")
+        print("Compiled program architecture will be an ARM executable (forcing arch=arm32).")
 
 
         arch = "arm"
         arch = "arm"
-        env["bits"] = "32"
+        env["arch"] = "arm32"
         env.Append(LINKFLAGS=["/MACHINE:ARM"])
         env.Append(LINKFLAGS=["/MACHINE:ARM"])
         env.Append(LIBPATH=[vc_base_path + "lib/store/arm"])
         env.Append(LIBPATH=[vc_base_path + "lib/store/arm"])
 
 
@@ -117,20 +116,20 @@ def configure(env):
         compiler_version_str = methods.detect_visual_c_compiler_version(env["ENV"])
         compiler_version_str = methods.detect_visual_c_compiler_version(env["ENV"])
 
 
         if compiler_version_str == "amd64" or compiler_version_str == "x86_amd64":
         if compiler_version_str == "amd64" or compiler_version_str == "x86_amd64":
-            env["bits"] = "64"
-            print("Compiled program architecture will be a x64 executable (forcing bits=64).")
+            env["arch"] = "x86_64"
+            print("Compiled program architecture will be a x64 executable (forcing arch=x86_64).")
         elif compiler_version_str == "x86" or compiler_version_str == "amd64_x86":
         elif compiler_version_str == "x86" or compiler_version_str == "amd64_x86":
-            env["bits"] = "32"
-            print("Compiled program architecture will be a x86 executable. (forcing bits=32).")
+            env["arch"] = "x86_32"
+            print("Compiled program architecture will be a x86 executable (forcing arch=x86_32).")
         else:
         else:
             print(
             print(
-                "Failed to detect MSVC compiler architecture version... Defaulting to 32-bit executable settings"
-                " (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture"
+                "Failed to detect MSVC compiler architecture version... Defaulting to x86 32-bit executable settings"
+                " (forcing arch=x86_32). Compilation attempt will continue, but SCons can not detect for what architecture"
                 " this build is compiled for. You should check your settings/compilation setup."
                 " this build is compiled for. You should check your settings/compilation setup."
             )
             )
-            env["bits"] = "32"
+            env["arch"] = "x86_32"
 
 
-        if env["bits"] == "32":
+        if env["arch"] == "x86_32":
             arch = "x86"
             arch = "x86"
 
 
             angle_build_cmd += "Win32"
             angle_build_cmd += "Win32"

+ 61 - 39
platform/windows/detect.py

@@ -1,5 +1,6 @@
 import methods
 import methods
 import os
 import os
+from platform_methods import detect_arch
 
 
 # To match other platforms
 # To match other platforms
 STACK_SIZE = 8388608
 STACK_SIZE = 8388608
@@ -46,6 +47,7 @@ def can_build():
 def get_opts():
 def get_opts():
     from SCons.Variables import BoolVariable, EnumVariable
     from SCons.Variables import BoolVariable, EnumVariable
 
 
+    # TODO: These shouldn't be hard-coded for x86.
     mingw32 = ""
     mingw32 = ""
     mingw64 = ""
     mingw64 = ""
     if os.name == "posix":
     if os.name == "posix":
@@ -77,11 +79,14 @@ def get_opts():
 
 
 
 
 def get_flags():
 def get_flags():
-    return []
+    return [
+        ("arch", detect_arch()),
+    ]
 
 
 
 
 def build_res_file(target, source, env):
 def build_res_file(target, source, env):
-    if env["bits"] == "32":
+    # TODO: This shouldn't be hard-coded for x86.
+    if env["arch"] == "x86_32":
         cmdbase = env["mingw_prefix_32"]
         cmdbase = env["mingw_prefix_32"]
     else:
     else:
         cmdbase = env["mingw_prefix_64"]
         cmdbase = env["mingw_prefix_64"]
@@ -100,21 +105,27 @@ def build_res_file(target, source, env):
 
 
 
 
 def setup_msvc_manual(env):
 def setup_msvc_manual(env):
+    # FIXME: This is super hacky, and probably obsolete.
+    # Won't work with detect_arch() used for `arch` by default.
+
     """Set up env to use MSVC manually, using VCINSTALLDIR"""
     """Set up env to use MSVC manually, using VCINSTALLDIR"""
-    if env["bits"] != "default":
+    if env["arch"] != "auto":
         print(
         print(
             """
             """
-            Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console
-            (or Visual Studio settings) that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits
-            argument (example: scons p=windows) and SCons will attempt to detect what MSVC compiler will be executed and inform you.
+            Arch argument is not supported for MSVC manual configuration (VCINSTALLDIR configured).
+            Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console (or Visual Studio settings) that is being used to run SCons.
+            As a consequence, the arch argument is disabled. Run scons again without arch argument (example: scons p=windows)
+            and SCons will attempt to detect what MSVC compiler will be executed and inform you.
             """
             """
         )
         )
-        raise SCons.Errors.UserError("Bits argument should not be used when using VCINSTALLDIR")
+        raise SCons.Errors.UserError("Arch argument should not be used when using VCINSTALLDIR")
 
 
-    # Force bits arg
+    # Force ARCH arg
     # (Actually msys2 mingw can support 64-bit, we could detect that)
     # (Actually msys2 mingw can support 64-bit, we could detect that)
-    env["bits"] = "32"
-    env["x86_libtheora_opt_vc"] = True
+    # TODO: This is wrong, but not sure what to do about it.
+    # We want to determine the arch and bitness in the SConstruct only.
+    # We can check if it's correct in here, but if it's not, it should
+    # just fail with an error message instead of trying to force it.
 
 
     # find compiler manually
     # find compiler manually
     compiler_version_str = methods.detect_visual_c_compiler_version(env["ENV"])
     compiler_version_str = methods.detect_visual_c_compiler_version(env["ENV"])
@@ -122,17 +133,19 @@ def setup_msvc_manual(env):
 
 
     # If building for 64bit architecture, disable assembly optimisations for 32 bit builds (theora as of writing)... vc compiler for 64bit can not compile _asm
     # If building for 64bit architecture, disable assembly optimisations for 32 bit builds (theora as of writing)... vc compiler for 64bit can not compile _asm
     if compiler_version_str == "amd64" or compiler_version_str == "x86_amd64":
     if compiler_version_str == "amd64" or compiler_version_str == "x86_amd64":
-        env["bits"] = "64"
+        env["arch"] = "x86_64"
         env["x86_libtheora_opt_vc"] = False
         env["x86_libtheora_opt_vc"] = False
-        print("Compiled program architecture will be a 64 bit executable (forcing bits=64).")
+        print("Compiled program architecture will be a 64 bit executable (forcing arch=x86_64).")
     elif compiler_version_str == "x86" or compiler_version_str == "amd64_x86":
     elif compiler_version_str == "x86" or compiler_version_str == "amd64_x86":
-        print("Compiled program architecture will be a 32 bit executable. (forcing bits=32).")
+        env["arch"] = "x86_32"
+        env["x86_libtheora_opt_vc"] = True
+        print("Compiled program architecture will be a 32 bit executable (forcing arch=x86_32).")
     else:
     else:
         print(
         print(
-            "Failed to manually detect MSVC compiler architecture version... Defaulting to 32bit executable settings"
-            " (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this"
-            " build is compiled for. You should check your settings/compilation setup, or avoid setting VCINSTALLDIR."
+            "Failed to manually detect MSVC compiler architecture version.\n"
+            "You should check your settings/compilation setup, or avoid setting VCINSTALLDIR."
         )
         )
+        sys.exit()
 
 
 
 
 def setup_msvc_auto(env):
 def setup_msvc_auto(env):
@@ -141,6 +154,18 @@ def setup_msvc_auto(env):
     # If MSVC_VERSION is set by SCons, we know MSVC is installed.
     # If MSVC_VERSION is set by SCons, we know MSVC is installed.
     # But we may want a different version or target arch.
     # But we may want a different version or target arch.
 
 
+    # Valid architectures for MSVC's TARGET_ARCH:
+    # ['amd64', 'emt64', 'i386', 'i486', 'i586', 'i686', 'ia64', 'itanium', 'x86', 'x86_64', 'arm', 'arm64', 'aarch64']
+    # Our x86_64 and arm64 are the same, and we need to map the 32-bit
+    # architectures to other names since MSVC isn't as explicit.
+    # The rest we don't need to worry about because they are
+    # aliases or aren't supported by Godot (itanium & ia64).
+    msvc_arch_aliases = {"x86_32": "x86", "arm32": "arm"}
+    if env["arch"] in msvc_arch_aliases.keys():
+        env["TARGET_ARCH"] = msvc_arch_aliases[env["arch"]]
+    else:
+        env["TARGET_ARCH"] = env["arch"]
+
     # The env may have already been set up with default MSVC tools, so
     # The env may have already been set up with default MSVC tools, so
     # reset a few things so we can set it up with the tools we want.
     # reset a few things so we can set it up with the tools we want.
     # (Ideally we'd decide on the tool config before configuring any
     # (Ideally we'd decide on the tool config before configuring any
@@ -149,21 +174,14 @@ def setup_msvc_auto(env):
     env["MSVC_SETUP_RUN"] = False  # Need to set this to re-run the tool
     env["MSVC_SETUP_RUN"] = False  # Need to set this to re-run the tool
     env["MSVS_VERSION"] = None
     env["MSVS_VERSION"] = None
     env["MSVC_VERSION"] = None
     env["MSVC_VERSION"] = None
-    env["TARGET_ARCH"] = None
-    if env["bits"] != "default":
-        env["TARGET_ARCH"] = {"32": "x86", "64": "x86_64"}[env["bits"]]
+
     if "msvc_version" in env:
     if "msvc_version" in env:
         env["MSVC_VERSION"] = env["msvc_version"]
         env["MSVC_VERSION"] = env["msvc_version"]
     env.Tool("msvc")
     env.Tool("msvc")
     env.Tool("mssdk")  # we want the MS SDK
     env.Tool("mssdk")  # we want the MS SDK
     # Note: actual compiler version can be found in env['MSVC_VERSION'], e.g. "14.1" for VS2015
     # Note: actual compiler version can be found in env['MSVC_VERSION'], e.g. "14.1" for VS2015
-    # Get actual target arch into bits (it may be "default" at this point):
-    if env["TARGET_ARCH"] in ("amd64", "x86_64"):
-        env["bits"] = "64"
-    else:
-        env["bits"] = "32"
-    print("Found MSVC version %s, arch %s, bits=%s" % (env["MSVC_VERSION"], env["TARGET_ARCH"], env["bits"]))
-    if env["TARGET_ARCH"] in ("amd64", "x86_64"):
+    print("Found MSVC version %s, arch %s" % (env["MSVC_VERSION"], env["TARGET_ARCH"]))
+    if env["arch"] == "x86_32":
         env["x86_libtheora_opt_vc"] = False
         env["x86_libtheora_opt_vc"] = False
 
 
 
 
@@ -244,7 +262,7 @@ def configure_msvc(env, manual_msvc_config):
         ]
         ]
     )
     )
     env.AppendUnique(CPPDEFINES=["NOMINMAX"])  # disable bogus min/max WinDef.h macros
     env.AppendUnique(CPPDEFINES=["NOMINMAX"])  # disable bogus min/max WinDef.h macros
-    if env["bits"] == "64":
+    if env["arch"] == "x86_64":
         env.AppendUnique(CPPDEFINES=["_WIN64"])
         env.AppendUnique(CPPDEFINES=["_WIN64"])
 
 
     ## Libs
     ## Libs
@@ -328,10 +346,10 @@ def configure_mingw(env):
         env.Append(CCFLAGS=["-msse2"])
         env.Append(CCFLAGS=["-msse2"])
 
 
         if env["optimize"] == "speed":  # optimize for speed (default)
         if env["optimize"] == "speed":  # optimize for speed (default)
-            if env["bits"] == "64":
-                env.Append(CCFLAGS=["-O3"])
-            else:
+            if env["arch"] == "x86_32":
                 env.Append(CCFLAGS=["-O2"])
                 env.Append(CCFLAGS=["-O2"])
+            else:
+                env.Append(CCFLAGS=["-O3"])
         else:  # optimize for size
         else:  # optimize for size
             env.Prepend(CCFLAGS=["-Os"])
             env.Prepend(CCFLAGS=["-Os"])
 
 
@@ -365,15 +383,12 @@ def configure_mingw(env):
     if os.name != "nt":
     if os.name != "nt":
         env["PROGSUFFIX"] = env["PROGSUFFIX"] + ".exe"  # for linux cross-compilation
         env["PROGSUFFIX"] = env["PROGSUFFIX"] + ".exe"  # for linux cross-compilation
 
 
-    if env["bits"] == "default":
-        if os.name == "nt":
-            env["bits"] = "64" if "PROGRAMFILES(X86)" in os.environ else "32"
-        else:  # default to 64-bit on Linux
-            env["bits"] = "64"
-
     mingw_prefix = ""
     mingw_prefix = ""
 
 
-    if env["bits"] == "32":
+    # TODO: This doesn't seem to be working, or maybe I just have
+    # MinGW set up incorrectly. It always gives me x86_64 builds,
+    # even though arch == "x86_32" and the file name has x86_32 in it.
+    if env["arch"] == "x86_32":
         if env["use_static_cpp"]:
         if env["use_static_cpp"]:
             env.Append(LINKFLAGS=["-static"])
             env.Append(LINKFLAGS=["-static"])
             env.Append(LINKFLAGS=["-static-libgcc"])
             env.Append(LINKFLAGS=["-static-libgcc"])
@@ -460,11 +475,18 @@ def configure_mingw(env):
 
 
 
 
 def configure(env):
 def configure(env):
+    # Validate arch.
+    supported_arches = ["x86_32", "x86_64", "arm32", "arm64"]
+    if env["arch"] not in supported_arches:
+        print(
+            'Unsupported CPU architecture "%s" for Windows. Supported architectures are: %s.'
+            % (env["arch"], ", ".join(supported_arches))
+        )
+        sys.exit()
+
     # At this point the env has been set up with basic tools/compilers.
     # At this point the env has been set up with basic tools/compilers.
     env.Prepend(CPPPATH=["#platform/windows"])
     env.Prepend(CPPPATH=["#platform/windows"])
 
 
-    print("Configuring for Windows: target=%s, bits=%s" % (env["target"], env["bits"]))
-
     if os.name == "nt":
     if os.name == "nt":
         env["ENV"] = os.environ  # this makes build less repeatable, but simplifies some things
         env["ENV"] = os.environ  # this makes build less repeatable, but simplifies some things
         env["ENV"]["TMP"] = os.environ["TMP"]
         env["ENV"]["TMP"] = os.environ["TMP"]

+ 1 - 1
platform/windows/platform_windows_builders.py

@@ -9,7 +9,7 @@ from platform_methods import subprocess_main
 
 
 def make_debug_mingw(target, source, env):
 def make_debug_mingw(target, source, env):
     mingw_prefix = ""
     mingw_prefix = ""
-    if env["bits"] == "32":
+    if env["arch"] == "x86_32":
         mingw_prefix = env["mingw_prefix_32"]
         mingw_prefix = env["mingw_prefix_32"]
     else:
     else:
         mingw_prefix = env["mingw_prefix_64"]
         mingw_prefix = env["mingw_prefix_64"]

+ 35 - 1
platform_methods.py

@@ -1,6 +1,7 @@
 import os
 import os
 import sys
 import sys
 import json
 import json
+import platform
 import uuid
 import uuid
 import functools
 import functools
 import subprocess
 import subprocess
@@ -71,9 +72,42 @@ def run_in_subprocess(builder_function):
 
 
 
 
 def subprocess_main(namespace):
 def subprocess_main(namespace):
-
     with open(sys.argv[1]) as json_file:
     with open(sys.argv[1]) as json_file:
         data = json.load(json_file)
         data = json.load(json_file)
 
 
     fn = namespace[data["fn"]]
     fn = namespace[data["fn"]]
     fn(*data["args"])
     fn(*data["args"])
+
+
+# CPU architecture options.
+architectures = ["x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc32", "ppc64", "wasm32"]
+architecture_aliases = {
+    "x86": "x86_32",
+    "x64": "x86_64",
+    "amd64": "x86_64",
+    "armv7": "arm32",
+    "armv8": "arm64",
+    "arm64v8": "arm64",
+    "aarch64": "arm64",
+    "rv": "rv64",
+    "riscv": "rv64",
+    "riscv64": "rv64",
+    "ppcle": "ppc32",
+    "ppc": "ppc32",
+    "ppc64le": "ppc64",
+}
+
+
+def detect_arch():
+    host_machine = platform.machine().lower()
+    if host_machine in architectures:
+        return host_machine
+    elif host_machine in architecture_aliases.keys():
+        return architecture_aliases[host_machine]
+    elif "86" in host_machine:
+        # Catches x86, i386, i486, i586, i686, etc.
+        return "x86_32"
+    else:
+        print("Unsupported CPU architecture: " + host_machine)
+        print("Falling back to x86_64.")
+        return "x86_64"