11#!/usr/bin/env python
22
33import json
4+ import os
45import re
56import shutil
67from pathlib import Path
@@ -70,7 +71,15 @@ def generate_wrappers(target):
7071 f .write (txt )
7172
7273
73- def get_file_list (api_filepath , output_dir , headers = False , sources = False ):
74+ def is_class_included (class_name , build_profile ):
75+ if "enabled_classes" in build_profile :
76+ return class_name in build_profile ["enabled_classes" ]
77+ if "disabled_classes" in build_profile :
78+ return class_name not in build_profile ["disabled_classes" ]
79+ return True
80+
81+
82+ def get_file_list (api_filepath , output_dir , headers = False , sources = False , build_profile = {}):
7483 api = {}
7584 files = []
7685 with open (api_filepath , encoding = "utf-8" ) as api_file :
@@ -97,6 +106,8 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
97106 files .append (str (source_filename .as_posix ()))
98107
99108 for engine_class in api ["classes" ]:
109+ if not is_class_included (engine_class ["name" ], build_profile ):
110+ continue
100111 # Generate code for the ClassDB singleton under a different name.
101112 if engine_class ["name" ] == "ClassDB" :
102113 engine_class ["name" ] = "ClassDBSingleton"
@@ -137,12 +148,65 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
137148 return files
138149
139150
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 )
151+ def print_file_list (api_filepath , output_dir , headers = False , sources = False , build_profile = {}):
152+ print (* get_file_list (api_filepath , output_dir , headers , sources , build_profile ), sep = ";" , end = None )
153+
154+
155+ def scons_parse_build_profile (env , api_filepath ):
156+ if not "build_profile" in env :
157+ return {}
158+ profile_filename = env ["build_profile" ]
159+ if not os .path .isabs (profile_filename ):
160+ profile_filename = os .path .join (env .Dir ("#" ).abspath , profile_filename )
161+ print ("Using feature build profile: " + profile_filename )
162+
163+ with open (profile_filename , encoding = "utf-8" ) as profile_file :
164+ profile = json .load (profile_file )
165+
166+ with open (api_filepath , encoding = "utf-8" ) as api_file :
167+ api = json .load (api_file )
168+
169+
170+ parents = {}
171+ childs = {}
172+ for engine_class in api ["classes" ]:
173+ parent = engine_class .get ("inherits" , "" )
174+ child = engine_class ["name" ]
175+ parents [child ] = parent
176+ if parent == "" :
177+ continue
178+ if parent not in childs :
179+ childs [parent ] = childs .get (parent , [])
180+ childs [parent ].append (child )
181+
182+ included = []
183+ front = list (profile .get ("enabled_classes" , []))
184+ while len (front ):
185+ cls = front .pop ()
186+ if cls in included :
187+ continue
188+ included .append (cls )
189+ parent = parents .get (cls , "" )
190+ if parent :
191+ front .append (parent )
192+
193+ excluded = []
194+ front = list (profile .get ("disabled_classes" , []))
195+ while len (front ):
196+ cls = front .pop ()
197+ if cls in excluded :
198+ continue
199+ excluded .append (cls )
200+ front .concat (childs .get (cls , []))
201+ return {
202+ "enabled_classes" : included ,
203+ "disabled_classes" : excluded ,
204+ }
142205
143206
144207def 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 )]
208+ build_profile = scons_parse_build_profile (env , str (source [0 ]))
209+ files = [env .File (f ) for f in get_file_list (str (source [0 ]), target [0 ].abspath , True , True , build_profile )]
146210 env .Clean (target , files )
147211 env ["godot_cpp_gen_dir" ] = target [0 ].abspath
148212 return files , source
@@ -159,7 +223,7 @@ def scons_generate_bindings(target, source, env):
159223 return None
160224
161225
162- def generate_bindings (api_filepath , use_template_get_node , bits = "64" , precision = "single" , output_dir = "." ):
226+ def generate_bindings (api_filepath , use_template_get_node , bits = "64" , precision = "single" , output_dir = "." , build_profile = {} ):
163227 api = None
164228
165229 target_dir = Path (output_dir ) / "gen"
@@ -177,7 +241,7 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision=
177241 generate_version_header (api , target_dir )
178242 generate_global_constant_binds (api , target_dir )
179243 generate_builtin_bindings (api , target_dir , real_t + "_" + bits )
180- generate_engine_classes_bindings (api , target_dir , use_template_get_node )
244+ generate_engine_classes_bindings (api , target_dir , use_template_get_node , build_profile )
181245 generate_utility_functions (api , target_dir )
182246
183247
@@ -1070,7 +1134,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
10701134 return "\n " .join (result )
10711135
10721136
1073- def generate_engine_classes_bindings (api , output_dir , use_template_get_node ):
1137+ def generate_engine_classes_bindings (api , output_dir , use_template_get_node , build_profile = {} ):
10741138 global engine_classes
10751139 global singletons
10761140 global native_structures
@@ -1083,6 +1147,8 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
10831147
10841148 # First create map of classes and singletons.
10851149 for class_api in api ["classes" ]:
1150+ if not is_class_included (class_api ["name" ], build_profile ):
1151+ continue
10861152 # Generate code for the ClassDB singleton under a different name.
10871153 if class_api ["name" ] == "ClassDB" :
10881154 class_api ["name" ] = "ClassDBSingleton"
@@ -1102,6 +1168,9 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
11021168 singletons .append (singleton ["name" ])
11031169
11041170 for class_api in api ["classes" ]:
1171+ if not is_class_included (class_api ["name" ], build_profile ):
1172+ continue
1173+
11051174 # Check used classes for header include.
11061175 used_classes = set ()
11071176 fully_used_classes = set ()
0 commit comments