@@ -70,12 +70,14 @@ def generate_wrappers(target):
70
70
f .write (txt )
71
71
72
72
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 = "" ):
74
74
api = {}
75
75
files = []
76
76
with open (api_filepath , encoding = "utf-8" ) as api_file :
77
77
api = json .load (api_file )
78
78
79
+ build_profile = parse_build_profile (profile_filepath , api )
80
+
79
81
core_gen_folder = Path (output_dir ) / "gen" / "include" / "godot_cpp" / "core"
80
82
include_gen_folder = Path (output_dir ) / "gen" / "include" / "godot_cpp"
81
83
source_gen_folder = Path (output_dir ) / "gen" / "src"
@@ -105,7 +107,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
105
107
source_filename = source_gen_folder / "classes" / (camel_to_snake (engine_class ["name" ]) + ".cpp" )
106
108
if headers :
107
109
files .append (str (header_filename .as_posix ()))
108
- if sources :
110
+ if sources and is_class_included ( engine_class [ "name" ], build_profile ) :
109
111
files .append (str (source_filename .as_posix ()))
110
112
111
113
for native_struct in api ["native_structures" ]:
@@ -137,12 +139,72 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
137
139
return files
138
140
139
141
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 , profile_filepath ), 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
+ }
142
200
143
201
144
202
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 )]
146
208
env .Clean (target , files )
147
209
env ["godot_cpp_gen_dir" ] = target [0 ].abspath
148
210
return files , source
@@ -2301,6 +2363,20 @@ def is_refcounted(type_name):
2301
2363
return type_name in engine_classes and engine_classes [type_name ]
2302
2364
2303
2365
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
+
2304
2380
def is_included (type_name , current_type ):
2305
2381
"""
2306
2382
Check if a builtin type should be included.
0 commit comments