Переглянути джерело

Merge pull request #90551 from Repiteo/scons/silence-msvc-for-real

SCons: Silence MSVC output bloat without hiding errors
Rémi Verschelde 1 рік тому
батько
коміт
cabb3ca4ef
1 змінених файлів з 24 додано та 10 видалено
  1. 24 10
      platform/windows/detect.py

+ 24 - 10
platform/windows/detect.py

@@ -202,9 +202,7 @@ def get_opts():
         BoolVariable("use_asan", "Use address sanitizer (ASAN)", False),
         BoolVariable("debug_crt", "Compile with MSVC's debug CRT (/MDd)", False),
         BoolVariable("incremental_link", "Use MSVC incremental linking. May increase or decrease build times.", False),
-        BoolVariable(
-            "silence_msvc", "Silence MSVC's stdout to decrease output log bloat. May hide error messages.", False
-        ),
+        BoolVariable("silence_msvc", "Silence MSVC's cl/link stdout bloat, redirecting any errors to stderr.", True),
         ("angle_libs", "Path to the ANGLE static libraries", ""),
         # Direct3D 12 support.
         (
@@ -398,16 +396,32 @@ def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config):
     env["MAXLINELENGTH"] = 8192  # Windows Vista and beyond, so always applicable.
 
     if env["silence_msvc"]:
-        env.Prepend(CCFLAGS=[">", "NUL"])
-        env.Prepend(LINKFLAGS=[">", "NUL"])
+        from tempfile import mkstemp
+
+        old_spawn = env["SPAWN"]
+
+        def spawn_capture(sh, escape, cmd, args, env):
+            # We only care about cl/link, process everything else as normal.
+            if args[0] not in ["cl", "link"]:
+                return old_spawn(sh, escape, cmd, args, env)
 
-        # "> NUL" fails if using a tempfile, circumvent by removing the argument altogether.
-        old_esc_func = env["TEMPFILEARGESCFUNC"]
+            tmp_stdout, tmp_stdout_name = mkstemp()
+            os.close(tmp_stdout)
+            args.append(f">{tmp_stdout_name}")
+            ret = old_spawn(sh, escape, cmd, args, env)
+
+            try:
+                with open(tmp_stdout_name, "rt", encoding=sys.stdout.encoding) as tmp_stdout:
+                    # First line is always bloat, subsequent lines are always errors. This filter sends
+                    # either just the errors to stderr, or an empty string to effectively do nothing.
+                    sys.stderr.write("".join(tmp_stdout.readlines()[1:]))
+                os.remove(tmp_stdout_name)
+            except OSError:
+                pass
 
-        def trim_nul(arg):
-            return "" if arg in [">", "NUL"] else old_esc_func(arg)
+            return ret
 
-        env["TEMPFILEARGESCFUNC"] = trim_nul
+        env["SPAWN"] = spawn_capture
 
     if env["debug_crt"]:
         # Always use dynamic runtime, static debug CRT breaks thread_local.