void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) exit_code = -1; String logs_dir = GodotSharpDirs::get_build_logs_dir().plus_file(build_info.solution.md5_text() + "_" + build_info.configuration); if (build_tab) { build_tab->on_build_start(); } else { build_tab = memnew(MonoBuildTab(build_info, logs_dir)); MonoBottomPanel::get_singleton()->add_build_tab(build_tab); } if (p_blocking) { // Required in order to update the build tasks list Main::iteration(); } if (!exited) { exited = true; String message = "Tried to start build process, but it is already running"; build_tab->on_build_exec_failed(message); ERR_EXPLAIN(message); ERR_FAIL(); } exited = false; // Remove old issues file String issues_file = "msbuild_issues.csv"; DirAccessRef d = DirAccess::create_for_path(logs_dir); if (d->file_exists(issues_file)) { Error err = d->remove(issues_file); if (err != OK) { exited = true; String file_path = ProjectSettings::get_singleton()->localize_path(logs_dir).plus_file(issues_file); String message = "Cannot remove issues file: " + file_path; build_tab->on_build_exec_failed(message); ERR_EXPLAIN(message); ERR_FAIL(); } } GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Build", "BuildInstance"); MonoObject *mono_object = mono_object_new(mono_domain_get(), klass->get_raw()); // Construct Variant solution = build_info.solution; Variant config = build_info.configuration; const Variant *ctor_args[2] = { &solution, &config }; MonoObject *ex = NULL; GDMonoMethod *ctor = klass->get_method(".ctor", 2); ctor->invoke(mono_object, ctor_args, &ex); if (ex) { exited = true; String message = "The build constructor threw an exception.\n" + GDMonoUtils::get_exception_name_and_message(ex); build_tab->on_build_exec_failed(message); ERR_EXPLAIN(message); ERR_FAIL(); } // Call Build Variant logger_assembly = OS::get_singleton()->get_executable_path().get_base_dir().plus_file(EDITOR_TOOLS_ASSEMBLY_NAME) + ".dll"; Variant logger_output_dir = logs_dir; Variant custom_props = build_info.custom_props; const Variant *args[3] = { &logger_assembly, &logger_output_dir, &custom_props }; ex = NULL; GDMonoMethod *build_method = klass->get_method(p_blocking ? "Build" : "BuildAsync", 3); build_method->invoke(mono_object, args, &ex); if (ex) { exited = true; String message = "The build method threw an exception.\n" + GDMonoUtils::get_exception_name_and_message(ex); build_tab->on_build_exec_failed(message); ERR_EXPLAIN(message); ERR_FAIL(); } // Build returned if (p_blocking) { exited = true; exit_code = klass->get_field("exitCode")->get_int_value(mono_object); if (exit_code != 0 && OS::get_singleton()->is_stdout_verbose()) OS::get_singleton()->print(String("MSBuild finished with exit code " + itos(exit_code) + "\n").utf8()); build_tab->on_build_exit(exit_code == 0 ? MonoBuildTab::RESULT_SUCCESS : MonoBuildTab::RESULT_ERROR); } else { build_instance = MonoGCHandle::create_strong(mono_object); exited = false; } }