diff --git a/SConstruct b/SConstruct index 470830d8eb7..442daea6d97 100644 --- a/SConstruct +++ b/SConstruct @@ -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() diff --git a/doc/tools/doc_status.py b/doc/tools/doc_status.py index dc52a38bddd..db2b19447b5 100755 --- a/doc/tools/doc_status.py +++ b/doc/tools/doc_status.py @@ -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 # diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py index a10b5d6e782..adb7500528b 100755 --- a/doc/tools/make_rst.py +++ b/doc/tools/make_rst.py @@ -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": diff --git a/methods.py b/methods.py index 4351584c6b6..fee268609d7 100644 --- a/methods.py +++ b/methods.py @@ -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 diff --git a/misc/scripts/install_d3d12_sdk_windows.py b/misc/scripts/install_d3d12_sdk_windows.py index fa9ce780513..26e5181d9a0 100644 --- a/misc/scripts/install_d3d12_sdk_windows.py +++ b/misc/scripts/install_d3d12_sdk_windows.py @@ -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` diff --git a/misc/utility/color.py b/misc/utility/color.py new file mode 100644 index 00000000000..ae392dd8470 --- /dev/null +++ b/misc/utility/color.py @@ -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) diff --git a/modules/text_server_adv/gdextension_build/SConstruct b/modules/text_server_adv/gdextension_build/SConstruct index 51caa4e6e55..39573aebde5 100644 --- a/modules/text_server_adv/gdextension_build/SConstruct +++ b/modules/text_server_adv/gdextension_build/SConstruct @@ -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() diff --git a/modules/text_server_adv/gdextension_build/methods.py b/modules/text_server_adv/gdextension_build/methods.py index d029e428558..c12b8c8a397 100644 --- a/modules/text_server_adv/gdextension_build/methods.py +++ b/modules/text_server_adv/gdextension_build/methods.py @@ -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"""\ diff --git a/modules/text_server_fb/gdextension_build/SConstruct b/modules/text_server_fb/gdextension_build/SConstruct index 72606760dff..ac1dc6d4e4a 100644 --- a/modules/text_server_fb/gdextension_build/SConstruct +++ b/modules/text_server_fb/gdextension_build/SConstruct @@ -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() diff --git a/modules/text_server_fb/gdextension_build/methods.py b/modules/text_server_fb/gdextension_build/methods.py index d029e428558..f39c1c4689b 100644 --- a/modules/text_server_fb/gdextension_build/methods.py +++ b/modules/text_server_fb/gdextension_build/methods.py @@ -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"""\ diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 8e567a2cd60..5893858dd9e 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -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"])