From 7c743122172e7f32f184081f743346ad6ac5b332 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= <rverschelde@gmail.com>
Date: Tue, 2 Jun 2020 13:16:42 +0200
Subject: [PATCH] SCons: Validate dependencies for linked multimedia modules

This is still a bit hacky and eventually we should rework the way we handle
optional dependencies (especially with regard to builtin/system libs), but
it's a simple first step.

Fixes #39219.
---
 SConstruct               | 15 +++++++--------
 methods.py               | 24 ++++++++++++++++++++++++
 modules/opus/config.py   |  2 +-
 modules/theora/config.py |  2 +-
 modules/vorbis/config.py |  2 +-
 modules/webm/config.py   |  5 ++++-
 6 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/SConstruct b/SConstruct
index 27e6c5f2d35..b424363dc80 100644
--- a/SConstruct
+++ b/SConstruct
@@ -86,6 +86,7 @@ env_base.__class__.add_library = methods.add_library
 env_base.__class__.add_program = methods.add_program
 env_base.__class__.CommandNoCache = methods.CommandNoCache
 env_base.__class__.disable_warnings = methods.disable_warnings
+env_base.__class__.module_check_dependencies = methods.module_check_dependencies
 
 env_base["x86_libtheora_opt_gcc"] = False
 env_base["x86_libtheora_opt_vc"] = False
@@ -607,14 +608,12 @@ if selected_platform in platform_list:
         env.Append(CPPDEFINES=["MINIZIP_ENABLED"])
 
     editor_module_list = ["regex"]
-    for x in editor_module_list:
-        if not env["module_" + x + "_enabled"]:
-            if env["tools"]:
-                print(
-                    "Build option 'module_" + x + "_enabled=no' cannot be used with 'tools=yes' (editor), "
-                    "only with 'tools=no' (export template)."
-                )
-                Exit(255)
+    if env["tools"] and not env.module_check_dependencies("tools", editor_module_list):
+        print(
+            "Build option 'module_" + x + "_enabled=no' cannot be used with 'tools=yes' (editor), "
+            "only with 'tools=no' (export template)."
+        )
+        Exit(255)
 
     if not env["verbose"]:
         methods.no_verbose(sys, env)
diff --git a/methods.py b/methods.py
index c1245cd95a4..756db19e9a9 100644
--- a/methods.py
+++ b/methods.py
@@ -231,6 +231,30 @@ def disable_module(self):
     self.disabled_modules.append(self.current_module)
 
 
+def module_check_dependencies(self, module, dependencies):
+    """
+    Checks if module dependencies are enabled for a given module,
+    and prints a warning if they aren't.
+    Meant to be used in module `can_build` methods.
+    Returns a boolean (True if dependencies are satisfied).
+    """
+    missing_deps = []
+    for dep in dependencies:
+        opt = "module_{}_enabled".format(dep)
+        if not opt in self or not self[opt]:
+            missing_deps.append(dep)
+
+    if missing_deps != []:
+        print(
+            "Disabling '{}' module as the following dependencies are not satisfied: {}".format(
+                module, ", ".join(missing_deps)
+            )
+        )
+        return False
+    else:
+        return True
+
+
 def use_windows_spawn_fix(self, platform=None):
 
     if os.name != "nt":
diff --git a/modules/opus/config.py b/modules/opus/config.py
index d22f9454ed2..9ff7b2dece5 100644
--- a/modules/opus/config.py
+++ b/modules/opus/config.py
@@ -1,5 +1,5 @@
 def can_build(env, platform):
-    return True
+    return env.module_check_dependencies("opus", ["ogg"])
 
 
 def configure(env):
diff --git a/modules/theora/config.py b/modules/theora/config.py
index 413acce2df8..b063ed51f97 100644
--- a/modules/theora/config.py
+++ b/modules/theora/config.py
@@ -1,5 +1,5 @@
 def can_build(env, platform):
-    return True
+    return env.module_check_dependencies("theora", ["ogg", "vorbis"])
 
 
 def configure(env):
diff --git a/modules/vorbis/config.py b/modules/vorbis/config.py
index d22f9454ed2..8a384e30668 100644
--- a/modules/vorbis/config.py
+++ b/modules/vorbis/config.py
@@ -1,5 +1,5 @@
 def can_build(env, platform):
-    return True
+    return env.module_check_dependencies("vorbis", ["ogg"])
 
 
 def configure(env):
diff --git a/modules/webm/config.py b/modules/webm/config.py
index 93b49d177ad..99f8ace114f 100644
--- a/modules/webm/config.py
+++ b/modules/webm/config.py
@@ -1,5 +1,8 @@
 def can_build(env, platform):
-    return platform not in ["iphone"]
+    if platform in ["iphone"]:
+        return False
+
+    return env.module_check_dependencies("webm", ["ogg", "opus", "vorbis"])
 
 
 def configure(env):