@@ -7,54 +7,9 @@ import subprocess
77from binding_generator import scons_generate_bindings , scons_emit_files
88from SCons .Errors import UserError
99
10- EnsureSConsVersion (4 , 0 )
11-
12-
13- def add_sources (sources , dir , extension ):
14- for f in os .listdir (dir ):
15- if f .endswith ("." + extension ):
16- sources .append (dir + "/" + f )
17-
18-
19- def normalize_path (val ):
20- return val if os .path .isabs (val ) else os .path .join (env .Dir ("#" ).abspath , val )
21-
22-
23- def validate_file (key , val , env ):
24- if not os .path .isfile (normalize_path (val )):
25- raise UserError ("'%s' is not a file: %s" % (key , val ))
26-
27-
28- def validate_dir (key , val , env ):
29- if not os .path .isdir (normalize_path (val )):
30- raise UserError ("'%s' is not a directory: %s" % (key , val ))
31-
32-
33- def validate_parent_dir (key , val , env ):
34- if not os .path .isdir (normalize_path (os .path .dirname (val ))):
35- raise UserError ("'%s' is not a directory: %s" % (key , os .path .dirname (val )))
36-
37-
38- def get_gdextension_dir (env ):
39- return normalize_path (env .get ("gdextension_dir" , env .Dir ("gdextension" ).abspath ))
40-
41-
42- def get_api_file (env ):
43- return normalize_path (env .get ("custom_api_file" , os .path .join (get_gdextension_dir (env ), "extension_api.json" )))
4410
11+ EnsureSConsVersion (4 , 0 )
4512
46- # Try to detect the host platform automatically.
47- # This is used if no `platform` argument is passed
48- if sys .platform .startswith ("linux" ):
49- default_platform = "linux"
50- elif sys .platform == "darwin" :
51- default_platform = "macos"
52- elif sys .platform == "win32" or sys .platform == "msys" :
53- default_platform = "windows"
54- elif ARGUMENTS .get ("platform" , "" ):
55- default_platform = ARGUMENTS .get ("platform" )
56- else :
57- raise ValueError ("Could not detect platform automatically, please specify with platform=<platform>" )
5813
5914try :
6015 Import ("env" )
@@ -65,24 +20,6 @@ except:
6520
6621env .PrependENVPath ("PATH" , os .getenv ("PATH" ))
6722
68- # Default num_jobs to local cpu count if not user specified.
69- # SCons has a peculiarity where user-specified options won't be overridden
70- # by SetOption, so we can rely on this to know if we should use our default.
71- initial_num_jobs = env .GetOption ("num_jobs" )
72- altered_num_jobs = initial_num_jobs + 1
73- env .SetOption ("num_jobs" , altered_num_jobs )
74- if env .GetOption ("num_jobs" ) == altered_num_jobs :
75- cpu_count = os .cpu_count ()
76- if cpu_count is None :
77- print ("Couldn't auto-detect CPU count to configure build parallelism. Specify it with the -j argument." )
78- else :
79- safer_cpu_count = cpu_count if cpu_count <= 4 else cpu_count - 1
80- print (
81- "Auto-detected %d CPU cores available for build parallelism. Using %d cores by default. You can override it with the -j argument."
82- % (cpu_count , safer_cpu_count )
83- )
84- env .SetOption ("num_jobs" , safer_cpu_count )
85-
8623# Custom options and profile flags.
8724customs = ["custom.py" ]
8825profile = ARGUMENTS .get ("profile" , "" )
@@ -92,159 +29,11 @@ if profile:
9229 elif os .path .isfile (profile + ".py" ):
9330 customs .append (profile + ".py" )
9431opts = Variables (customs , ARGUMENTS )
95-
96- platforms = ("linux" , "macos" , "windows" , "android" , "ios" , "javascript" )
97- opts .Add (
98- EnumVariable (
99- key = "platform" ,
100- help = "Target platform" ,
101- default = env .get ("platform" , default_platform ),
102- allowed_values = platforms ,
103- ignorecase = 2 ,
104- )
105- )
106-
107- # Editor and template_debug are compatible (i.e. you can use the same binary for Godot editor builds and Godot debug templates).
108- # Godot release templates are only compatible with "template_release" builds.
109- # For this reason, we default to template_debug builds, unlike Godot which defaults to editor builds.
110- opts .Add (
111- EnumVariable (
112- key = "target" ,
113- help = "Compilation target" ,
114- default = env .get ("target" , "template_debug" ),
115- allowed_values = ("editor" , "template_release" , "template_debug" ),
116- )
117- )
118- opts .Add (
119- PathVariable (
120- key = "gdextension_dir" ,
121- help = "Path to a custom directory containing GDExtension interface header and API JSON file" ,
122- default = env .get ("gdextension_dir" , None ),
123- validator = validate_dir ,
124- )
125- )
126- opts .Add (
127- PathVariable (
128- key = "custom_api_file" ,
129- help = "Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`)" ,
130- default = env .get ("custom_api_file" , None ),
131- validator = validate_file ,
132- )
133- )
134- opts .Add (
135- BoolVariable (
136- key = "generate_bindings" ,
137- help = "Force GDExtension API bindings generation. Auto-detected by default." ,
138- default = env .get ("generate_bindings" , False ),
139- )
140- )
141- opts .Add (
142- BoolVariable (
143- key = "generate_template_get_node" ,
144- help = "Generate a template version of the Node class's get_node." ,
145- default = env .get ("generate_template_get_node" , True ),
146- )
147- )
148-
149- opts .Add (BoolVariable (key = "build_library" , help = "Build the godot-cpp library." , default = env .get ("build_library" , True )))
150- opts .Add (
151- EnumVariable (
152- key = "precision" ,
153- help = "Set the floating-point precision level" ,
154- default = env .get ("precision" , "single" ),
155- allowed_values = ("single" , "double" ),
156- )
157- )
158-
159- # compiledb
160- opts .Add (
161- BoolVariable (
162- key = "compiledb" ,
163- help = "Generate compilation DB (`compile_commands.json`) for external tools" ,
164- default = env .get ("compiledb" , False ),
165- )
166- )
167- opts .Add (
168- PathVariable (
169- key = "compiledb_file" ,
170- help = "Path to a custom `compile_commands.json` file" ,
171- default = env .get ("compiledb_file" , "compile_commands.json" ),
172- validator = validate_parent_dir ,
173- )
174- )
175-
176- # Add platform options
177- tools = {}
178- for pl in platforms :
179- tool = Tool (pl , toolpath = ["tools" ])
180- if hasattr (tool , "options" ):
181- tool .options (opts )
182- tools [pl ] = tool
183-
184- # CPU architecture options.
185- architecture_array = ["" , "universal" , "x86_32" , "x86_64" , "arm32" , "arm64" , "rv64" , "ppc32" , "ppc64" , "wasm32" ]
186- architecture_aliases = {
187- "x64" : "x86_64" ,
188- "amd64" : "x86_64" ,
189- "armv7" : "arm32" ,
190- "armv8" : "arm64" ,
191- "arm64v8" : "arm64" ,
192- "aarch64" : "arm64" ,
193- "rv" : "rv64" ,
194- "riscv" : "rv64" ,
195- "riscv64" : "rv64" ,
196- "ppcle" : "ppc32" ,
197- "ppc" : "ppc32" ,
198- "ppc64le" : "ppc64" ,
199- }
200- opts .Add (
201- EnumVariable (
202- key = "arch" ,
203- help = "CPU architecture" ,
204- default = env .get ("arch" , "" ),
205- allowed_values = architecture_array ,
206- map = architecture_aliases ,
207- )
208- )
209-
210- # Targets flags tool (optimizations, debug symbols)
211- target_tool = Tool ("targets" , toolpath = ["tools" ])
212- target_tool .options (opts )
213-
32+ cpp_tool = Tool ("godotcpp" , toolpath = ["tools" ])
33+ cpp_tool .options (opts , env )
21434opts .Update (env )
215- Help (opts .GenerateHelpText (env ))
216-
217- # Process CPU architecture argument.
218- if env ["arch" ] == "" :
219- # No architecture specified. Default to arm64 if building for Android,
220- # universal if building for macOS or iOS, wasm32 if building for web,
221- # otherwise default to the host architecture.
222- if env ["platform" ] in ["macos" , "ios" ]:
223- env ["arch" ] = "universal"
224- elif env ["platform" ] == "android" :
225- env ["arch" ] = "arm64"
226- elif env ["platform" ] == "javascript" :
227- env ["arch" ] = "wasm32"
228- else :
229- host_machine = platform .machine ().lower ()
230- if host_machine in architecture_array :
231- env ["arch" ] = host_machine
232- elif host_machine in architecture_aliases .keys ():
233- env ["arch" ] = architecture_aliases [host_machine ]
234- elif "86" in host_machine :
235- # Catches x86, i386, i486, i586, i686, etc.
236- env ["arch" ] = "x86_32"
237- else :
238- print ("Unsupported CPU architecture: " + host_machine )
239- Exit ()
24035
241- tool = Tool (env ["platform" ], toolpath = ["tools" ])
242-
243- if tool is None or not tool .exists (env ):
244- raise ValueError ("Required toolchain not found for platform " + env ["platform" ])
245-
246- tool .generate (env )
247- target_tool .generate (env )
36+ Help (opts .GenerateHelpText (env ))
24837
24938# Detect and print a warning listing unknown SCons variables to ease troubleshooting.
25039unknown = opts .UnknownVariables ()
@@ -253,71 +42,12 @@ if unknown:
25342 for item in unknown .items ():
25443 print (" " + item [0 ] + "=" + item [1 ])
25544
256- print ("Building for architecture " + env ["arch" ] + " on platform " + env ["platform" ])
257-
258- # Require C++17
259- if env .get ("is_msvc" , False ):
260- env .Append (CXXFLAGS = ["/std:c++17" ])
261- else :
262- env .Append (CXXFLAGS = ["-std=c++17" ])
263-
264- if env ["precision" ] == "double" :
265- env .Append (CPPDEFINES = ["REAL_T_IS_DOUBLE" ])
266-
267- # compile_commands.json
268- if env .get ("compiledb" , False ):
269- env .Tool ("compilation_db" )
270- env .Alias ("compiledb" , env .CompilationDatabase (normalize_path (env ["compiledb_file" ])))
271-
272- # Generate bindings
273- env .Append (BUILDERS = {"GenerateBindings" : Builder (action = scons_generate_bindings , emitter = scons_emit_files )})
274-
275- bindings = env .GenerateBindings (
276- env .Dir ("." ),
277- [get_api_file (env ), os .path .join (get_gdextension_dir (env ), "gdextension_interface.h" ), "binding_generator.py" ],
278- )
279-
28045scons_cache_path = os .environ .get ("SCONS_CACHE" )
28146if scons_cache_path is not None :
28247 CacheDir (scons_cache_path )
28348 Decider ("MD5" )
28449
285- # Forces bindings regeneration.
286- if env ["generate_bindings" ]:
287- AlwaysBuild (bindings )
288- NoCache (bindings )
289-
290- # Includes
291- env .Append (CPPPATH = [[env .Dir (d ) for d in [get_gdextension_dir (env ), "include" , os .path .join ("gen" , "include" )]]])
292-
293- # Sources to compile
294- sources = []
295- add_sources (sources , "src" , "cpp" )
296- add_sources (sources , "src/classes" , "cpp" )
297- add_sources (sources , "src/core" , "cpp" )
298- add_sources (sources , "src/variant" , "cpp" )
299- sources .extend ([f for f in bindings if str (f ).endswith (".cpp" )])
300-
301- suffix = ".{}.{}" .format (env ["platform" ], env ["target" ])
302- if env .dev_build :
303- suffix += ".dev"
304- if env ["precision" ] == "double" :
305- suffix += ".double"
306- suffix += "." + env ["arch" ]
307- if env ["ios_simulator" ]:
308- suffix += ".simulator"
309-
310- # Expose it when included from another project
311- env ["suffix" ] = suffix
312-
313- library = None
314- env ["OBJSUFFIX" ] = suffix + env ["OBJSUFFIX" ]
315- library_name = "libgodot-cpp{}{}" .format (suffix , env ["LIBSUFFIX" ])
316-
317- if env ["build_library" ]:
318- library = env .StaticLibrary (target = env .File ("bin/%s" % library_name ), source = sources )
319- Default (library )
50+ cpp_tool .generate (env )
51+ library = env .GodotCPP ()
32052
321- env .Append (LIBPATH = [env .Dir ("bin" )])
322- env .Append (LIBS = library_name )
32353Return ("env" )
0 commit comments