void add_item(const String &p_project_path, const String &p_item_type, const String &p_include) { _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Project", "ProjectUtils"); Variant project_path = p_project_path; Variant item_type = p_item_type; Variant include = p_include; const Variant *args[3] = { &project_path, &item_type, &include }; MonoException *exc = NULL; klass->get_method("AddItemToProjectChecked", 3)->invoke(NULL, args, &exc); if (exc) { GDMonoUtils::debug_print_unhandled_exception(exc); ERR_FAIL(); } }
String generate_core_api_project(const String &p_dir, const Vector<String> &p_files) { _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Project", "ProjectGenerator"); Variant dir = p_dir; Variant compile_items = p_files; const Variant *args[2] = { &dir, &compile_items }; MonoException *exc = NULL; MonoObject *ret = klass->get_method("GenCoreApiProject", 2)->invoke(NULL, args, &exc); if (exc) { GDMonoUtils::debug_print_unhandled_exception(exc); ERR_FAIL_V(String()); } return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : String(); }
String generate_game_project(const String &p_dir, const String &p_name, const Vector<String> &p_files) { _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Project", "ProjectGenerator"); Variant dir = p_dir; Variant name = p_name; Variant compile_items = p_files; const Variant *args[3] = { &dir, &name, &compile_items }; MonoObject *ex = NULL; MonoObject *ret = klass->get_method("GenGameProject", 3)->invoke(NULL, args, &ex); if (ex) { mono_print_unhandled_exception(ex); ERR_FAIL_V(String()); } return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : ""; }
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; } }
void GodotSharpExport::_export_begin(const Set<String> &p_features, bool p_debug, const String &p_path, int p_flags) { // TODO right now there is no way to stop the export process with an error ERR_FAIL_COND(!GDMono::get_singleton()->is_runtime_initialized()); ERR_FAIL_NULL(TOOLS_DOMAIN); ERR_FAIL_NULL(GDMono::get_singleton()->get_editor_tools_assembly()); if (FileAccess::exists(GodotSharpDirs::get_project_sln_path())) { String build_config = p_debug ? "Debug" : "Release"; String scripts_metadata_path = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata." + String(p_debug ? "debug" : "release")); Error metadata_err = CSharpProject::generate_scripts_metadata(GodotSharpDirs::get_project_csproj_path(), scripts_metadata_path); ERR_FAIL_COND(metadata_err != OK); ERR_FAIL_COND(!_add_file(scripts_metadata_path, scripts_metadata_path)); // Turn export features into defines Vector<String> godot_defines; for (Set<String>::Element *E = p_features.front(); E; E = E->next()) { godot_defines.push_back(E->get()); } ERR_FAIL_COND(!GodotSharpBuilds::build_project_blocking(build_config, godot_defines)); // Add dependency assemblies Map<String, String> dependencies; String project_dll_name = ProjectSettings::get_singleton()->get("application/config/name"); if (project_dll_name.empty()) { project_dll_name = "UnnamedProject"; } String project_dll_src_dir = GodotSharpDirs::get_res_temp_assemblies_base_dir().plus_file(build_config); String project_dll_src_path = project_dll_src_dir.plus_file(project_dll_name + ".dll"); dependencies.insert(project_dll_name, project_dll_src_path); { MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.ProjectExportDomain"); ERR_FAIL_NULL(export_domain); _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain); _GDMONO_SCOPE_DOMAIN_(export_domain); GDMonoAssembly *scripts_assembly = NULL; bool load_success = GDMono::get_singleton()->load_assembly_from(project_dll_name, project_dll_src_path, &scripts_assembly, /* refonly: */ true); ERR_EXPLAIN("Cannot load refonly assembly: " + project_dll_name); ERR_FAIL_COND(!load_success); Vector<String> search_dirs; GDMonoAssembly::fill_search_dirs(search_dirs, build_config); Error depend_error = _get_assembly_dependencies(scripts_assembly, search_dirs, dependencies); ERR_FAIL_COND(depend_error != OK); } for (Map<String, String>::Element *E = dependencies.front(); E; E = E->next()) { String depend_src_path = E->value(); String depend_dst_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(depend_src_path.get_file()); ERR_FAIL_COND(!_add_file(depend_src_path, depend_dst_path)); } } // Mono specific export template extras (data dir) GDMonoClass *export_class = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Editor", "GodotSharpExport"); ERR_FAIL_NULL(export_class); GDMonoMethod *export_begin_method = export_class->get_method("_ExportBegin", 4); ERR_FAIL_NULL(export_begin_method); MonoArray *features = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), p_features.size()); int i = 0; for (const Set<String>::Element *E = p_features.front(); E; E = E->next()) { MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E->get()); mono_array_set(features, MonoString *, i, boxed); i++; } MonoBoolean debug = p_debug; MonoString *path = GDMonoMarshal::mono_string_from_godot(p_path); uint32_t flags = p_flags; void *args[4] = { features, &debug, path, &flags }; MonoException *exc = NULL; export_begin_method->invoke_raw(NULL, args, &exc); if (exc) { GDMonoUtils::debug_print_unhandled_exception(exc); ERR_FAIL(); } }