@@ -7,49 +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_api_file (key , val , env ):
24-  if  not  os .path .isfile (normalize_path (val )):
25-  raise  UserError ("GDExtension API file ('%s') does not exist: %s"  %  (key , val ))
26- 
27- 
28- def  validate_gdextension_dir (key , val , env ):
29-  if  not  os .path .isdir (normalize_path (val )):
30-  raise  UserError ("GDExtension directory ('%s') does not exist: %s"  %  (key , val ))
31- 
32- 
33- def  get_gdextension_dir (env ):
34-  return  normalize_path (env .get ("gdextension_dir" , env .Dir ("gdextension" ).abspath ))
35- 
36- 
37- def  get_api_file (env ):
38-  return  normalize_path (env .get ("custom_api_file" , os .path .join (get_gdextension_dir (env ), "extension_api.json" )))
3910
11+ EnsureSConsVersion (4 , 0 )
4012
41- # Try to detect the host platform automatically. 
42- # This is used if no `platform` argument is passed 
43- if  sys .platform .startswith ("linux" ):
44-  default_platform  =  "linux" 
45- elif  sys .platform  ==  "darwin" :
46-  default_platform  =  "macos" 
47- elif  sys .platform  ==  "win32"  or  sys .platform  ==  "msys" :
48-  default_platform  =  "windows" 
49- elif  ARGUMENTS .get ("platform" , "" ):
50-  default_platform  =  ARGUMENTS .get ("platform" )
51- else :
52-  raise  ValueError ("Could not detect platform automatically, please specify with platform=<platform>" )
5313
5414try :
5515 Import ("env" )
@@ -60,24 +20,6 @@ except:
6020
6121env .PrependENVPath ("PATH" , os .getenv ("PATH" ))
6222
63- # Default num_jobs to local cpu count if not user specified. 
64- # SCons has a peculiarity where user-specified options won't be overridden 
65- # by SetOption, so we can rely on this to know if we should use our default. 
66- initial_num_jobs  =  env .GetOption ("num_jobs" )
67- altered_num_jobs  =  initial_num_jobs  +  1 
68- env .SetOption ("num_jobs" , altered_num_jobs )
69- if  env .GetOption ("num_jobs" ) ==  altered_num_jobs :
70-  cpu_count  =  os .cpu_count ()
71-  if  cpu_count  is  None :
72-  print ("Couldn't auto-detect CPU count to configure build parallelism. Specify it with the -j argument." )
73-  else :
74-  safer_cpu_count  =  cpu_count  if  cpu_count  <=  4  else  cpu_count  -  1 
75-  print (
76-  "Auto-detected %d CPU cores available for build parallelism. Using %d cores by default. You can override it with the -j argument." 
77-  %  (cpu_count , safer_cpu_count )
78-  )
79-  env .SetOption ("num_jobs" , safer_cpu_count )
80- 
8123# Custom options and profile flags. 
8224customs  =  ["custom.py" ]
8325profile  =  ARGUMENTS .get ("profile" , "" )
@@ -87,142 +29,11 @@ if profile:
8729 elif  os .path .isfile (profile  +  ".py" ):
8830 customs .append (profile  +  ".py" )
8931opts  =  Variables (customs , ARGUMENTS )
90- 
91- platforms  =  ("linux" , "macos" , "windows" , "android" , "ios" , "javascript" )
92- opts .Add (
93-  EnumVariable (
94-  key = "platform" ,
95-  help = "Target platform" ,
96-  default = env .get ("platform" , default_platform ),
97-  allowed_values = platforms ,
98-  ignorecase = 2 ,
99-  )
100- )
101- 
102- # Editor and template_debug are compatible (i.e. you can use the same binary for Godot editor builds and Godot debug templates). 
103- # Godot release templates are only compatible with "template_release" builds. 
104- # For this reason, we default to template_debug builds, unlike Godot which defaults to editor builds. 
105- opts .Add (
106-  EnumVariable (
107-  key = "target" ,
108-  help = "Compilation target" ,
109-  default = env .get ("target" , "template_debug" ),
110-  allowed_values = ("editor" , "template_release" , "template_debug" ),
111-  )
112- )
113- opts .Add (
114-  PathVariable (
115-  key = "gdextension_dir" ,
116-  help = "Path to a custom directory containing GDExtension interface header and API JSON file" ,
117-  default = env .get ("gdextension_dir" , None ),
118-  validator = validate_gdextension_dir ,
119-  )
120- )
121- opts .Add (
122-  PathVariable (
123-  key = "custom_api_file" ,
124-  help = "Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`)" ,
125-  default = env .get ("custom_api_file" , None ),
126-  validator = validate_api_file ,
127-  )
128- )
129- opts .Add (
130-  BoolVariable (
131-  key = "generate_bindings" ,
132-  help = "Force GDExtension API bindings generation. Auto-detected by default." ,
133-  default = env .get ("generate_bindings" , False ),
134-  )
135- )
136- opts .Add (
137-  BoolVariable (
138-  key = "generate_template_get_node" ,
139-  help = "Generate a template version of the Node class's get_node." ,
140-  default = env .get ("generate_template_get_node" , True ),
141-  )
142- )
143- 
144- opts .Add (BoolVariable (key = "build_library" , help = "Build the godot-cpp library." , default = env .get ("build_library" , True )))
145- opts .Add (
146-  EnumVariable (
147-  key = "precision" ,
148-  help = "Set the floating-point precision level" ,
149-  default = env .get ("precision" , "single" ),
150-  allowed_values = ("single" , "double" ),
151-  )
152- )
153- 
154- # Add platform options 
155- tools  =  {}
156- for  pl  in  platforms :
157-  tool  =  Tool (pl , toolpath = ["tools" ])
158-  if  hasattr (tool , "options" ):
159-  tool .options (opts )
160-  tools [pl ] =  tool 
161- 
162- # CPU architecture options. 
163- architecture_array  =  ["" , "universal" , "x86_32" , "x86_64" , "arm32" , "arm64" , "rv64" , "ppc32" , "ppc64" , "wasm32" ]
164- architecture_aliases  =  {
165-  "x64" : "x86_64" ,
166-  "amd64" : "x86_64" ,
167-  "armv7" : "arm32" ,
168-  "armv8" : "arm64" ,
169-  "arm64v8" : "arm64" ,
170-  "aarch64" : "arm64" ,
171-  "rv" : "rv64" ,
172-  "riscv" : "rv64" ,
173-  "riscv64" : "rv64" ,
174-  "ppcle" : "ppc32" ,
175-  "ppc" : "ppc32" ,
176-  "ppc64le" : "ppc64" ,
177- }
178- opts .Add (
179-  EnumVariable (
180-  key = "arch" ,
181-  help = "CPU architecture" ,
182-  default = env .get ("arch" , "" ),
183-  allowed_values = architecture_array ,
184-  map = architecture_aliases ,
185-  )
186- )
187- 
188- # Targets flags tool (optimizations, debug symbols) 
189- target_tool  =  Tool ("targets" , toolpath = ["tools" ])
190- target_tool .options (opts )
191- 
32+ cpp_tool  =  Tool ("godotcpp" , toolpath = ["tools" ])
33+ cpp_tool .options (opts , env )
19234opts .Update (env )
193- Help (opts .GenerateHelpText (env ))
194- 
195- # Process CPU architecture argument. 
196- if  env ["arch" ] ==  "" :
197-  # No architecture specified. Default to arm64 if building for Android, 
198-  # universal if building for macOS or iOS, wasm32 if building for web, 
199-  # otherwise default to the host architecture. 
200-  if  env ["platform" ] in  ["macos" , "ios" ]:
201-  env ["arch" ] =  "universal" 
202-  elif  env ["platform" ] ==  "android" :
203-  env ["arch" ] =  "arm64" 
204-  elif  env ["platform" ] ==  "javascript" :
205-  env ["arch" ] =  "wasm32" 
206-  else :
207-  host_machine  =  platform .machine ().lower ()
208-  if  host_machine  in  architecture_array :
209-  env ["arch" ] =  host_machine 
210-  elif  host_machine  in  architecture_aliases .keys ():
211-  env ["arch" ] =  architecture_aliases [host_machine ]
212-  elif  "86"  in  host_machine :
213-  # Catches x86, i386, i486, i586, i686, etc. 
214-  env ["arch" ] =  "x86_32" 
215-  else :
216-  print ("Unsupported CPU architecture: "  +  host_machine )
217-  Exit ()
21835
219- tool  =  Tool (env ["platform" ], toolpath = ["tools" ])
220- 
221- if  tool  is  None  or  not  tool .exists (env ):
222-  raise  ValueError ("Required toolchain not found for platform "  +  env ["platform" ])
223- 
224- tool .generate (env )
225- target_tool .generate (env )
36+ Help (opts .GenerateHelpText (env ))
22637
22738# Detect and print a warning listing unknown SCons variables to ease troubleshooting. 
22839unknown  =  opts .UnknownVariables ()
@@ -231,66 +42,12 @@ if unknown:
23142 for  item  in  unknown .items ():
23243 print (" "  +  item [0 ] +  "="  +  item [1 ])
23344
234- print ("Building for architecture "  +  env ["arch" ] +  " on platform "  +  env ["platform" ])
235- 
236- # Require C++17 
237- if  env .get ("is_msvc" , False ):
238-  env .Append (CXXFLAGS = ["/std:c++17" ])
239- else :
240-  env .Append (CXXFLAGS = ["-std=c++17" ])
241- 
242- if  env ["precision" ] ==  "double" :
243-  env .Append (CPPDEFINES = ["REAL_T_IS_DOUBLE" ])
244- 
245- # Generate bindings 
246- env .Append (BUILDERS = {"GenerateBindings" : Builder (action = scons_generate_bindings , emitter = scons_emit_files )})
247- 
248- bindings  =  env .GenerateBindings (
249-  env .Dir ("." ),
250-  [get_api_file (env ), os .path .join (get_gdextension_dir (env ), "gdextension_interface.h" ), "binding_generator.py" ],
251- )
252- 
25345scons_cache_path  =  os .environ .get ("SCONS_CACHE" )
25446if  scons_cache_path  is  not None :
25547 CacheDir (scons_cache_path )
25648 Decider ("MD5" )
25749
258- # Forces bindings regeneration. 
259- if  env ["generate_bindings" ]:
260-  AlwaysBuild (bindings )
261-  NoCache (bindings )
262- 
263- # Includes 
264- env .Append (CPPPATH = [[env .Dir (d ) for  d  in  [get_gdextension_dir (env ), "include" , os .path .join ("gen" , "include" )]]])
265- 
266- # Sources to compile 
267- sources  =  []
268- add_sources (sources , "src" , "cpp" )
269- add_sources (sources , "src/classes" , "cpp" )
270- add_sources (sources , "src/core" , "cpp" )
271- add_sources (sources , "src/variant" , "cpp" )
272- sources .extend ([f  for  f  in  bindings  if  str (f ).endswith (".cpp" )])
273- 
274- suffix  =  ".{}.{}" .format (env ["platform" ], env ["target" ])
275- if  env .dev_build :
276-  suffix  +=  ".dev" 
277- if  env ["precision" ] ==  "double" :
278-  suffix  +=  ".double" 
279- suffix  +=  "."  +  env ["arch" ]
280- if  env ["ios_simulator" ]:
281-  suffix  +=  ".simulator" 
282- 
283- # Expose it when included from another project 
284- env ["suffix" ] =  suffix 
285- 
286- library  =  None 
287- env ["OBJSUFFIX" ] =  suffix  +  env ["OBJSUFFIX" ]
288- library_name  =  "libgodot-cpp{}{}" .format (suffix , env ["LIBSUFFIX" ])
289- 
290- if  env ["build_library" ]:
291-  library  =  env .StaticLibrary (target = env .File ("bin/%s"  %  library_name ), source = sources )
292-  Default (library )
50+ cpp_tool .generate (env )
51+ library  =  env .GodotCPP ()
29352
294- env .Append (LIBPATH = [env .Dir ("bin" )])
295- env .Append (LIBS = library_name )
29653Return ("env" )
0 commit comments