Skip to content

Instantly share code, notes, and snippets.

@MarianoGnu
Created November 13, 2021 20:19
Show Gist options
  • Save MarianoGnu/f61a29b32346a70c65d0b7e2f605efa6 to your computer and use it in GitHub Desktop.
Save MarianoGnu/f61a29b32346a70c65d0b7e2f605efa6 to your computer and use it in GitHub Desktop.
@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