summaryrefslogtreecommitdiffstats
path: root/methods.py
diff options
context:
space:
mode:
Diffstat (limited to 'methods.py')
-rw-r--r--methods.py563
1 files changed, 216 insertions, 347 deletions
diff --git a/methods.py b/methods.py
index 9e881773c9..203f0dd8a5 100644
--- a/methods.py
+++ b/methods.py
@@ -1,5 +1,7 @@
+import atexit
import contextlib
import glob
+import math
import os
import re
import subprocess
@@ -8,7 +10,7 @@ from collections import OrderedDict
from enum import Enum
from io import StringIO, TextIOWrapper
from pathlib import Path
-from typing import Generator, List, Optional, Union
+from typing import Generator, List, Optional, Union, cast
# Get the "Godot" folder name ahead of time
base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/"
@@ -73,21 +75,13 @@ def print_error(*values: object) -> None:
def add_source_files_orig(self, sources, files, allow_gen=False):
# Convert string to list of absolute paths (including expanding wildcard)
- if isinstance(files, (str, bytes)):
- # Keep SCons project-absolute path as they are (no wildcard support)
- if files.startswith("#"):
- if "*" in files:
- print_error("Wildcards can't be expanded in SCons project-absolute path: '{}'".format(files))
- return
- files = [files]
- else:
- # Exclude .gen.cpp files from globbing, to avoid including obsolete ones.
- # They should instead be added manually.
- skip_gen_cpp = "*" in files
- dir_path = self.Dir(".").abspath
- files = sorted(glob.glob(dir_path + "/" + files))
- if skip_gen_cpp and not allow_gen:
- files = [f for f in files if not f.endswith(".gen.cpp")]
+ if isinstance(files, str):
+ # Exclude .gen.cpp files from globbing, to avoid including obsolete ones.
+ # They should instead be added manually.
+ skip_gen_cpp = "*" in files
+ files = self.Glob(files)
+ if skip_gen_cpp and not allow_gen:
+ files = [f for f in files if not str(f).endswith(".gen.cpp")]
# Add each path as compiled Object following environment (self) configuration
for path in files:
@@ -98,35 +92,6 @@ def add_source_files_orig(self, sources, files, allow_gen=False):
sources.append(obj)
-# The section name is used for checking
-# the hash table to see whether the folder
-# is included in the SCU build.
-# It will be something like "core/math".
-def _find_scu_section_name(subdir):
- section_path = os.path.abspath(subdir) + "/"
-
- folders = []
- folder = ""
-
- for i in range(8):
- folder = os.path.dirname(section_path)
- folder = os.path.basename(folder)
- if folder == base_folder_only:
- break
- folders += [folder]
- section_path += "../"
- section_path = os.path.abspath(section_path) + "/"
-
- section_name = ""
- for n in range(len(folders)):
- # section_name += folders[len(folders) - n - 1] + " "
- section_name += folders[len(folders) - n - 1]
- if n != (len(folders) - 1):
- section_name += "/"
-
- return section_name
-
-
def add_source_files_scu(self, sources, files, allow_gen=False):
if self["scu_build"] and isinstance(files, str):
if "*." not in files:
@@ -135,10 +100,8 @@ def add_source_files_scu(self, sources, files, allow_gen=False):
# If the files are in a subdirectory, we want to create the scu gen
# files inside this subdirectory.
subdir = os.path.dirname(files)
- if subdir != "":
- subdir += "/"
-
- section_name = _find_scu_section_name(subdir)
+ subdir = subdir if subdir == "" else subdir + "/"
+ section_name = self.Dir(subdir).tpath
# if the section name is in the hash table?
# i.e. is it part of the SCU build?
global _scu_folders
@@ -277,34 +240,6 @@ def get_version_info(module_version_string="", silent=False):
return version_info
-def parse_cg_file(fname, uniforms, sizes, conditionals):
- with open(fname, "r", encoding="utf-8") as fs:
- line = fs.readline()
-
- while line:
- if re.match(r"^\s*uniform", line):
- res = re.match(r"uniform ([\d\w]*) ([\d\w]*)")
- type = res.groups(1)
- name = res.groups(2)
-
- uniforms.append(name)
-
- if type.find("texobj") != -1:
- sizes.append(1)
- else:
- t = re.match(r"float(\d)x(\d)", type)
- if t:
- sizes.append(int(t.groups(1)) * int(t.groups(2)))
- else:
- t = re.match(r"float(\d)", type)
- sizes.append(int(t.groups(1)))
-
- if line.find("[branch]") != -1:
- conditionals.append(name)
-
- line = fs.readline()
-
-
def get_cmdline_bool(option, default):
"""We use `ARGUMENTS.get()` to check if options were manually overridden on the command line,
and SCons' _text2bool helper to convert them to booleans, otherwise they're handled as strings.
@@ -404,10 +339,6 @@ def convert_custom_modules_path(path):
return path
-def disable_module(self):
- self.disabled_modules.append(self.current_module)
-
-
def module_add_dependencies(self, module, dependencies, optional=False):
"""
Adds dependencies for a given module.
@@ -428,19 +359,21 @@ def module_check_dependencies(self, module):
Meant to be used in module `can_build` methods.
Returns a boolean (True if dependencies are satisfied).
"""
- missing_deps = []
+ missing_deps = set()
required_deps = self.module_dependencies[module][0] if module in self.module_dependencies else []
for dep in required_deps:
opt = "module_{}_enabled".format(dep)
- if opt not in self or not self[opt]:
- missing_deps.append(dep)
-
- if missing_deps != []:
- print_warning(
- "Disabling '{}' module as the following dependencies are not satisfied: {}".format(
- module, ", ".join(missing_deps)
+ if opt not in self or not self[opt] or not module_check_dependencies(self, dep):
+ missing_deps.add(dep)
+
+ if missing_deps:
+ if module not in self.disabled_modules:
+ print_warning(
+ "Disabling '{}' module as the following dependencies are not satisfied: {}".format(
+ module, ", ".join(missing_deps)
+ )
)
- )
+ self.disabled_modules.add(module)
return False
else:
return True
@@ -478,8 +411,7 @@ def use_windows_spawn_fix(self, platform=None):
"shell": False,
"env": env,
}
- if sys.version_info >= (3, 7, 0):
- popen_args["text"] = True
+ popen_args["text"] = True
proc = subprocess.Popen(cmdline, **popen_args)
_, err = proc.communicate()
rv = proc.wait()
@@ -565,40 +497,7 @@ def detect_visual_c_compiler_version(tools_env):
vc_chosen_compiler_index = -1
vc_chosen_compiler_str = ""
- # Start with Pre VS 2017 checks which uses VCINSTALLDIR:
- if "VCINSTALLDIR" in tools_env:
- # print("Checking VCINSTALLDIR")
-
- # find() works with -1 so big ifs below are needed... the simplest solution, in fact
- # First test if amd64 and amd64_x86 compilers are present in the path
- vc_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\amd64;")
- if vc_amd64_compiler_detection_index > -1:
- vc_chosen_compiler_index = vc_amd64_compiler_detection_index
- vc_chosen_compiler_str = "amd64"
-
- vc_amd64_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\amd64_x86;")
- if vc_amd64_x86_compiler_detection_index > -1 and (
- vc_chosen_compiler_index == -1 or vc_chosen_compiler_index > vc_amd64_x86_compiler_detection_index
- ):
- vc_chosen_compiler_index = vc_amd64_x86_compiler_detection_index
- vc_chosen_compiler_str = "amd64_x86"
-
- # Now check the 32 bit compilers
- vc_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN;")
- if vc_x86_compiler_detection_index > -1 and (
- vc_chosen_compiler_index == -1 or vc_chosen_compiler_index > vc_x86_compiler_detection_index
- ):
- vc_chosen_compiler_index = vc_x86_compiler_detection_index
- vc_chosen_compiler_str = "x86"
-
- vc_x86_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\x86_amd64;")
- if vc_x86_amd64_compiler_detection_index > -1 and (
- vc_chosen_compiler_index == -1 or vc_chosen_compiler_index > vc_x86_amd64_compiler_detection_index
- ):
- vc_chosen_compiler_index = vc_x86_amd64_compiler_detection_index
- vc_chosen_compiler_str = "x86_amd64"
-
- # and for VS 2017 and newer we check VCTOOLSINSTALLDIR:
+ # VS 2017 and newer should set VCTOOLSINSTALLDIR
if "VCTOOLSINSTALLDIR" in tools_env:
# Newer versions have a different path available
vc_amd64_compiler_detection_index = (
@@ -695,23 +594,6 @@ def glob_recursive(pattern, node="."):
return results
-def add_to_vs_project(env, sources):
- for x in sources:
- fname = env.File(x).path if isinstance(x, str) else env.File(x)[0].path
- pieces = fname.split(".")
- if len(pieces) > 0:
- basename = pieces[0]
- basename = basename.replace("\\\\", "/")
- if os.path.isfile(basename + ".h"):
- env.vs_incs += [basename + ".h"]
- elif os.path.isfile(basename + ".hpp"):
- env.vs_incs += [basename + ".hpp"]
- if os.path.isfile(basename + ".c"):
- env.vs_srcs += [basename + ".c"]
- elif os.path.isfile(basename + ".cpp"):
- env.vs_srcs += [basename + ".cpp"]
-
-
def precious_program(env, program, sources, **args):
program = env.ProgramOriginal(program, sources, **args)
env.Precious(program)
@@ -772,7 +654,9 @@ def detect_darwin_sdk_path(platform, env):
raise
-def is_vanilla_clang(env):
+def is_apple_clang(env):
+ if env["platform"] not in ["macos", "ios"]:
+ return False
if not using_clang(env):
return False
try:
@@ -780,7 +664,7 @@ def is_vanilla_clang(env):
except (subprocess.CalledProcessError, OSError):
print_warning("Couldn't parse CXX environment variable to infer compiler version.")
return False
- return not version.startswith("Apple")
+ return version.startswith("Apple")
def get_compiler_version(env):
@@ -904,159 +788,165 @@ def using_emcc(env):
def show_progress(env):
- if env["ninja"]:
- # Has its own progress/tracking tool that clashes with ours
+ # Progress reporting is not available in non-TTY environments since it messes with the output
+ # (for example, when writing to a file). Ninja has its own progress/tracking tool that clashes
+ # with ours.
+ if not env["progress"] or not sys.stdout.isatty() or env["ninja"]:
return
- import sys
-
- from SCons.Script import AlwaysBuild, Command, Progress
-
- screen = sys.stdout
- # Progress reporting is not available in non-TTY environments since it
- # messes with the output (for example, when writing to a file)
- show_progress = env["progress"] and sys.stdout.isatty()
- node_count = 0
- node_count_max = 0
- node_count_interval = 1
- node_count_fname = str(env.Dir("#")) + "/.scons_node_count"
-
- import math
-
- class cache_progress:
- # The default is 1 GB cache
- def __init__(self, path=None, limit=pow(1024, 3)):
- self.path = path
- self.limit = limit
- if env["verbose"] and path is not None:
- screen.write(
- "Current cache limit is {} (used: {})\n".format(
- self.convert_size(limit), self.convert_size(self.get_size(path))
- )
- )
+ NODE_COUNT_FILENAME = f"{base_folder_path}.scons_node_count"
+
+ class ShowProgress:
+ def __init__(self):
+ self.count = 0
+ self.max = 0
+ try:
+ with open(NODE_COUNT_FILENAME, "r", encoding="utf-8") as f:
+ self.max = int(f.readline())
+ except OSError:
+ pass
+ if self.max == 0:
+ print("NOTE: Performing initial build, progress percentage unavailable!")
def __call__(self, node, *args, **kw):
- nonlocal node_count, node_count_max, node_count_interval, node_count_fname, show_progress
- if show_progress:
- # Print the progress percentage
- node_count += node_count_interval
- if node_count_max > 0 and node_count <= node_count_max:
- screen.write("\r[%3d%%] " % (node_count * 100 / node_count_max))
- screen.flush()
- elif node_count_max > 0 and node_count > node_count_max:
- screen.write("\r[100%] ")
- screen.flush()
- else:
- screen.write("\r[Initial build] ")
- screen.flush()
-
- def convert_size(self, size_bytes):
- if size_bytes == 0:
- return "0 bytes"
- size_name = ("bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
- i = int(math.floor(math.log(size_bytes, 1024)))
- p = math.pow(1024, i)
- s = round(size_bytes / p, 2)
- return "%s %s" % (int(s) if i == 0 else s, size_name[i])
-
- def get_size(self, start_path="."):
- total_size = 0
- for dirpath, dirnames, filenames in os.walk(start_path):
- for f in filenames:
- fp = os.path.join(dirpath, f)
- total_size += os.path.getsize(fp)
- return total_size
+ self.count += 1
+ if self.max != 0:
+ percent = int(min(self.count * 100 / self.max, 100))
+ sys.stdout.write(f"\r[{percent:3d}%] ")
+ sys.stdout.flush()
+
+ from SCons.Script import Progress
+
+ progressor = ShowProgress()
+ Progress(progressor)
def progress_finish(target, source, env):
- nonlocal node_count, progressor
try:
- with open(node_count_fname, "w", encoding="utf-8", newline="\n") as f:
- f.write("%d\n" % node_count)
- except Exception:
+ with open(NODE_COUNT_FILENAME, "w", encoding="utf-8", newline="\n") as f:
+ f.write(f"{progressor.count}\n")
+ except OSError:
pass
- try:
- with open(node_count_fname, "r", encoding="utf-8") as f:
- node_count_max = int(f.readline())
- except Exception:
- pass
+ env.AlwaysBuild(
+ env.CommandNoCache(
+ "progress_finish", [], env.Action(progress_finish, "Building node count database .scons_node_count")
+ )
+ )
+
+
+def convert_size(size_bytes: int) -> str:
+ if size_bytes == 0:
+ return "0 bytes"
+ SIZE_NAMES = ["bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
+ index = math.floor(math.log(size_bytes, 1024))
+ power = math.pow(1024, index)
+ size = round(size_bytes / power, 2)
+ return f"{size} {SIZE_NAMES[index]}"
- cache_directory = os.environ.get("SCONS_CACHE")
- # Simple cache pruning, attached to SCons' progress callback. Trim the
- # cache directory to a size not larger than cache_limit.
- cache_limit = float(os.getenv("SCONS_CACHE_LIMIT", 1024)) * 1024 * 1024
- progressor = cache_progress(cache_directory, cache_limit)
- Progress(progressor, interval=node_count_interval)
-
- progress_finish_command = Command("progress_finish", [], progress_finish)
- AlwaysBuild(progress_finish_command)
-
-
-def clean_cache(env):
- import atexit
- import time
-
- class cache_clean:
- def __init__(self, path=None, limit=pow(1024, 3)):
- self.path = path
- self.limit = limit
-
- def clean(self):
- self.delete(self.file_list())
-
- def delete(self, files):
- if len(files) == 0:
- return
- if env["verbose"]:
- # Utter something
- print("Purging %d %s from cache..." % (len(files), "files" if len(files) > 1 else "file"))
- [os.remove(f) for f in files]
-
- def file_list(self):
- if self.path is None:
- # Nothing to do
- return []
- # Gather a list of (filename, (size, atime)) within the
- # cache directory
- file_stat = [(x, os.stat(x)[6:8]) for x in glob.glob(os.path.join(self.path, "*", "*"))]
- if file_stat == []:
- # Nothing to do
- return []
- # Weight the cache files by size (assumed to be roughly
- # proportional to the recompilation time) times an exponential
- # decay since the ctime, and return a list with the entries
- # (filename, size, weight).
- current_time = time.time()
- file_stat = [(x[0], x[1][0], (current_time - x[1][1])) for x in file_stat]
- # Sort by the most recently accessed files (most sensible to keep) first
- file_stat.sort(key=lambda x: x[2])
- # Search for the first entry where the storage limit is
- # reached
- sum, mark = 0, None
- for i, x in enumerate(file_stat):
- sum += x[1]
- if sum > self.limit:
- mark = i
- break
- if mark is None:
- return []
- else:
- return [x[0] for x in file_stat[mark:]]
- def cache_finally():
- nonlocal cleaner
+def get_size(start_path: str = ".") -> int:
+ total_size = 0
+ for dirpath, _, filenames in os.walk(start_path):
+ for file in filenames:
+ path = os.path.join(dirpath, file)
+ total_size += os.path.getsize(path)
+ return total_size
+
+
+def clean_cache(cache_path: str, cache_limit: int, verbose: bool):
+ files = glob.glob(os.path.join(cache_path, "*", "*"))
+ if not files:
+ return
+
+ # Remove all text files, store binary files in list of (filename, size, atime).
+ purge = []
+ texts = []
+ stats = []
+ for file in files:
try:
- cleaner.clean()
- except Exception:
- pass
+ # Save file stats to rewrite after modifying.
+ tmp_stat = os.stat(file)
+ # Failing a utf-8 decode is the easiest way to determine if a file is binary.
+ try:
+ with open(file, encoding="utf-8") as out:
+ out.read(1024)
+ except UnicodeDecodeError:
+ stats.append((file, *tmp_stat[6:8]))
+ # Restore file stats after reading.
+ os.utime(file, (tmp_stat[7], tmp_stat[8]))
+ else:
+ texts.append(file)
+ except OSError:
+ print_error(f'Failed to access cache file "{file}"; skipping.')
+
+ if texts:
+ count = len(texts)
+ for file in texts:
+ try:
+ os.remove(file)
+ except OSError:
+ print_error(f'Failed to remove cache file "{file}"; skipping.')
+ count -= 1
+ if verbose:
+ print("Purging %d text %s from cache..." % (count, "files" if count > 1 else "file"))
+
+ if cache_limit:
+ # Sort by most recent access (most sensible to keep) first. Search for the first entry where
+ # the cache limit is reached.
+ stats.sort(key=lambda x: x[2], reverse=True)
+ sum = 0
+ for index, stat in enumerate(stats):
+ sum += stat[1]
+ if sum > cache_limit:
+ purge.extend([x[0] for x in stats[index:]])
+ break
- cache_directory = os.environ.get("SCONS_CACHE")
- # Simple cache pruning, attached to SCons' progress callback. Trim the
- # cache directory to a size not larger than cache_limit.
- cache_limit = float(os.getenv("SCONS_CACHE_LIMIT", 1024)) * 1024 * 1024
- cleaner = cache_clean(cache_directory, cache_limit)
+ if purge:
+ count = len(purge)
+ for file in purge:
+ try:
+ os.remove(file)
+ except OSError:
+ print_error(f'Failed to remove cache file "{file}"; skipping.')
+ count -= 1
+ if verbose:
+ print("Purging %d %s from cache..." % (count, "files" if count > 1 else "file"))
+
+
+def prepare_cache(env) -> None:
+ if env.GetOption("clean"):
+ return
+
+ cache_path = ""
+ if env["cache_path"]:
+ cache_path = cast(str, env["cache_path"])
+ elif os.environ.get("SCONS_CACHE"):
+ print_warning("Environment variable `SCONS_CACHE` is deprecated; use `cache_path` argument instead.")
+ cache_path = cast(str, os.environ.get("SCONS_CACHE"))
+
+ if not cache_path:
+ return
+
+ env.CacheDir(cache_path)
+ print(f'SCons cache enabled... (path: "{cache_path}")')
+
+ if env["cache_limit"]:
+ cache_limit = float(env["cache_limit"])
+ elif os.environ.get("SCONS_CACHE_LIMIT"):
+ print_warning("Environment variable `SCONS_CACHE_LIMIT` is deprecated; use `cache_limit` argument instead.")
+ cache_limit = float(os.getenv("SCONS_CACHE_LIMIT", "0")) / 1024 # Old method used MiB, convert to GiB
+
+ # Convert GiB to bytes; treat negative numbers as 0 (unlimited).
+ cache_limit = max(0, int(cache_limit * 1024 * 1024 * 1024))
+ if env["verbose"]:
+ print(
+ "Current cache limit is {} (used: {})".format(
+ convert_size(cache_limit) if cache_limit else "∞",
+ convert_size(get_size(cache_path)),
+ )
+ )
- atexit.register(cache_finally)
+ atexit.register(clean_cache, cache_path, cache_limit, env["verbose"])
def dump(env):
@@ -1127,6 +1017,30 @@ def generate_vs_project(env, original_args, project_name="godot"):
return v[0] if len(v) == 1 else f"{v[0]}={v[1]}"
return v
+ def get_dependencies(file, env, exts, headers, sources, others):
+ for child in file.children():
+ if isinstance(child, str):
+ child = env.File(x)
+ fname = ""
+ try:
+ fname = child.path
+ except AttributeError:
+ # It's not a file.
+ pass
+
+ if fname:
+ parts = os.path.splitext(fname)
+ if len(parts) > 1:
+ ext = parts[1].lower()
+ if ext in exts["sources"]:
+ sources += [fname]
+ elif ext in exts["headers"]:
+ headers += [fname]
+ elif ext in exts["others"]:
+ others += [fname]
+
+ get_dependencies(child, env, exts, headers, sources, others)
+
filtered_args = original_args.copy()
# Ignore the "vsproj" option to not regenerate the VS project on every build
@@ -1188,35 +1102,35 @@ def generate_vs_project(env, original_args, project_name="godot"):
sys.path.remove(tmppath)
sys.modules.pop("msvs")
+ extensions = {}
+ extensions["headers"] = [".h", ".hh", ".hpp", ".hxx", ".inc"]
+ extensions["sources"] = [".c", ".cc", ".cpp", ".cxx", ".m", ".mm", ".java"]
+ extensions["others"] = [".natvis", ".glsl", ".rc"]
+
headers = []
headers_dirs = []
- for file in glob_recursive_2("*.h", headers_dirs):
- headers.append(str(file).replace("/", "\\"))
- for file in glob_recursive_2("*.hpp", headers_dirs):
- headers.append(str(file).replace("/", "\\"))
+ for ext in extensions["headers"]:
+ for file in glob_recursive_2("*" + ext, headers_dirs):
+ headers.append(str(file).replace("/", "\\"))
sources = []
sources_dirs = []
- for file in glob_recursive_2("*.cpp", sources_dirs):
- sources.append(str(file).replace("/", "\\"))
- for file in glob_recursive_2("*.c", sources_dirs):
- sources.append(str(file).replace("/", "\\"))
+ for ext in extensions["sources"]:
+ for file in glob_recursive_2("*" + ext, sources_dirs):
+ sources.append(str(file).replace("/", "\\"))
others = []
others_dirs = []
- for file in glob_recursive_2("*.natvis", others_dirs):
- others.append(str(file).replace("/", "\\"))
- for file in glob_recursive_2("*.glsl", others_dirs):
- others.append(str(file).replace("/", "\\"))
+ for ext in extensions["others"]:
+ for file in glob_recursive_2("*" + ext, others_dirs):
+ others.append(str(file).replace("/", "\\"))
skip_filters = False
import hashlib
import json
md5 = hashlib.md5(
- json.dumps(headers + headers_dirs + sources + sources_dirs + others + others_dirs, sort_keys=True).encode(
- "utf-8"
- )
+ json.dumps(sorted(headers + headers_dirs + sources + sources_dirs + others + others_dirs)).encode("utf-8")
).hexdigest()
if os.path.exists(f"{project_name}.vcxproj.filters"):
@@ -1273,58 +1187,13 @@ def generate_vs_project(env, original_args, project_name="godot"):
with open(f"{project_name}.vcxproj.filters", "w", encoding="utf-8", newline="\r\n") as f:
f.write(filters_template)
- envsources = []
-
- envsources += env.core_sources
- envsources += env.drivers_sources
- envsources += env.main_sources
- envsources += env.modules_sources
- envsources += env.scene_sources
- envsources += env.servers_sources
- if env.editor_build:
- envsources += env.editor_sources
- envsources += env.platform_sources
-
headers_active = []
sources_active = []
others_active = []
- for x in envsources:
- fname = ""
- if isinstance(x, str):
- fname = env.File(x).path
- else:
- # Some object files might get added directly as a File object and not a list.
- try:
- fname = env.File(x)[0].path
- except Exception:
- fname = x.path
- pass
- if fname:
- fname = fname.replace("\\\\", "/")
- parts = os.path.splitext(fname)
- basename = parts[0]
- ext = parts[1]
- idx = fname.find(env["OBJSUFFIX"])
- if ext in [".h", ".hpp"]:
- headers_active += [fname]
- elif ext in [".c", ".cpp"]:
- sources_active += [fname]
- elif idx > 0:
- basename = fname[:idx]
- if os.path.isfile(basename + ".h"):
- headers_active += [basename + ".h"]
- elif os.path.isfile(basename + ".hpp"):
- headers_active += [basename + ".hpp"]
- elif basename.endswith(".gen") and os.path.isfile(basename[:-4] + ".h"):
- headers_active += [basename[:-4] + ".h"]
- if os.path.isfile(basename + ".c"):
- sources_active += [basename + ".c"]
- elif os.path.isfile(basename + ".cpp"):
- sources_active += [basename + ".cpp"]
- else:
- fname = os.path.relpath(os.path.abspath(fname), env.Dir("").abspath)
- others_active += [fname]
+ get_dependencies(
+ env.File(f"#bin/godot{env['PROGSUFFIX']}"), env, extensions, headers_active, sources_active, others_active
+ )
all_items = []
properties = []