Ejemplo n.º 1
0
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;
	}
}