SCons: Refactor color output implementation

This commit is contained in:
Thaddeus Crews 2025-01-07 15:55:17 -06:00
parent d2ada64a03
commit a29294fddc
No known key found for this signature in database
GPG Key ID: 62181B86FE9E5D84
11 changed files with 211 additions and 304 deletions

View File

@ -5,12 +5,10 @@ EnsureSConsVersion(4, 0)
EnsurePythonVersion(3, 8)
# System
import atexit
import glob
import os
import pickle
import sys
import time
from collections import OrderedDict
from importlib.util import module_from_spec, spec_from_file_location
from types import ModuleType
@ -52,13 +50,14 @@ _helper_module("platform_methods", "platform_methods.py")
_helper_module("version", "version.py")
_helper_module("core.core_builders", "core/core_builders.py")
_helper_module("main.main_builders", "main/main_builders.py")
_helper_module("misc.utility.color", "misc/utility/color.py")
# Local
import gles3_builders
import glsl_builders
import methods
import scu_builders
from methods import Ansi, print_error, print_info, print_warning
from misc.utility.color import STDERR_COLOR, print_error, print_info, print_warning
from platform_methods import architecture_aliases, architectures, compatibility_platform_aliases
if ARGUMENTS.get("target", "editor") == "editor":
@ -74,8 +73,6 @@ platform_doc_class_path = {}
platform_exporters = []
platform_apis = []
time_at_start = time.time()
for x in sorted(glob.glob("platform/*")):
if not os.path.isdir(x) or not os.path.exists(x + "/detect.py"):
continue
@ -702,6 +699,14 @@ if env["arch"] == "x86_32":
else:
env.Append(CCFLAGS=["-msse2"])
# Explicitly specify colored output.
if methods.using_gcc(env):
env.AppendUnique(CCFLAGS=["-fdiagnostics-color" if STDERR_COLOR else "-fno-diagnostics-color"])
elif methods.using_clang(env) or methods.using_emcc(env):
env.AppendUnique(CCFLAGS=["-fcolor-diagnostics" if STDERR_COLOR else "-fno-color-diagnostics"])
if sys.platform == "win32":
env.AppendUnique(CCFLAGS=["-fansi-escape-codes"])
# Set optimize and debug_symbols flags.
# "custom" means do nothing and let users set their own optimization flags.
# Needs to happen after configure to have `env.msvc` defined.
@ -1086,30 +1091,5 @@ methods.show_progress(env)
# TODO: replace this with `env.Dump(format="json")`
# once we start requiring SCons 4.0 as min version.
methods.dump(env)
def print_elapsed_time():
elapsed_time_sec = round(time.time() - time_at_start, 2)
time_centiseconds = round((elapsed_time_sec % 1) * 100)
print(
"{}[Time elapsed: {}.{:02}]{}".format(
Ansi.GRAY,
time.strftime("%H:%M:%S", time.gmtime(elapsed_time_sec)),
time_centiseconds,
Ansi.RESET,
)
)
atexit.register(print_elapsed_time)
def purge_flaky_files():
paths_to_keep = [env["ninja_file"]]
for build_failure in GetBuildFailures():
path = build_failure.node.path
if os.path.isfile(path) and path not in paths_to_keep:
os.remove(path)
atexit.register(purge_flaky_files)
methods.prepare_purge(env)
methods.prepare_timer()

View File

@ -10,14 +10,14 @@ from typing import Dict, List, Set
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../"))
from methods import COLOR_SUPPORTED, Ansi, toggle_color
from misc.utility.color import STDOUT_COLOR, Ansi, toggle_color
################################################################################
# Config #
################################################################################
flags = {
"c": COLOR_SUPPORTED,
"c": STDOUT_COLOR,
"b": False,
"g": False,
"s": False,
@ -330,7 +330,8 @@ if flags["u"]:
table_column_names.append("Docs URL")
table_columns.append("url")
toggle_color(flags["c"])
if flags["c"]:
toggle_color(True)
################################################################################
# Help #

View File

@ -13,7 +13,7 @@ from typing import Any, Dict, List, Optional, TextIO, Tuple, Union
sys.path.insert(0, root_directory := os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../"))
import version
from methods import Ansi, toggle_color
from misc.utility.color import Ansi, toggle_color
# $DOCS_URL/path/to/page.html(#fragment-tag)
GODOT_DOCS_PATTERN = re.compile(r"^\$DOCS_URL/(.*)\.html(#.*)?$")
@ -697,7 +697,8 @@ def main() -> None:
)
args = parser.parse_args()
toggle_color(args.color)
if args.color:
toggle_color(True)
# Retrieve heading translations for the given language.
if not args.dry_run and args.lang != "en":

View File

@ -7,125 +7,16 @@ import re
import subprocess
import sys
from collections import OrderedDict
from enum import Enum
from io import StringIO, TextIOWrapper
from pathlib import Path
from typing import Final, Generator, List, Optional, Union, cast
from typing import Generator, List, Optional, Union, cast
from misc.utility.color import print_error, print_info, print_warning
# Get the "Godot" folder name ahead of time
base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/"
base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
################################################################################
# COLORIZE
################################################################################
IS_CI: Final[bool] = bool(os.environ.get("CI"))
IS_TTY: Final[bool] = bool(sys.stdout.isatty())
def _color_supported() -> bool:
"""
Enables ANSI escape code support on Windows 10 and later (for colored console output).
See here: https://github.com/python/cpython/issues/73245
"""
if sys.platform == "win32" and IS_TTY:
try:
from ctypes import WinError, byref, windll # type: ignore
from ctypes.wintypes import DWORD # type: ignore
stdout_handle = windll.kernel32.GetStdHandle(DWORD(-11))
mode = DWORD(0)
if not windll.kernel32.GetConsoleMode(stdout_handle, byref(mode)):
raise WinError()
mode = DWORD(mode.value | 4)
if not windll.kernel32.SetConsoleMode(stdout_handle, mode):
raise WinError()
except (TypeError, OSError) as e:
print(f"Failed to enable ANSI escape code support, disabling color output.\n{e}", file=sys.stderr)
return False
return IS_TTY or IS_CI
# Colors are disabled in non-TTY environments such as pipes. This means
# that if output is redirected to a file, it won't contain color codes.
# Colors are always enabled on continuous integration.
COLOR_SUPPORTED: Final[bool] = _color_supported()
_can_color: bool = COLOR_SUPPORTED
def toggle_color(value: Optional[bool] = None) -> None:
"""
Explicitly toggle color codes, regardless of support.
- `value`: An optional boolean to explicitly set the color
state instead of toggling.
"""
global _can_color
_can_color = value if value is not None else not _can_color
class Ansi(Enum):
"""
Enum class for adding ansi colorcodes directly into strings.
Automatically converts values to strings representing their
internal value, or an empty string in a non-colorized scope.
"""
RESET = "\x1b[0m"
BOLD = "\x1b[1m"
DIM = "\x1b[2m"
ITALIC = "\x1b[3m"
UNDERLINE = "\x1b[4m"
STRIKETHROUGH = "\x1b[9m"
REGULAR = "\x1b[22;23;24;29m"
BLACK = "\x1b[30m"
RED = "\x1b[31m"
GREEN = "\x1b[32m"
YELLOW = "\x1b[33m"
BLUE = "\x1b[34m"
MAGENTA = "\x1b[35m"
CYAN = "\x1b[36m"
WHITE = "\x1b[37m"
LIGHT_BLACK = "\x1b[90m"
LIGHT_RED = "\x1b[91m"
LIGHT_GREEN = "\x1b[92m"
LIGHT_YELLOW = "\x1b[93m"
LIGHT_BLUE = "\x1b[94m"
LIGHT_MAGENTA = "\x1b[95m"
LIGHT_CYAN = "\x1b[96m"
LIGHT_WHITE = "\x1b[97m"
GRAY = LIGHT_BLACK if IS_CI else BLACK
"""
Special case. GitHub Actions doesn't convert `BLACK` to gray as expected, but does convert `LIGHT_BLACK`.
By implementing `GRAY`, we handle both cases dynamically, while still allowing for explicit values if desired.
"""
def __str__(self) -> str:
global _can_color
return str(self.value) if _can_color else ""
def print_info(*values: object) -> None:
"""Prints a informational message with formatting."""
print(f"{Ansi.GRAY}{Ansi.BOLD}INFO:{Ansi.REGULAR}", *values, Ansi.RESET)
def print_warning(*values: object) -> None:
"""Prints a warning message with formatting."""
print(f"{Ansi.YELLOW}{Ansi.BOLD}WARNING:{Ansi.REGULAR}", *values, Ansi.RESET, file=sys.stderr)
def print_error(*values: object) -> None:
"""Prints an error message with formatting."""
print(f"{Ansi.RED}{Ansi.BOLD}ERROR:{Ansi.REGULAR}", *values, Ansi.RESET, file=sys.stderr)
# Listing all the folders we have converted
# for SCU in scu_builders.py
_scu_folders = set()
@ -505,6 +396,8 @@ def use_windows_spawn_fix(self, platform=None):
def no_verbose(env):
from misc.utility.color import Ansi
colors = [Ansi.BLUE, Ansi.BOLD, Ansi.REGULAR, Ansi.RESET]
# There is a space before "..." to ensure that source file names can be
@ -875,7 +768,7 @@ def show_progress(env):
# Progress reporting is not available in non-TTY environments since it
# messes with the output (for example, when writing to a file).
self.display = cast(bool, self.max and env["progress"] and IS_TTY)
self.display = cast(bool, self.max and env["progress"] and sys.stdout.isatty())
if self.display and not self.max:
print_info("Performing initial build, progress percentage unavailable!")
@ -1019,6 +912,31 @@ def prepare_cache(env) -> None:
atexit.register(clean_cache, cache_path, cache_limit, env["verbose"])
def prepare_purge(env):
from SCons.Script.Main import GetBuildFailures
def purge_flaky_files():
paths_to_keep = [env["ninja_file"]]
for build_failure in GetBuildFailures():
path = build_failure.node.path
if os.path.isfile(path) and path not in paths_to_keep:
os.remove(path)
atexit.register(purge_flaky_files)
def prepare_timer():
import time
def print_elapsed_time(time_at_start: float):
time_elapsed = time.time() - time_at_start
time_formatted = time.strftime("%H:%M:%S", time.gmtime(time_elapsed))
time_centiseconds = round((time_elapsed % 1) * 100)
print_info(f"Time elapsed: {time_formatted}.{time_centiseconds}")
atexit.register(print_elapsed_time, time.time())
def dump(env):
# Dumps latest build information for debugging purposes and external tools.
from json import dump

View File

@ -8,7 +8,7 @@ import urllib.request
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../"))
from methods import Ansi
from misc.utility.color import Ansi
# Base Godot dependencies path
# If cross-compiling (no LOCALAPPDATA), we install in `bin`

130
misc/utility/color.py Normal file
View File

@ -0,0 +1,130 @@
from __future__ import annotations
import os
import sys
from enum import Enum
from typing import Final
# Colors are disabled in non-TTY environments such as pipes. This means if output is redirected
# to a file, it won't contain color codes. Colors are always enabled on continuous integration.
IS_CI: Final[bool] = bool(os.environ.get("CI"))
STDOUT_TTY: Final[bool] = bool(sys.stdout.isatty())
STDERR_TTY: Final[bool] = bool(sys.stderr.isatty())
def _color_supported(stdout: bool) -> bool:
"""
Validates if the current environment supports colored output. Attempts to enable ANSI escape
code support on Windows 10 and later.
"""
if IS_CI:
return True
if sys.platform != "win32":
return STDOUT_TTY if stdout else STDERR_TTY
else:
from ctypes import POINTER, WINFUNCTYPE, WinError, windll
from ctypes.wintypes import BOOL, DWORD, HANDLE
STD_HANDLE = -11 if stdout else -12
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
def err_handler(result, func, args):
if not result:
raise WinError()
return args
GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(("GetStdHandle", windll.kernel32), ((1, "nStdHandle"),))
GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))(
("GetConsoleMode", windll.kernel32),
((1, "hConsoleHandle"), (2, "lpMode")),
)
GetConsoleMode.errcheck = err_handler
SetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, DWORD)(
("SetConsoleMode", windll.kernel32),
((1, "hConsoleHandle"), (1, "dwMode")),
)
SetConsoleMode.errcheck = err_handler
try:
handle = GetStdHandle(STD_HANDLE)
flags = GetConsoleMode(handle)
SetConsoleMode(handle, flags | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
return True
except OSError:
return False
STDOUT_COLOR: Final[bool] = _color_supported(True)
STDERR_COLOR: Final[bool] = _color_supported(False)
_stdout_override: bool = STDOUT_COLOR
_stderr_override: bool = STDERR_COLOR
def toggle_color(stdout: bool, value: bool | None = None) -> None:
"""
Explicitly toggle color codes, regardless of support.
- `stdout`: A boolean to choose the output stream. `True` for stdout, `False` for stderr.
- `value`: An optional boolean to explicitly set the color state instead of toggling.
"""
if stdout:
global _stdout_override
_stdout_override = value if value is not None else not _stdout_override
else:
global _stderr_override
_stderr_override = value if value is not None else not _stderr_override
class Ansi(Enum):
"""
Enum class for adding ansi codepoints directly into strings. Automatically converts values to
strings representing their internal value.
"""
RESET = "\x1b[0m"
BOLD = "\x1b[1m"
DIM = "\x1b[2m"
ITALIC = "\x1b[3m"
UNDERLINE = "\x1b[4m"
STRIKETHROUGH = "\x1b[9m"
REGULAR = "\x1b[22;23;24;29m"
BLACK = "\x1b[30m"
RED = "\x1b[31m"
GREEN = "\x1b[32m"
YELLOW = "\x1b[33m"
BLUE = "\x1b[34m"
MAGENTA = "\x1b[35m"
CYAN = "\x1b[36m"
WHITE = "\x1b[37m"
GRAY = "\x1b[90m"
def __str__(self) -> str:
return self.value
def print_info(*values: object) -> None:
"""Prints a informational message with formatting."""
if _stdout_override:
print(f"{Ansi.GRAY}{Ansi.BOLD}INFO:{Ansi.REGULAR}", *values, Ansi.RESET)
else:
print(*values)
def print_warning(*values: object) -> None:
"""Prints a warning message with formatting."""
if _stderr_override:
print(f"{Ansi.YELLOW}{Ansi.BOLD}WARNING:{Ansi.REGULAR}", *values, Ansi.RESET, file=sys.stderr)
else:
print(*values, file=sys.stderr)
def print_error(*values: object) -> None:
"""Prints an error message with formatting."""
if _stderr_override:
print(f"{Ansi.RED}{Ansi.BOLD}ERROR:{Ansi.REGULAR}", *values, Ansi.RESET, file=sys.stderr)
else:
print(*values, file=sys.stderr)

View File

@ -1,14 +1,8 @@
#!/usr/bin/env python
import atexit
import time
from typing import TYPE_CHECKING
# ruff: noqa: F821
import methods
if TYPE_CHECKING:
from misc.utility.scons_hints import *
# For the reference:
# - CCFLAGS are compilation flags shared between C and C++
# - CFLAGS are for C-specific compilation flags
@ -17,8 +11,6 @@ if TYPE_CHECKING:
# - CPPDEFINES are for pre-processor defines
# - LINKFLAGS are for linking flags
time_at_start = time.time()
env = SConscript("./godot-cpp/SConstruct")
env.__class__.disable_warnings = methods.disable_warnings
@ -33,9 +25,6 @@ opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", Fa
opts.Update(env)
if not env["verbose"]:
methods.no_verbose(env)
if env["platform"] == "windows" and not env["use_mingw"]:
env.AppendUnique(CCFLAGS=["/utf-8"]) # Force to use Unicode encoding.
@ -767,18 +756,4 @@ else:
Default(library)
def print_elapsed_time():
elapsed_time_sec = round(time.time() - time_at_start, 2)
time_centiseconds = round((elapsed_time_sec % 1) * 100)
print(
"{}[Time elapsed: {}.{:02}]{}".format(
methods.Ansi.GRAY,
time.strftime("%H:%M:%S", time.gmtime(elapsed_time_sec)),
time_centiseconds,
methods.Ansi.RESET,
)
)
atexit.register(print_elapsed_time)
methods.prepare_timer()

View File

@ -1,41 +1,3 @@
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../"))
from methods import Ansi
def no_verbose(env):
colors = [Ansi.BLUE, Ansi.BOLD, Ansi.REGULAR, Ansi.RESET]
# There is a space before "..." to ensure that source file names can be
# Ctrl + clicked in the VS Code terminal.
compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(*colors)
java_compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(*colors)
compile_shared_source_message = "{}Compiling shared {}$SOURCE{} ...{}".format(*colors)
link_program_message = "{}Linking Program {}$TARGET{} ...{}".format(*colors)
link_library_message = "{}Linking Static Library {}$TARGET{} ...{}".format(*colors)
ranlib_library_message = "{}Ranlib Library {}$TARGET{} ...{}".format(*colors)
link_shared_library_message = "{}Linking Shared Library {}$TARGET{} ...{}".format(*colors)
java_library_message = "{}Creating Java Archive {}$TARGET{} ...{}".format(*colors)
compiled_resource_message = "{}Creating Compiled Resource {}$TARGET{} ...{}".format(*colors)
generated_file_message = "{}Generating {}$TARGET{} ...{}".format(*colors)
env["CXXCOMSTR"] = compile_source_message
env["CCCOMSTR"] = compile_source_message
env["SHCCCOMSTR"] = compile_shared_source_message
env["SHCXXCOMSTR"] = compile_shared_source_message
env["ARCOMSTR"] = link_library_message
env["RANLIBCOMSTR"] = ranlib_library_message
env["SHLINKCOMSTR"] = link_shared_library_message
env["LINKCOMSTR"] = link_program_message
env["JARCOMSTR"] = java_library_message
env["JAVACCOMSTR"] = java_compile_source_message
env["RCCOMSTR"] = compiled_resource_message
env["GENCOMSTR"] = generated_file_message
def disable_warnings(self):
# 'self' is the environment
if self["platform"] == "windows" and not self["use_mingw"]:
@ -50,6 +12,19 @@ def disable_warnings(self):
self.AppendUnique(CCFLAGS=["-w"])
def prepare_timer():
import atexit
import time
def print_elapsed_time(time_at_start: float):
time_elapsed = time.time() - time_at_start
time_formatted = time.strftime("%H:%M:%S", time.gmtime(time_elapsed))
time_centiseconds = round((time_elapsed % 1) * 100)
print(f"[Time elapsed: {time_formatted}.{time_centiseconds}]")
atexit.register(print_elapsed_time, time.time())
def make_icu_data(target, source, env):
dst = target[0].srcnode().abspath
with open(dst, "w", encoding="utf-8", newline="\n") as g:
@ -75,6 +50,8 @@ def make_icu_data(target, source, env):
def write_macos_plist(target, binary_name, identifier, name):
import os
os.makedirs(f"{target}/Resource/", exist_ok=True)
with open(f"{target}/Resource/Info.plist", "w", encoding="utf-8", newline="\n") as f:
f.write(f"""\

View File

@ -1,14 +1,8 @@
#!/usr/bin/env python
import atexit
import time
from typing import TYPE_CHECKING
# ruff: noqa: F821
import methods
if TYPE_CHECKING:
from misc.utility.scons_hints import *
# For the reference:
# - CCFLAGS are compilation flags shared between C and C++
# - CFLAGS are for C-specific compilation flags
@ -17,8 +11,6 @@ if TYPE_CHECKING:
# - CPPDEFINES are for pre-processor defines
# - LINKFLAGS are for linking flags
time_at_start = time.time()
env = SConscript("./godot-cpp/SConstruct")
env.__class__.disable_warnings = methods.disable_warnings
@ -31,9 +23,6 @@ opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", Fa
opts.Update(env)
if not env["verbose"]:
methods.no_verbose(env)
# ThorVG
if env["thorvg_enabled"] and env["freetype_enabled"]:
env_tvg = env.Clone()
@ -313,18 +302,4 @@ else:
Default(library)
def print_elapsed_time():
elapsed_time_sec = round(time.time() - time_at_start, 2)
time_centiseconds = round((elapsed_time_sec % 1) * 100)
print(
"{}[Time elapsed: {}.{:02}]{}".format(
methods.Ansi.GRAY,
time.strftime("%H:%M:%S", time.gmtime(elapsed_time_sec)),
time_centiseconds,
methods.Ansi.RESET,
)
)
atexit.register(print_elapsed_time)
methods.prepare_timer()

View File

@ -1,41 +1,3 @@
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../"))
from methods import Ansi
def no_verbose(env):
colors = [Ansi.BLUE, Ansi.BOLD, Ansi.REGULAR, Ansi.RESET]
# There is a space before "..." to ensure that source file names can be
# Ctrl + clicked in the VS Code terminal.
compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(*colors)
java_compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(*colors)
compile_shared_source_message = "{}Compiling shared {}$SOURCE{} ...{}".format(*colors)
link_program_message = "{}Linking Program {}$TARGET{} ...{}".format(*colors)
link_library_message = "{}Linking Static Library {}$TARGET{} ...{}".format(*colors)
ranlib_library_message = "{}Ranlib Library {}$TARGET{} ...{}".format(*colors)
link_shared_library_message = "{}Linking Shared Library {}$TARGET{} ...{}".format(*colors)
java_library_message = "{}Creating Java Archive {}$TARGET{} ...{}".format(*colors)
compiled_resource_message = "{}Creating Compiled Resource {}$TARGET{} ...{}".format(*colors)
generated_file_message = "{}Generating {}$TARGET{} ...{}".format(*colors)
env["CXXCOMSTR"] = compile_source_message
env["CCCOMSTR"] = compile_source_message
env["SHCCCOMSTR"] = compile_shared_source_message
env["SHCXXCOMSTR"] = compile_shared_source_message
env["ARCOMSTR"] = link_library_message
env["RANLIBCOMSTR"] = ranlib_library_message
env["SHLINKCOMSTR"] = link_shared_library_message
env["LINKCOMSTR"] = link_program_message
env["JARCOMSTR"] = java_library_message
env["JAVACCOMSTR"] = java_compile_source_message
env["RCCOMSTR"] = compiled_resource_message
env["GENCOMSTR"] = generated_file_message
def disable_warnings(self):
# 'self' is the environment
if self["platform"] == "windows" and not self["use_mingw"]:
@ -50,31 +12,22 @@ def disable_warnings(self):
self.AppendUnique(CCFLAGS=["-w"])
def make_icu_data(target, source, env):
dst = target[0].srcnode().abspath
with open(dst, "w", encoding="utf-8", newline="\n") as g:
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("/* (C) 2016 and later: Unicode, Inc. and others. */\n")
g.write("/* License & terms of use: https://www.unicode.org/copyright.html */\n")
g.write("#ifndef _ICU_DATA_H\n")
g.write("#define _ICU_DATA_H\n")
g.write('#include "unicode/utypes.h"\n')
g.write('#include "unicode/udata.h"\n')
g.write('#include "unicode/uversion.h"\n')
def prepare_timer():
import atexit
import time
with open(source[0].srcnode().abspath, "rb") as f:
buf = f.read()
def print_elapsed_time(time_at_start: float):
time_elapsed = time.time() - time_at_start
time_formatted = time.strftime("%H:%M:%S", time.gmtime(time_elapsed))
time_centiseconds = round((time_elapsed % 1) * 100)
print(f"[Time elapsed: {time_formatted}.{time_centiseconds}]")
g.write('extern "C" U_EXPORT const size_t U_ICUDATA_SIZE = ' + str(len(buf)) + ";\n")
g.write('extern "C" U_EXPORT const unsigned char U_ICUDATA_ENTRY_POINT[] = {\n')
for i in range(len(buf)):
g.write("\t" + str(buf[i]) + ",\n")
g.write("};\n")
g.write("#endif")
atexit.register(print_elapsed_time, time.time())
def write_macos_plist(target, binary_name, identifier, name):
import os
os.makedirs(f"{target}/Resource/", exist_ok=True)
with open(f"{target}/Resource/Info.plist", "w", encoding="utf-8", newline="\n") as f:
f.write(f"""\

View File

@ -812,9 +812,6 @@ def configure_mingw(env: "SConsEnvironment"):
env.Append(CCFLAGS=san_flags)
env.Append(LINKFLAGS=san_flags)
if env["use_llvm"] and os.name == "nt" and methods._can_color:
env.Append(CCFLAGS=["$(-fansi-escape-codes$)", "$(-fcolor-diagnostics$)"])
if get_is_ar_thin_supported(env):
env.Append(ARFLAGS=["--thin"])