2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*  gdextension_library_loader.cpp                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                         This file is part of:                          */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                             GODOT ENGINE                               */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                        https://godotengine.org                         */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Permission is hereby granted, free of charge, to any person obtaining  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* a copy of this software and associated documentation files (the        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* "Software"), to deal in the Software without restriction, including    */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* without limitation the rights to use, copy, modify, merge, publish,    */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* distribute, sublicense, and/or sell copies of the Software, and to     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* permit persons to whom the Software is furnished to do so, subject to  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* the following conditions:                                              */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* The above copyright notice and this permission notice shall be         */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* included in all copies or substantial portions of the Software.        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "gdextension_library_loader.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "core/config/project_settings.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "core/io/dir_access.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "core/version.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "gdextension.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Vector < SharedObject >  GDExtensionLibraryLoader : : find_extension_dependencies ( const  String  & p_path ,  Ref < ConfigFile >  p_config ,  std : : function < bool ( String ) >  p_has_feature )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Vector < SharedObject >  dependencies_shared_objects ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( p_config - > has_section ( " dependencies " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-23 23:32:05 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										Vector < String >  config_dependencies  =  p_config - > get_section_keys ( " dependencies " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  ( const  String  & dependency  :  config_dependencies )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Vector < String >  dependency_tags  =  dependency . split ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											bool  all_tags_met  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  ( int  i  =  0 ;  i  <  dependency_tags . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												String  tag  =  dependency_tags [ i ] . strip_edges ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( ! p_has_feature ( tag ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													all_tags_met  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( all_tags_met )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Dictionary  dependency_value  =  p_config - > get_value ( " dependencies " ,  dependency ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												for  ( const  Variant  * key  =  dependency_value . next ( nullptr ) ;  key ;  key  =  dependency_value . next ( key ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													String  dependency_path  =  * key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													String  target_path  =  dependency_value [ * key ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( dependency_path . is_relative_path ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														dependency_path  =  p_path . get_base_dir ( ) . path_join ( dependency_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													dependencies_shared_objects . push_back ( SharedObject ( dependency_path ,  dependency_tags ,  target_path ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  dependencies_shared_objects ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								String  GDExtensionLibraryLoader : : find_extension_library ( const  String  & p_path ,  Ref < ConfigFile >  p_config ,  std : : function < bool ( String ) >  p_has_feature ,  PackedStringArray  * r_tags )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// First, check the explicit libraries.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( p_config - > has_section ( " libraries " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-23 23:32:05 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										Vector < String >  libraries  =  p_config - > get_section_keys ( " libraries " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Iterate the libraries, finding the best matching tags.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										String  best_library_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Vector < String >  best_library_tags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  ( const  String  & E  :  libraries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											Vector < String >  tags  =  E . split ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											bool  all_tags_met  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  ( int  i  =  0 ;  i  <  tags . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												String  tag  =  tags [ i ] . strip_edges ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( ! p_has_feature ( tag ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													all_tags_met  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( all_tags_met  & &  tags . size ( )  >  best_library_tags . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												best_library_path  =  p_config - > get_value ( " libraries " ,  E ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												best_library_tags  =  tags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! best_library_path . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( best_library_path . is_relative_path ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												best_library_path  =  p_path . get_base_dir ( ) . path_join ( best_library_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( r_tags  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												r_tags - > append_array ( best_library_tags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  best_library_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Second, try to autodetect.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									String  autodetect_library_prefix ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( p_config - > has_section_key ( " configuration " ,  " autodetect_library_prefix " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										autodetect_library_prefix  =  p_config - > get_value ( " configuration " ,  " autodetect_library_prefix " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! autodetect_library_prefix . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										String  autodetect_path  =  autodetect_library_prefix ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( autodetect_path . is_relative_path ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											autodetect_path  =  p_path . get_base_dir ( ) . path_join ( autodetect_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Find the folder and file parts of the prefix.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										String  folder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										String  file_prefix ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( DirAccess : : dir_exists_absolute ( autodetect_path ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											folder  =  autodetect_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  if  ( DirAccess : : dir_exists_absolute ( autodetect_path . get_base_dir ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											folder  =  autodetect_path . get_base_dir ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											file_prefix  =  autodetect_path . get_file ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ERR_FAIL_V_MSG ( String ( ) ,  vformat ( " Error in extension: %s. Could not find folder for automatic detection of libraries files. autodetect_library_prefix= \" %s \" " ,  p_path ,  autodetect_library_prefix ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Open the folder.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Ref < DirAccess >  dir  =  DirAccess : : open ( folder ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_FAIL_COND_V_MSG ( dir . is_null ( ) ,  String ( ) ,  vformat ( " Error in extension: %s. Could not open folder for automatic detection of libraries files. autodetect_library_prefix= \" %s \" " ,  p_path ,  autodetect_library_prefix ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Iterate the files and check the prefixes, finding the best matching file.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										String  best_file ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Vector < String >  best_file_tags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										dir - > list_dir_begin ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										String  file_name  =  dir - > _get_next ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										while  ( file_name  ! =  " " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! dir - > current_is_dir ( )  & &  file_name . begins_with ( file_prefix ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												// Check if the files matches all requested feature tags.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												String  tags_str  =  file_name . trim_prefix ( file_prefix ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												tags_str  =  tags_str . trim_suffix ( tags_str . get_extension ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Vector < String >  tags  =  tags_str . split ( " . " ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												bool  all_tags_met  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												for  ( int  i  =  0 ;  i  <  tags . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													String  tag  =  tags [ i ] . strip_edges ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( ! p_has_feature ( tag ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														all_tags_met  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												// If all tags are found in the feature list, and we found more tags than before, use this file.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( all_tags_met  & &  tags . size ( )  >  best_file_tags . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													best_file_tags  =  tags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													best_file  =  file_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											file_name  =  dir - > _get_next ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! best_file . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											String  library_path  =  folder . path_join ( best_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( r_tags  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												r_tags - > append_array ( best_file_tags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  library_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Error  GDExtensionLibraryLoader : : open_library ( const  String  & p_path )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Error  err  =  parse_gdextension_file ( p_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									String  abs_path  =  ProjectSettings : : get_singleton ( ) - > globalize_path ( library_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Vector < String >  abs_dependencies_paths ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! library_dependencies . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  ( const  SharedObject  & dependency  :  library_dependencies )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											abs_dependencies_paths . push_back ( ProjectSettings : : get_singleton ( ) - > globalize_path ( dependency . path ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OS : : GDExtensionData  data  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										true ,  // also_set_library_path
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										& library_path ,  // r_resolved_path
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Engine : : get_singleton ( ) - > is_editor_hint ( ) ,  // generate_temp_files
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										& abs_dependencies_paths ,  // library_dependencies
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									err  =  OS : : get_singleton ( ) - > open_dynamic_library ( is_static_library  ?  String ( )  :  abs_path ,  library ,  & data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Error  GDExtensionLibraryLoader : : initialize ( GDExtensionInterfaceGetProcAddress  p_get_proc_address ,  const  Ref < GDExtension >  & p_extension ,  GDExtensionInitialization  * r_initialization )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef TOOLS_ENABLED 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									p_extension - > set_reloadable ( is_reloadable  & &  Engine : : get_singleton ( ) - > is_extension_reloading_enabled ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( const  KeyValue < String ,  String >  & icon  :  class_icon_paths )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										p_extension - > class_icon_paths [ icon . key ]  =  icon . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									void  * entry_funcptr  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Error  err  =  OS : : get_singleton ( ) - > get_dynamic_library_symbol_handle ( library ,  entry_symbol ,  entry_funcptr ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-11 16:17:49 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ERR_PRINT ( vformat ( " GDExtension entry point '%s' not found in library %s. " ,  entry_symbol ,  library_path ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									GDExtensionInitializationFunction  initialization_function  =  ( GDExtensionInitializationFunction ) entry_funcptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									GDExtensionBool  ret  =  initialization_function ( p_get_proc_address ,  p_extension . ptr ( ) ,  r_initialization ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ret )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-11 16:17:49 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ERR_PRINT ( vformat ( " GDExtension initialization function '%s' returned an error. " ,  entry_symbol ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  GDExtensionLibraryLoader : : close_library ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									OS : : get_singleton ( ) - > close_dynamic_library ( library ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									library  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								bool  GDExtensionLibraryLoader : : is_library_open ( )  const  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  library  ! =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								bool  GDExtensionLibraryLoader : : has_library_changed ( )  const  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef TOOLS_ENABLED 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Check only that the last modified time is different (rather than checking
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// that it's newer) since some OS's (namely Windows) will preserve the modified
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// time by default when copying files.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( FileAccess : : get_modified_time ( resource_path )  ! =  resource_last_modified_time )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( FileAccess : : get_modified_time ( library_path )  ! =  library_last_modified_time )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 09:21:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								bool  GDExtensionLibraryLoader : : library_exists ( )  const  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  FileAccess : : exists ( resource_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								Error  GDExtensionLibraryLoader : : parse_gdextension_file ( const  String  & p_path )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									resource_path  =  p_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Ref < ConfigFile >  config ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									config . instantiate ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Error  err  =  config - > load ( p_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( err  ! =  OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-11 16:17:49 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ERR_PRINT ( vformat ( " Error loading GDExtension configuration file: '%s'. " ,  p_path ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! config - > has_section_key ( " configuration " ,  " entry_symbol " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-11 16:17:49 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ERR_PRINT ( vformat ( " GDExtension configuration file must contain a  \" configuration/entry_symbol \"  key: '%s'. " ,  p_path ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return  ERR_INVALID_DATA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									entry_symbol  =  config - > get_value ( " configuration " ,  " entry_symbol " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									uint32_t  compatibility_minimum [ 3 ]  =  {  0 ,  0 ,  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( config - > has_section_key ( " configuration " ,  " compatibility_minimum " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										String  compat_string  =  config - > get_value ( " configuration " ,  " compatibility_minimum " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Vector < int >  parts  =  compat_string . split_ints ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  ( int  i  =  0 ;  i  <  parts . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( i  > =  3 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( parts [ i ]  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												compatibility_minimum [ i ]  =  parts [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-11 16:17:49 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ERR_PRINT ( vformat ( " GDExtension configuration file must contain a  \" configuration/compatibility_minimum \"  key: '%s'. " ,  p_path ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return  ERR_INVALID_DATA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( compatibility_minimum [ 0 ]  <  4  | |  ( compatibility_minimum [ 0 ]  = =  4  & &  compatibility_minimum [ 1 ]  = =  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_PRINT ( vformat ( " GDExtension's compatibility_minimum (%d.%d.%d) must be at least 4.1.0: %s " ,  compatibility_minimum [ 0 ] ,  compatibility_minimum [ 1 ] ,  compatibility_minimum [ 2 ] ,  p_path ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ERR_INVALID_DATA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bool  compatible  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Check version lexicographically.
 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-03 22:27:29 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( GODOT_VERSION_MAJOR  ! =  compatibility_minimum [ 0 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										compatible  =  GODOT_VERSION_MAJOR  >  compatibility_minimum [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( GODOT_VERSION_MINOR  ! =  compatibility_minimum [ 1 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										compatible  =  GODOT_VERSION_MINOR  >  compatibility_minimum [ 1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-03 22:27:29 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										compatible  =  GODOT_VERSION_PATCH  > =  compatibility_minimum [ 2 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! compatible )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 14:14:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ERR_PRINT ( vformat ( " GDExtension only compatible with Godot version %d.%d.%d or later: %s, but your Godot version is %d.%d.%d " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												compatibility_minimum [ 0 ] ,  compatibility_minimum [ 1 ] ,  compatibility_minimum [ 2 ] ,  p_path , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												GODOT_VERSION_MAJOR ,  GODOT_VERSION_MINOR ,  GODOT_VERSION_PATCH ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return  ERR_INVALID_DATA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Optionally check maximum compatibility.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( config - > has_section_key ( " configuration " ,  " compatibility_maximum " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										uint32_t  compatibility_maximum [ 3 ]  =  {  0 ,  0 ,  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										String  compat_string  =  config - > get_value ( " configuration " ,  " compatibility_maximum " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										Vector < int >  parts  =  compat_string . split_ints ( " . " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  ( int  i  =  0 ;  i  <  3 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( i  <  parts . size ( )  & &  parts [ i ]  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												compatibility_maximum [ i ]  =  parts [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												// If a version part is missing, set the maximum to an arbitrary high value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												compatibility_maximum [ i ]  =  9999 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										compatible  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-03 22:27:29 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( GODOT_VERSION_MAJOR  ! =  compatibility_maximum [ 0 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											compatible  =  GODOT_VERSION_MAJOR  <  compatibility_maximum [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  if  ( GODOT_VERSION_MINOR  ! =  compatibility_maximum [ 1 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											compatible  =  GODOT_VERSION_MINOR  <  compatibility_maximum [ 1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-03 22:27:29 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# if GODOT_VERSION_PATCH 
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										// #if check to avoid -Wtype-limits warning when 0.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										else  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-03-03 22:27:29 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											compatible  =  GODOT_VERSION_PATCH  < =  compatibility_maximum [ 2 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! compatible )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 14:14:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ERR_PRINT ( vformat ( " GDExtension only compatible with Godot version %s or earlier: %s, but your Godot version is %d.%d.%d " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													compat_string ,  p_path ,  GODOT_VERSION_MAJOR ,  GODOT_VERSION_MINOR ,  GODOT_VERSION_PATCH ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return  ERR_INVALID_DATA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									library_path  =  find_extension_library ( p_path ,  config ,  [ ] ( const  String  & p_feature )  {  return  OS : : get_singleton ( ) - > has_feature ( p_feature ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( library_path . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										const  String  os_arch  =  OS : : get_singleton ( ) - > get_name ( ) . to_lower ( )  +  " . "  +  Engine : : get_singleton ( ) - > get_architecture_name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_PRINT ( vformat ( " No GDExtension library found for current OS and architecture (%s) in configuration file: %s " ,  os_arch ,  p_path ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ERR_FILE_NOT_FOUND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									is_static_library  =  library_path . ends_with ( " .a " )  | |  library_path . ends_with ( " .xcframework " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! library_path . is_resource_file ( )  & &  ! library_path . is_absolute_path ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										library_path  =  p_path . get_base_dir ( ) . path_join ( library_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef TOOLS_ENABLED 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									is_reloadable  =  config - > get_value ( " configuration " ,  " reloadable " ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									update_last_modified_time ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											FileAccess : : get_modified_time ( resource_path ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											FileAccess : : get_modified_time ( library_path ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									library_dependencies  =  find_extension_dependencies ( p_path ,  config ,  [ ] ( const  String  & p_feature )  {  return  OS : : get_singleton ( ) - > has_feature ( p_feature ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Handle icons if any are specified.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( config - > has_section ( " icons " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-23 23:32:05 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										Vector < String >  keys  =  config - > get_section_keys ( " icons " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-24 01:32:25 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										for  ( const  String  & key  :  keys )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											String  icon_path  =  config - > get_value ( " icons " ,  key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( icon_path . is_relative_path ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												icon_path  =  p_path . get_base_dir ( ) . path_join ( icon_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											class_icon_paths [ key ]  =  icon_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}