@@ -197,12 +197,14 @@ def generate_virtuals(target):
197
197
f .write (txt )
198
198
199
199
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 = "" ):
201
201
api = {}
202
202
files = []
203
203
with open (api_filepath , encoding = "utf-8" ) as api_file :
204
204
api = json .load (api_file )
205
205
206
+ build_profile = parse_build_profile (profile_filepath , api )
207
+
206
208
core_gen_folder = Path (output_dir ) / "gen" / "include" / "godot_cpp" / "core"
207
209
include_gen_folder = Path (output_dir ) / "gen" / "include" / "godot_cpp"
208
210
source_gen_folder = Path (output_dir ) / "gen" / "src"
@@ -233,7 +235,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
233
235
source_filename = source_gen_folder / "classes" / (camel_to_snake (engine_class ["name" ]) + ".cpp" )
234
236
if headers :
235
237
files .append (str (header_filename .as_posix ()))
236
- if sources :
238
+ if sources and is_class_included ( engine_class [ "name" ], build_profile ) :
237
239
files .append (str (source_filename .as_posix ()))
238
240
239
241
for native_struct in api ["native_structures" ]:
@@ -265,12 +267,72 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
265
267
return files
266
268
267
269
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
+ }
270
328
271
329
272
330
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 )]
274
336
env .Clean (target , files )
275
337
env ["godot_cpp_gen_dir" ] = target [0 ].abspath
276
338
return files , source
@@ -2473,6 +2535,20 @@ def is_refcounted(type_name):
2473
2535
return type_name in engine_classes and engine_classes [type_name ]
2474
2536
2475
2537
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
+
2476
2552
def is_included (type_name , current_type ):
2477
2553
"""
2478
2554
Check if a builtin type should be included.
0 commit comments