@@ -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