Skip to content

Commit ceb8e43

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

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
@@ -197,12 +197,14 @@ def generate_virtuals(target):
197197
f.write(txt)
198198

199199

200-
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
200+
def get_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
201201
api = {}
202202
files = []
203203
with open(api_filepath, encoding="utf-8") as api_file:
204204
api = json.load(api_file)
205205

206+
build_profile = parse_build_profile(profile_filepath, api)
207+
206208
core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
207209
include_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp"
208210
source_gen_folder = Path(output_dir) / "gen" / "src"
@@ -233,7 +235,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
233235
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
234236
if headers:
235237
files.append(str(header_filename.as_posix()))
236-
if sources:
238+
if sources and is_class_included(engine_class["name"], build_profile):
237239
files.append(str(source_filename.as_posix()))
238240

239241
for native_struct in api["native_structures"]:
@@ -265,12 +267,72 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
265267
return files
266268

267269

268-
def print_file_list(api_filepath, output_dir, headers=False, sources=False):
269-
print(*get_file_list(api_filepath, output_dir, headers, sources), sep=";", end=None)
270+
def print_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
271+
print(*get_file_list(api_filepath, output_dir, headers, sources, profile_filepath), sep=";", end=None)
272+
273+
274+
def parse_build_profile(profile_filepath, api):
275+
if profile_filepath == "":
276+
return {}
277+
print("Using feature build profile: " + profile_filepath)
278+
279+
with open(profile_filepath, encoding="utf-8") as profile_file:
280+
profile = json.load(profile_file)
281+
282+
parents = {}
283+
children = {}
284+
for engine_class in api["classes"]:
285+
parent = engine_class.get("inherits", "")
286+
child = engine_class["name"]
287+
parents[child] = parent
288+
if parent == "":
289+
continue
290+
children[parent] = children.get(parent, [])
291+
children[parent].append(child)
292+
293+
included = []
294+
front = list(profile.get("enabled_classes", []))
295+
while front:
296+
cls = front.pop()
297+
if cls in included:
298+
continue
299+
included.append(cls)
300+
parent = parents.get(cls, "")
301+
if parent:
302+
front.append(parent)
303+
304+
excluded = []
305+
front = list(profile.get("disabled_classes", []))
306+
while front:
307+
cls = front.pop()
308+
if cls in excluded:
309+
continue
310+
excluded.append(cls)
311+
front += children.get(cls, [])
312+
313+
if included and excluded:
314+
print(
315+
"WARNING: Cannot specify both 'enabled_classes' and 'disabled_classes' in build profile. 'disabled_classes' will be ignored."
316+
)
317+
318+
if included:
319+
# These must always be included
320+
included.append("ClassDB")
321+
included.append("ClassDBSingleton")
322+
included.append("FileAccess")
323+
324+
return {
325+
"enabled_classes": included,
326+
"disabled_classes": excluded,
327+
}
270328

271329

272330
def scons_emit_files(target, source, env):
273-
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)]
331+
profile_filepath = env.get("build_profile", "")
332+
if profile_filepath and not Path(profile_filepath).is_absolute():
333+
profile_filepath = str((Path(env.Dir("#").abspath) / profile_filepath).as_posix())
334+
335+
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True, profile_filepath)]
274336
env.Clean(target, files)
275337
env["godot_cpp_gen_dir"] = target[0].abspath
276338
return files, source
@@ -2473,6 +2535,20 @@ def is_refcounted(type_name):
24732535
return type_name in engine_classes and engine_classes[type_name]
24742536

24752537

2538+
def is_class_included(class_name, build_profile):
2539+
"""
2540+
Check if an engine class should be included.
2541+
This removes classes according to a build profile of enabled or disabled classes.
2542+
"""
2543+
included = build_profile.get("enabled_classes", [])
2544+
excluded = build_profile.get("disabled_classes", [])
2545+
if included:
2546+
return class_name in included
2547+
if excluded:
2548+
return class_name not in excluded
2549+
return True
2550+
2551+
24762552
def is_included(type_name, current_type):
24772553
"""
24782554
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
@@ -221,6 +221,15 @@ def options(opts, env):
221221
)
222222
)
223223

224+
opts.Add(
225+
PathVariable(
226+
"build_profile",
227+
"Path to a file containing a feature build profile",
228+
default=env.get("build_profile", None),
229+
validator=validate_file,
230+
)
231+
)
232+
224233
opts.Add(
225234
BoolVariable(
226235
key="use_hot_reload",

0 commit comments

Comments
 (0)