Skip to content

Commit e7126c7

Browse files
committed
Add support for build profiles.
Allow enabling or disabling specific classes (which will not be built).
1 parent 0ddef6e commit e7126c7

File tree

3 files changed

+106
-5
lines changed

3 files changed

+106
-5
lines changed

binding_generator.py

+81-5
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,14 @@ def generate_wrappers(target):
7070
f.write(txt)
7171

7272

73-
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
73+
def get_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
7474
api = {}
7575
files = []
7676
with open(api_filepath, encoding="utf-8") as api_file:
7777
api = json.load(api_file)
7878

79+
build_profile = parse_build_profile(profile_filepath, api)
80+
7981
core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
8082
include_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp"
8183
source_gen_folder = Path(output_dir) / "gen" / "src"
@@ -105,7 +107,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
105107
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
106108
if headers:
107109
files.append(str(header_filename.as_posix()))
108-
if sources:
110+
if sources and is_class_included(engine_class["name"], build_profile):
109111
files.append(str(source_filename.as_posix()))
110112

111113
for native_struct in api["native_structures"]:
@@ -137,12 +139,72 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
137139
return files
138140

139141

140-
def print_file_list(api_filepath, output_dir, headers=False, sources=False):
141-
print(*get_file_list(api_filepath, output_dir, headers, sources), sep=";", end=None)
142+
def print_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
143+
print(*get_file_list(api_filepath, output_dir, headers, sources, build_profile), sep=";", end=None)
144+
145+
146+
def parse_build_profile(profile_filepath, api):
147+
if profile_filepath == "":
148+
return {}
149+
print("Using feature build profile: " + profile_filepath)
150+
151+
with open(profile_filepath, encoding="utf-8") as profile_file:
152+
profile = json.load(profile_file)
153+
154+
parents = {}
155+
children = {}
156+
for engine_class in api["classes"]:
157+
parent = engine_class.get("inherits", "")
158+
child = engine_class["name"]
159+
parents[child] = parent
160+
if parent == "":
161+
continue
162+
children[parent] = children.get(parent, [])
163+
children[parent].append(child)
164+
165+
included = []
166+
front = list(profile.get("enabled_classes", []))
167+
while front:
168+
cls = front.pop()
169+
if cls in included:
170+
continue
171+
included.append(cls)
172+
parent = parents.get(cls, "")
173+
if parent:
174+
front.append(parent)
175+
176+
excluded = []
177+
front = list(profile.get("disabled_classes", []))
178+
while front:
179+
cls = front.pop()
180+
if cls in excluded:
181+
continue
182+
excluded.append(cls)
183+
front += children.get(cls, [])
184+
185+
if included and excluded:
186+
print(
187+
"WARNING: Cannot specify both 'enabled_classes' and 'disabled_classes' in build profile. 'disabled_classes' will be ignored."
188+
)
189+
190+
if included:
191+
# These must always be included
192+
included.append("ClassDB")
193+
included.append("ClassDBSingleton")
194+
included.append("FileAccess")
195+
196+
return {
197+
"enabled_classes": included,
198+
"disabled_classes": excluded,
199+
}
142200

143201

144202
def scons_emit_files(target, source, env):
145-
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)]
203+
profile_filepath = env.get("build_profile", "")
204+
if profile_filepath and not Path(profile_filepath).is_absolute():
205+
profile_filepath = str((Path(env.Dir("#").abspath) / profile_filepath).as_posix())
206+
207+
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True, profile_filepath)]
146208
env.Clean(target, files)
147209
env["godot_cpp_gen_dir"] = target[0].abspath
148210
return files, source
@@ -2301,6 +2363,20 @@ def is_refcounted(type_name):
23012363
return type_name in engine_classes and engine_classes[type_name]
23022364

23032365

2366+
def is_class_included(class_name, build_profile):
2367+
"""
2368+
Check if an engine class should be included.
2369+
This removes classes according to a build profile of enabled or disabled classes.
2370+
"""
2371+
included = build_profile.get("enabled_classes", [])
2372+
excluded = build_profile.get("disabled_classes", [])
2373+
if included:
2374+
return class_name in included
2375+
if excluded:
2376+
return class_name not in excluded
2377+
return True
2378+
2379+
23042380
def is_included(type_name, current_type):
23052381
"""
23062382
Check if a builtin type should be included.

test/build_profile.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"enabled_classes": [
3+
"Control",
4+
"Viewport",
5+
"InputEventKey",
6+
"TileMap",
7+
"Label",
8+
"Texture2D",
9+
"Material",
10+
"StyleBox",
11+
"SceneTree",
12+
"Mesh",
13+
"Window",
14+
"Shader"
15+
]
16+
}

tools/godotcpp.py

+9
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,15 @@ def options(opts, env):
198198
)
199199
)
200200

201+
opts.Add(
202+
PathVariable(
203+
"build_profile",
204+
"Path to a file containing a feature build profile",
205+
default=env.get("build_profile", None),
206+
validator=validate_file,
207+
)
208+
)
209+
201210
# Add platform options
202211
for pl in platforms:
203212
tool = Tool(pl, toolpath=["tools"])

0 commit comments

Comments
 (0)