Skip to content

Commit a0acdea

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

File tree

3 files changed

+178
-9
lines changed

3 files changed

+178
-9
lines changed

SConstruct

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ opts.Add(BoolVariable("generate_template_get_node", "Generate a template version
124124

125125
opts.Add(BoolVariable("build_library", "Build the godot-cpp library.", True))
126126
opts.Add(EnumVariable("precision", "Set the floating-point precision level", "single", ("single", "double")))
127+
opts.Add("build_profile", "Path to a file containing a feature build profile", "")
127128

128129
# Add platform options
129130
tools = {}

binding_generator.py

+46-9
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,18 @@
33
import json
44
import re
55
import shutil
6+
import sys
67
from pathlib import Path
78

89

10+
def is_class_included(class_name, build_profile):
11+
if "enabled_classes" in build_profile:
12+
return class_name in build_profile["enabled_classes"]
13+
if "disabled_classes" in build_profile:
14+
return class_name not in build_profile["disabled_classes"]
15+
return True
16+
17+
918
def generate_mod_version(argcount, const=False, returns=False):
1019
s = """
1120
#define MODBIND$VER($RETTYPE m_name$ARG) \\
@@ -70,7 +79,7 @@ def generate_wrappers(target):
7079
f.write(txt)
7180

7281

73-
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
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
# TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
101112
if engine_class["name"] == "ClassDB":
102113
continue
@@ -134,31 +145,51 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
134145
return files
135146

136147

137-
def print_file_list(api_filepath, output_dir, headers=False, sources=False):
148+
def print_file_list(api_filepath, output_dir, headers=False, sources=False, build_profile={}):
138149
end = ";"
139-
for f in get_file_list(api_filepath, output_dir, headers, sources):
150+
for f in get_file_list(api_filepath, output_dir, headers, sources, build_profile):
140151
print(f, end=end)
141152

142153

154+
def scons_parse_build_profile(env):
155+
if env["build_profile"] != "":
156+
print("Using feature build profile: " + env["build_profile"])
157+
import json
158+
159+
path = env.File(env["build_profile"]).abspath
160+
try:
161+
ft = json.load(open(path))
162+
return ft
163+
except:
164+
print("Error opening feature build profile: " + path)
165+
sys.exit(255)
166+
return {}
167+
168+
143169
def scons_emit_files(target, source, env):
144-
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)]
170+
build_profile = scons_parse_build_profile(env)
171+
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True, build_profile)]
145172
env.Clean(target, files)
146173
env["godot_cpp_gen_dir"] = target[0].abspath
147174
return files, source
148175

149176

150177
def scons_generate_bindings(target, source, env):
178+
build_profile = scons_parse_build_profile(env)
151179
generate_bindings(
152180
str(source[0]),
153181
env["generate_template_get_node"],
154182
"32" if "32" in env["arch"] else "64",
155183
env["precision"],
156184
env["godot_cpp_gen_dir"],
185+
build_profile,
157186
)
158187
return None
159188

160189

161-
def generate_bindings(api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."):
190+
def generate_bindings(
191+
api_filepath, use_template_get_node, bits="64", precision="single", output_dir=".", build_profile={}
192+
):
162193
api = None
163194

164195
target_dir = Path(output_dir) / "gen"
@@ -175,7 +206,7 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision=
175206
generate_global_constants(api, target_dir)
176207
generate_global_constant_binds(api, target_dir)
177208
generate_builtin_bindings(api, target_dir, real_t + "_" + bits)
178-
generate_engine_classes_bindings(api, target_dir, use_template_get_node)
209+
generate_engine_classes_bindings(api, target_dir, use_template_get_node, build_profile)
179210
generate_utility_functions(api, target_dir)
180211

181212

@@ -1023,7 +1054,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
10231054
return "\n".join(result)
10241055

10251056

1026-
def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
1057+
def generate_engine_classes_bindings(api, output_dir, use_template_get_node, build_profile):
10271058
global engine_classes
10281059
global singletons
10291060
global native_structures
@@ -1036,6 +1067,8 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
10361067

10371068
# First create map of classes and singletons.
10381069
for class_api in api["classes"]:
1070+
if not is_class_included(class_api["name"], build_profile):
1071+
continue
10391072
# TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
10401073
if class_api["name"] == "ClassDB":
10411074
continue
@@ -1048,6 +1081,8 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
10481081
singletons.append(singleton["name"])
10491082

10501083
for class_api in api["classes"]:
1084+
if not is_class_included(class_api["name"], build_profile):
1085+
continue
10511086
# TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
10521087
if class_api["name"] == "ClassDB":
10531088
continue
@@ -1161,7 +1196,7 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
11611196

11621197
register_engine_classes_filename = Path(output_dir) / "src" / "register_engine_classes.cpp"
11631198
with register_engine_classes_filename.open("w+", encoding="utf-8") as source_file:
1164-
source_file.write(generate_register_engine_classes_source(api))
1199+
source_file.write(generate_register_engine_classes_source(api, build_profile))
11651200

11661201
for native_struct in api["native_structures"]:
11671202
struct_name = native_struct["name"]
@@ -1585,11 +1620,13 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
15851620
return "\n".join(result)
15861621

15871622

1588-
def generate_register_engine_classes_source(api):
1623+
def generate_register_engine_classes_source(api, build_profile):
15891624
includes = []
15901625
registrations = []
15911626

15921627
for class_api in api["classes"]:
1628+
if not is_class_included(class_api["name"], build_profile):
1629+
continue
15931630
if class_api["name"] == "ClassDB":
15941631
continue
15951632

test/build_profile.json

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
{
2+
"enabled_classes": [
3+
"Control",
4+
"Image",
5+
"InputEvent",
6+
"InputEventKey",
7+
"Viewport",
8+
"Object",
9+
"FileAccess",
10+
"RefCounted",
11+
"EditorPlugin",
12+
"Node",
13+
"Window",
14+
"Tween",
15+
"SceneTree",
16+
"Texture2D",
17+
"MultiplayerAPI",
18+
"PopupMenu",
19+
"Button",
20+
"EditorUndoRedoManager",
21+
"Script",
22+
"EditorTranslationParserPlugin",
23+
"EditorImportPlugin",
24+
"EditorSceneFormatImporter",
25+
"EditorDebuggerPlugin",
26+
"Camera3D",
27+
"ConfigFile",
28+
"ScriptCreateDialog",
29+
"EditorInspectorPlugin",
30+
"EditorNode3DGizmoPlugin",
31+
"EditorScenePostImportPlugin",
32+
"EditorExportPlugin",
33+
"EditorResourceConversionPlugin",
34+
"EditorInterface",
35+
"WorkerThreadPool",
36+
"XMLParser",
37+
"Texture",
38+
"Resource",
39+
"BaseButton",
40+
"CanvasItem",
41+
"ButtonGroup",
42+
"Material",
43+
"Theme",
44+
"StyleBox",
45+
"Font",
46+
"Shortcut",
47+
"Mesh",
48+
"World2D",
49+
"MultiMesh",
50+
"TextServer",
51+
"Environment",
52+
"Node3D",
53+
"World3D",
54+
"Node3DGizmo",
55+
"CameraAttributes",
56+
"Sky",
57+
"Shader",
58+
"TriangleMesh",
59+
"PhysicsDirectSpaceState2D",
60+
"ConvexPolygonShape3D",
61+
"ConcavePolygonShape3D",
62+
"Shape3D",
63+
"ConfirmationDialog",
64+
"PhysicsShapeQueryParameters2D",
65+
"PhysicsShapeQueryParameters3D",
66+
"EditorExportPlatform",
67+
"AcceptDialog",
68+
"PhysicsRayQueryParameters2D",
69+
"ArrayMesh",
70+
"Camera2D",
71+
"Node2D",
72+
"MethodTweener",
73+
"ViewportTexture",
74+
"Label",
75+
"LabelSettings",
76+
"Popup",
77+
"UndoRedo",
78+
"EditorNode3DGizmo",
79+
"EditorInspector",
80+
"ScriptEditor",
81+
"VBoxContainer",
82+
"EditorSettings",
83+
"EditorSelection",
84+
"EditorResourcePreview",
85+
"EditorPaths",
86+
"EditorFileSystem",
87+
"EditorCommandPalette",
88+
"ResourceImporter",
89+
"EditorDebuggerSession",
90+
"StandardMaterial3D",
91+
"FileSystemDock",
92+
"BoxContainer",
93+
"Container",
94+
"PanelContainer",
95+
"ScriptEditorBase",
96+
"EditorResourcePreviewGenerator",
97+
"ScrollContainer",
98+
"EditorFileSystemDirectory",
99+
"EditorFileSystem",
100+
"SkinReference",
101+
"BaseMaterial3D",
102+
"EditorSyntaxHighlighter",
103+
"VScrollBar",
104+
"HScrollBar",
105+
"ScrollBar",
106+
"Range",
107+
"EditorResourceTooltipPlugin",
108+
"PhysicsPointQueryParameters2D",
109+
"PropertyTweener",
110+
"CallbackTweener",
111+
"Tweener",
112+
"Skin",
113+
"IntervalTweener",
114+
"MultiplayerPeer",
115+
"InputEventWithModifiers",
116+
"SyntaxHighlighter",
117+
"InputEventFromWindow",
118+
"TextureRect",
119+
"PhysicsDirectSpaceState3D",
120+
"PacketPeer",
121+
"TextEdit",
122+
"SceneTreeTimer",
123+
"PackedScene",
124+
"MainLoop",
125+
"SceneState",
126+
"PhysicsRayQueryParameters3D",
127+
"PhysicsPointQueryParameters3D",
128+
"OS",
129+
"Semaphore"
130+
]
131+
}

0 commit comments

Comments
 (0)