Browse Source

SCons: Fix build with `p` alias or platform auto-detection

Fixes a pre-existing bug that #44433 exposed.

It's pretty hacky, but we use `platform` in `env` both as an optional command
line option (instead it can be autodetected, or passed via the `p` alias, and
on Linux it might be overridden if you pass one of the convenience alias
values), and as the reference value for what platform we're building on.

Thus we override `env_base["platform"]` with the autodetected or validated
platform, but any call to `opts.Update(env_base)` overrides it with the
original command line option... causing e.g. #44448.

The proper fix would be to refactor all this so that we don't reuse
`env["platform"]` for platform detection (it could instead be e.g.
`env.platform` as a member variable which holds the validated value),
but for now I'm tapering over the immediate breakage.

Fixes #44448 and other breakages induced by #44433.

(cherry picked from commit 8f660393feb603a9a7364c1f8e00d5a3b204419b)
Rémi Verschelde 4 years ago
parent
commit
ee77567cac
1 changed files with 51 additions and 47 deletions
  1. 51 47
      SConstruct

+ 51 - 47
SConstruct

@@ -17,6 +17,7 @@ from platform_methods import run_in_subprocess
 # scan possible build platforms
 
 platform_list = []  # list of platforms
+platform_opts = {}  # options for each platform
 platform_flags = {}  # flags for each platform
 
 active_platforms = []
@@ -43,6 +44,7 @@ for x in sorted(glob.glob("platform/*")):
         x = x.replace("platform/", "")  # rest of world
         x = x.replace("platform\\", "")  # win32
         platform_list += [x]
+        platform_opts[x] = detect.get_opts()
         platform_flags[x] = detect.get_flags()
     sys.path.remove(tmppath)
     sys.modules.pop("detect")
@@ -172,10 +174,55 @@ opts.Add("CFLAGS", "Custom flags for the C compiler")
 opts.Add("CXXFLAGS", "Custom flags for the C++ compiler")
 opts.Add("LINKFLAGS", "Custom flags for the linker")
 
-# Update the environment now as the "custom_modules" option may be
-# defined in a file rather than specified via the command line.
+# Update the environment to have all above options defined
+# in following code (especially platform and custom_modules).
 opts.Update(env_base)
 
+# Platform selection: validate input, and add options.
+
+selected_platform = ""
+
+if env_base["platform"] != "":
+    selected_platform = env_base["platform"]
+elif env_base["p"] != "":
+    selected_platform = env_base["p"]
+else:
+    # Missing `platform` argument, try to detect platform automatically
+    if sys.platform.startswith("linux"):
+        selected_platform = "x11"
+    elif sys.platform == "darwin":
+        selected_platform = "osx"
+    elif sys.platform == "win32":
+        selected_platform = "windows"
+    else:
+        print("Could not detect platform automatically. Supported platforms:")
+        for x in platform_list:
+            print("\t" + x)
+        print("\nPlease run SCons again and select a valid platform: platform=<string>")
+
+    if selected_platform != "":
+        print("Automatically detected platform: " + selected_platform)
+
+if selected_platform in ["linux", "bsd", "linuxbsd"]:
+    if selected_platform == "linuxbsd":
+        # Alias for forward compatibility.
+        print('Platform "linuxbsd" is still called "x11" in Godot 3.2.x. Building for platform "x11".')
+    # Alias for convenience.
+    selected_platform = "x11"
+
+# Make sure to update this to the found, valid platform as it's used through the buildsystem as the reference.
+# It should always be re-set after calling `opts.Update()` otherwise it uses the original input value.
+env_base["platform"] = selected_platform
+
+# Add platform-specific options.
+if selected_platform in platform_opts:
+    for opt in platform_opts[selected_platform]:
+        opts.Add(opt)
+
+# Update the environment to take platform-specific options into account.
+opts.Update(env_base)
+env_base["platform"] = selected_platform  # Must always be re-set after calling opts.Update().
+
 # Detect modules.
 modules_detected = OrderedDict()
 module_search_paths = ["modules"]  # Built-in path.
@@ -214,6 +261,8 @@ methods.write_modules(modules_detected)
 
 # Update the environment again after all the module options are added.
 opts.Update(env_base)
+env_base["platform"] = selected_platform  # Must always be re-set after calling opts.Update().
+Help(opts.GenerateHelpText(env_base))
 
 # add default include paths
 
@@ -245,52 +294,11 @@ if env_base["no_editor_splash"]:
 if not env_base["deprecated"]:
     env_base.Append(CPPDEFINES=["DISABLE_DEPRECATED"])
 
-env_base.platforms = {}
-
-selected_platform = ""
-
-if env_base["platform"] != "":
-    selected_platform = env_base["platform"]
-elif env_base["p"] != "":
-    selected_platform = env_base["p"]
-    env_base["platform"] = selected_platform
-else:
-    # Missing `platform` argument, try to detect platform automatically
-    if sys.platform.startswith("linux"):
-        selected_platform = "x11"
-    elif sys.platform == "darwin":
-        selected_platform = "osx"
-    elif sys.platform == "win32":
-        selected_platform = "windows"
-    else:
-        print("Could not detect platform automatically. Supported platforms:")
-        for x in platform_list:
-            print("\t" + x)
-        print("\nPlease run SCons again and select a valid platform: platform=<string>")
-
-    if selected_platform != "":
-        print("Automatically detected platform: " + selected_platform)
-        env_base["platform"] = selected_platform
-
-if selected_platform in ["linux", "bsd", "linuxbsd"]:
-    if selected_platform == "linuxbsd":
-        # Alias for forward compatibility.
-        print('Platform "linuxbsd" is still called "x11" in Godot 3.2.x. Building for platform "x11".')
-    # Alias for convenience.
-    selected_platform = "x11"
-    env_base["platform"] = selected_platform
-
 if selected_platform in platform_list:
     tmppath = "./platform/" + selected_platform
     sys.path.insert(0, tmppath)
     import detect
 
-    # Add platform-specific options.
-    for opt in detect.get_opts():
-        opts.Add(opt)
-    opts.Update(env_base)
-    Help(opts.GenerateHelpText(env_base))
-
     if "create" in dir(detect):
         env = detect.create(env_base)
     else:
@@ -623,10 +631,6 @@ elif selected_platform != "":
     else:
         sys.exit(255)
 
-else:
-    # Update help to include options.
-    Help(opts.GenerateHelpText(env_base))
-
 # The following only makes sense when the 'env' is defined, and assumes it is.
 if "env" in locals():
     methods.show_progress(env)