Created
November 13, 2021 20:19
-
-
Save MarianoGnu/f61a29b32346a70c65d0b7e2f605efa6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@tool | |
extends EditorPlugin | |
const MODULES_PATH = "res://modules/" | |
const SETTING_GODOT_CPP_PATH = "gd_extensions/build_tool/godot_cpp_path" | |
const SETTING_GENERATE_VSPROJ = "gd_extensions/build_tool/generate_vsproj" | |
const SETTING_EXTRA_BUILD_ARGS = "gd_extensions/build_tool/extra_build_args" | |
var godot_cpp_path : String | |
func _build() -> bool: | |
if (!settings()): | |
push_warning("Can't access editor settings, skipping build of GdExtensions") | |
return true | |
if !settings().has_setting(SETTING_GODOT_CPP_PATH) || settings().get_setting(SETTING_GODOT_CPP_PATH) == "": | |
# module is not setled up, ignore | |
push_warning("GdExtensions build tool settings are not configured, skipping build of GdExtensions") | |
return true | |
godot_cpp_path = settings().get_setting(SETTING_GODOT_CPP_PATH) | |
var dir := Directory.new() | |
if !dir.dir_exists(godot_cpp_path): | |
# module is not setled up, ignore | |
push_error("GdExtensions build tool cannot locate the godot-cpp repository on the specified location '" + godot_cpp_path + "'") | |
return false | |
if !dir.dir_exists(MODULES_PATH): | |
# no modules exists, skip | |
return true | |
if dir.open(MODULES_PATH) == OK: | |
dir.list_dir_begin() | |
var folder_name = dir.get_next() | |
while folder_name != "": | |
if dir.current_is_dir(): | |
if !_build_extension(folder_name): | |
return false | |
folder_name = dir.get_next() | |
else: | |
print("An error occurred when trying to access the path.") | |
return false | |
return true | |
func _build_extension(folder_name: String, target: String = "debug") -> bool: | |
# res://modules/example/ | |
var extension_path = MODULES_PATH + folder_name + "/" | |
# res://modules/example/example.gdextension | |
var extension_main_file = MODULES_PATH + folder_name + "/" + folder_name + ".gdextension" | |
var dir := Directory.new() | |
if !dir.file_exists(extension_main_file): | |
# Not a GdExtension folder, skip | |
return true | |
var extension_settings := ConfigFile.new() | |
if extension_settings.load(extension_main_file) != OK: | |
push_error("Failed to build extension '%s', could not load gdextension file '%s'" % [folder_name, extension_main_file]) | |
return false | |
#-j32 platform=windows bits=64 target=debug vsproj=yes cpp_bindings_path="E:/godot-cpp/" target_name="park_game" | |
var platform := OS.get_name().to_lower() | |
var build_args : Array[String] | |
build_args.push_back("target=%s" % target) | |
build_args.push_back('cpp_bindings_path="%s"' % godot_cpp_path) | |
build_args.push_back('target_name="%s"' % folder_name) | |
build_args.push_back("platform=" + platform) | |
if settings().has_setting(SETTING_EXTRA_BUILD_ARGS + "." + platform): | |
# Use platform specific override | |
print("Extra arguments: ", settings().get_setting(SETTING_EXTRA_BUILD_ARGS + "." + platform)) | |
build_args.push_back(settings().get_setting(SETTING_EXTRA_BUILD_ARGS + "." + platform)) | |
elif settings().get_setting(SETTING_EXTRA_BUILD_ARGS) != "": | |
print("Extra arguments: ", settings().get_setting(SETTING_EXTRA_BUILD_ARGS)) | |
build_args.push_back(settings().get_setting(SETTING_EXTRA_BUILD_ARGS)) | |
if platform == "windows" && bool(settings().get_setting(SETTING_GENERATE_VSPROJ)): | |
build_args.push_back("vsproj=yes") | |
var global_folder = ProjectSettings.globalize_path(extension_path) | |
var command_line := "scons " + " ".join(build_args) | |
print("Building module '%s' with target '%s' and command:" % [global_folder, target]) | |
print(command_line) | |
var complete_command_line := 'cd "%s" && %s' % [global_folder, command_line] | |
var output = [] | |
var result = -1 | |
if platform == "windows": | |
# Windows require to set the drive first | |
# drive will always be the first 2 letters of the global folder | |
complete_command_line = global_folder.left(2) + " && " + complete_command_line | |
print(complete_command_line) | |
result = OS.execute("CMD.exe", ["/C", complete_command_line], output, true) | |
else: | |
result = OS.execute(complete_command_line, [], output, true) | |
for line in output: | |
print(line) | |
return result == OK | |
func _enter_tree() -> void: | |
if is_instance_valid(settings()): | |
if !settings().has_setting(SETTING_GODOT_CPP_PATH): | |
settings().set_setting(SETTING_GODOT_CPP_PATH, "") | |
var property_info = { | |
"name": SETTING_GODOT_CPP_PATH, | |
"type": TYPE_STRING, | |
"hint": PROPERTY_HINT_GLOBAL_DIR, | |
"hint_string": "" | |
} | |
settings().add_property_info(property_info) | |
if !settings().has_setting(SETTING_GENERATE_VSPROJ): | |
settings().set_setting(SETTING_GENERATE_VSPROJ, false) | |
var property_info = { | |
"name": SETTING_GODOT_CPP_PATH, | |
"type": TYPE_BOOL, | |
"hint": PROPERTY_HINT_NONE, | |
"hint_string": "" | |
} | |
settings().add_property_info(property_info) | |
if !settings().has_setting(SETTING_EXTRA_BUILD_ARGS): | |
settings().set_setting(SETTING_EXTRA_BUILD_ARGS, "-j8") | |
var property_info = { | |
"name": SETTING_EXTRA_BUILD_ARGS, | |
"type": TYPE_STRING, | |
"hint": PROPERTY_HINT_NONE, | |
"hint_string": "" | |
} | |
settings().add_property_info(property_info) | |
func _exit_tree() -> void: | |
pass | |
func settings() -> EditorSettings: | |
return get_editor_interface().get_editor_settings() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment