Compare commits

...

4 Commits

Author SHA1 Message Date
Fabio Alessandrelli 29e80a3b52
Merge 2bb9bdbe91 into 36847f6af0 2024-01-23 01:03:15 +03:00
David Snopek 36847f6af0
Merge pull request #1370 from MJacred/patch-1
Update README: fix godot-cpp issue tracker url
2024-01-22 08:57:08 -06:00
MJacred 8a535d0ecc
Update README: fix godot-cpp issue tracker url 2024-01-22 10:50:27 +01:00
Fabio Alessandrelli 2bb9bdbe91 Add support for build profiles.
Allow enabling or disabling specific classes (which will not be built).
2024-01-19 15:46:58 +01:00
4 changed files with 107 additions and 6 deletions

View File

@ -58,7 +58,7 @@ first-party `godot-cpp` extension.
Some compatibility breakage is to be expected as GDExtension and `godot-cpp` Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
get more used, documented, and critical issues get resolved. See the get more used, documented, and critical issues get resolved. See the
[Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension) [Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension)
and the [godot-cpp issue tracker](https://github.com/godotengine/godot/issues) and the [godot-cpp issue tracker](https://github.com/godotengine/godot-cpp/issues)
for a list of known issues, and be sure to provide feedback on issues and PRs for a list of known issues, and be sure to provide feedback on issues and PRs
which affect your use of this extension. which affect your use of this extension.

View File

@ -70,12 +70,14 @@ def generate_wrappers(target):
f.write(txt) f.write(txt)
def get_file_list(api_filepath, output_dir, headers=False, sources=False): def get_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
api = {} api = {}
files = [] files = []
with open(api_filepath, encoding="utf-8") as api_file: with open(api_filepath, encoding="utf-8") as api_file:
api = json.load(api_file) api = json.load(api_file)
build_profile = parse_build_profile(profile_filepath, api)
core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core" core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
include_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" include_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp"
source_gen_folder = Path(output_dir) / "gen" / "src" source_gen_folder = Path(output_dir) / "gen" / "src"
@ -105,7 +107,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp") source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
if headers: if headers:
files.append(str(header_filename.as_posix())) files.append(str(header_filename.as_posix()))
if sources: if sources and is_class_included(engine_class["name"], build_profile):
files.append(str(source_filename.as_posix())) files.append(str(source_filename.as_posix()))
for native_struct in api["native_structures"]: for native_struct in api["native_structures"]:
@ -137,12 +139,72 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
return files return files
def print_file_list(api_filepath, output_dir, headers=False, sources=False): def print_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
print(*get_file_list(api_filepath, output_dir, headers, sources), sep=";", end=None) print(*get_file_list(api_filepath, output_dir, headers, sources, profile_filepath), sep=";", end=None)
def parse_build_profile(profile_filepath, api):
if profile_filepath == "":
return {}
print("Using feature build profile: " + profile_filepath)
with open(profile_filepath, encoding="utf-8") as profile_file:
profile = json.load(profile_file)
parents = {}
children = {}
for engine_class in api["classes"]:
parent = engine_class.get("inherits", "")
child = engine_class["name"]
parents[child] = parent
if parent == "":
continue
children[parent] = children.get(parent, [])
children[parent].append(child)
included = []
front = list(profile.get("enabled_classes", []))
while front:
cls = front.pop()
if cls in included:
continue
included.append(cls)
parent = parents.get(cls, "")
if parent:
front.append(parent)
excluded = []
front = list(profile.get("disabled_classes", []))
while front:
cls = front.pop()
if cls in excluded:
continue
excluded.append(cls)
front += children.get(cls, [])
if included and excluded:
print(
"WARNING: Cannot specify both 'enabled_classes' and 'disabled_classes' in build profile. 'disabled_classes' will be ignored."
)
if included:
# These must always be included
included.append("ClassDB")
included.append("ClassDBSingleton")
included.append("FileAccess")
return {
"enabled_classes": included,
"disabled_classes": excluded,
}
def scons_emit_files(target, source, env): def scons_emit_files(target, source, env):
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)] profile_filepath = env.get("build_profile", "")
if profile_filepath and not Path(profile_filepath).is_absolute():
profile_filepath = str((Path(env.Dir("#").abspath) / profile_filepath).as_posix())
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True, profile_filepath)]
env.Clean(target, files) env.Clean(target, files)
env["godot_cpp_gen_dir"] = target[0].abspath env["godot_cpp_gen_dir"] = target[0].abspath
return files, source return files, source
@ -2301,6 +2363,20 @@ def is_refcounted(type_name):
return type_name in engine_classes and engine_classes[type_name] return type_name in engine_classes and engine_classes[type_name]
def is_class_included(class_name, build_profile):
"""
Check if an engine class should be included.
This removes classes according to a build profile of enabled or disabled classes.
"""
included = build_profile.get("enabled_classes", [])
excluded = build_profile.get("disabled_classes", [])
if included:
return class_name in included
if excluded:
return class_name not in excluded
return True
def is_included(type_name, current_type): def is_included(type_name, current_type):
""" """
Check if a builtin type should be included. Check if a builtin type should be included.

16
test/build_profile.json Normal file
View File

@ -0,0 +1,16 @@
{
"enabled_classes": [
"Control",
"Viewport",
"InputEventKey",
"TileMap",
"Label",
"Texture2D",
"Material",
"StyleBox",
"SceneTree",
"Mesh",
"Window",
"Shader"
]
}

View File

@ -198,6 +198,15 @@ def options(opts, env):
) )
) )
opts.Add(
PathVariable(
"build_profile",
"Path to a file containing a feature build profile",
default=env.get("build_profile", None),
validator=validate_file,
)
)
# Add platform options # Add platform options
for pl in platforms: for pl in platforms:
tool = Tool(pl, toolpath=["tools"]) tool = Tool(pl, toolpath=["tools"])