Skip to content

Commit 0b9fd7e

Browse files
committed
Merge pull request godotengine#102627 from raulsntos/dotnet/android-export-validate-tfm
C#: Validate project TFM for Android template exports
2 parents 9c7a42b + 70ff213 commit 0b9fd7e

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

platform/android/export/export_plugin.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
#include "modules/modules_enabled.gen.h" // For mono.
5656
#include "modules/svg/image_loader_svg.h"
5757

58+
#ifdef MODULE_MONO_ENABLED
59+
#include "modules/mono/utils/path_utils.h"
60+
#endif
61+
5862
#ifdef ANDROID_ENABLED
5963
#include "../os_android.h"
6064
#endif
@@ -2526,6 +2530,43 @@ bool EditorExportPlatformAndroid::has_valid_username_and_password(const Ref<Edit
25262530
return valid;
25272531
}
25282532

2533+
#ifdef MODULE_MONO_ENABLED
2534+
bool _validate_dotnet_tfm(const String &required_tfm, String &r_error) {
2535+
String assembly_name = path::get_csharp_project_name();
2536+
String project_path = ProjectSettings::get_singleton()->globalize_path("res://" + assembly_name + ".csproj");
2537+
2538+
if (!FileAccess::exists(project_path)) {
2539+
return true;
2540+
}
2541+
2542+
String pipe;
2543+
List<String> args;
2544+
args.push_back("build");
2545+
args.push_back(project_path);
2546+
args.push_back("--getProperty:TargetFramework");
2547+
2548+
int exitcode;
2549+
Error err = OS::get_singleton()->execute("dotnet", args, &pipe, &exitcode, true);
2550+
if (err != OK || exitcode != 0) {
2551+
if (err != OK) {
2552+
WARN_PRINT("Failed to execute dotnet command. Error " + String(error_names[err]));
2553+
} else if (exitcode != 0) {
2554+
print_line(pipe);
2555+
WARN_PRINT("dotnet command exited with code " + itos(exitcode) + ". See output above for more details.");
2556+
}
2557+
r_error += vformat(TTR("Unable to determine the C# project's TFM, it may be incompatible. The export template only supports '%s'. Make sure the project targets '%s' or consider using gradle builds instead."), required_tfm, required_tfm) + "\n";
2558+
} else {
2559+
String tfm = pipe.strip_edges();
2560+
if (tfm != required_tfm) {
2561+
r_error += vformat(TTR("C# project targets '%s' but the export template only supports '%s'. Consider using gradle builds instead."), tfm, required_tfm) + "\n";
2562+
return false;
2563+
}
2564+
}
2565+
2566+
return true;
2567+
}
2568+
#endif
2569+
25292570
bool EditorExportPlatformAndroid::has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug) const {
25302571
String err;
25312572
bool valid = false;
@@ -2534,6 +2575,15 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Ref<Edito
25342575
#ifdef MODULE_MONO_ENABLED
25352576
// Android export is still a work in progress, keep a message as a warning.
25362577
err += TTR("Exporting to Android when using C#/.NET is experimental.") + "\n";
2578+
2579+
if (!gradle_build_enabled) {
2580+
// For template exports we only support .NET 8 because the template
2581+
// includes .jar dependencies that may only be compatible with .NET 8.
2582+
if (!_validate_dotnet_tfm("net8.0", err)) {
2583+
r_error = err;
2584+
return false;
2585+
}
2586+
}
25372587
#endif
25382588

25392589
// Look for export templates (first official, and if defined custom templates).

0 commit comments

Comments
 (0)