diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2022-10-12 22:52:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-12 22:52:59 +0200 |
commit | f2248969db7e5cb8463f323160bed8d00aae7629 (patch) | |
tree | 9baeaa0000cc4adfa5a496de093ab5aee88af702 /modules/mono | |
parent | ea47e03b360d0aeee10c1f7ef798f5750c2b1aa8 (diff) | |
parent | 6daf4c659303c148c2c84d5cc04214eee0ee3654 (diff) |
Merge pull request #66952 from bruvzg/macos_net_export
Fix macOS .NET export.
Diffstat (limited to 'modules/mono')
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs | 118 | ||||
-rw-r--r-- | modules/mono/godotsharp_dirs.cpp | 152 | ||||
-rw-r--r-- | modules/mono/godotsharp_dirs.h | 16 |
3 files changed, 87 insertions, 199 deletions
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 0d2bea2363..745a8b73f8 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -17,6 +17,8 @@ namespace GodotTools.Export { public partial class ExportPlugin : EditorExportPlugin { + private List<string> _tempFolders = new List<string>(); + public void RegisterExportSettings() { // TODO: These would be better as export preset options, but that doesn't seem to be supported yet @@ -111,62 +113,78 @@ namespace GodotTools.Export string buildConfig = isDebug ? "ExportDebug" : "ExportRelease"; - // TODO: This works for now, as we only implemented support for x86 family desktop so far, but it needs to be fixed - string arch = features.Contains("x86_64") ? "x86_64" : "x86"; - - string ridOS = DetermineRuntimeIdentifierOS(platform); - string ridArch = DetermineRuntimeIdentifierArch(arch); - string runtimeIdentifier = $"{ridOS}-{ridArch}"; - - // Create temporary publish output directory - - string publishOutputTempDir = Path.Combine(Path.GetTempPath(), "godot-publish-dotnet", - $"{Process.GetCurrentProcess().Id}-{buildConfig}-{runtimeIdentifier}"); - - if (!Directory.Exists(publishOutputTempDir)) - Directory.CreateDirectory(publishOutputTempDir); - - // Execute dotnet publish - - if (!BuildManager.PublishProjectBlocking(buildConfig, platform, - runtimeIdentifier, publishOutputTempDir)) + var archs = new List<string>(); + if (features.Contains("x86_64")) { - throw new InvalidOperationException("Failed to build project."); + archs.Add("x86_64"); } - - string soExt = ridOS switch + else if (features.Contains("x86_32")) { - OS.DotNetOS.Win or OS.DotNetOS.Win10 => "dll", - OS.DotNetOS.OSX or OS.DotNetOS.iOS => "dylib", - _ => "so" - }; - - if (!File.Exists(Path.Combine(publishOutputTempDir, $"{GodotSharpDirs.ProjectAssemblyName}.dll")) - // NativeAOT shared library output - && !File.Exists(Path.Combine(publishOutputTempDir, $"{GodotSharpDirs.ProjectAssemblyName}.{soExt}"))) + archs.Add("x86_32"); + } + else if (features.Contains("arm64")) { - throw new NotSupportedException( - "Publish succeeded but project assembly not found in the output directory"); + archs.Add("arm64"); } - - // Copy all files from the dotnet publish output directory to - // a data directory next to the Godot output executable. - - string outputDataDir = Path.Combine(outputDir, DetermineDataDirNameForProject()); - - if (Directory.Exists(outputDataDir)) - Directory.Delete(outputDataDir, recursive: true); // Clean first - - Directory.CreateDirectory(outputDataDir); - - foreach (string dir in Directory.GetDirectories(publishOutputTempDir, "*", SearchOption.AllDirectories)) + else if (features.Contains("universal")) { - Directory.CreateDirectory(Path.Combine(outputDataDir, dir.Substring(publishOutputTempDir.Length + 1))); + if (platform == OS.Platforms.MacOS) + { + archs.Add("x86_64"); + archs.Add("arm64"); + } } - foreach (string file in Directory.GetFiles(publishOutputTempDir, "*", SearchOption.AllDirectories)) + foreach (var arch in archs) { - File.Copy(file, Path.Combine(outputDataDir, file.Substring(publishOutputTempDir.Length + 1))); + string ridOS = DetermineRuntimeIdentifierOS(platform); + string ridArch = DetermineRuntimeIdentifierArch(arch); + string runtimeIdentifier = $"{ridOS}-{ridArch}"; + string projectDataDirName = $"{DetermineDataDirNameForProject()}_{arch}"; + if (platform == OS.Platforms.MacOS) + { + projectDataDirName = Path.Combine("Contents", "Resources", projectDataDirName); + } + + // Create temporary publish output directory + + string publishOutputTempDir = Path.Combine(Path.GetTempPath(), "godot-publish-dotnet", + $"{Process.GetCurrentProcess().Id}-{buildConfig}-{runtimeIdentifier}"); + + _tempFolders.Add(publishOutputTempDir); + + if (!Directory.Exists(publishOutputTempDir)) + Directory.CreateDirectory(publishOutputTempDir); + + // Execute dotnet publish + + if (!BuildManager.PublishProjectBlocking(buildConfig, platform, + runtimeIdentifier, publishOutputTempDir)) + { + throw new InvalidOperationException("Failed to build project."); + } + + string soExt = ridOS switch + { + OS.DotNetOS.Win or OS.DotNetOS.Win10 => "dll", + OS.DotNetOS.OSX or OS.DotNetOS.iOS => "dylib", + _ => "so" + }; + + if (!File.Exists(Path.Combine(publishOutputTempDir, $"{GodotSharpDirs.ProjectAssemblyName}.dll")) + // NativeAOT shared library output + && !File.Exists(Path.Combine(publishOutputTempDir, $"{GodotSharpDirs.ProjectAssemblyName}.{soExt}"))) + { + throw new NotSupportedException( + "Publish succeeded but project assembly not found in the output directory"); + } + + // Add to the exported project shared object list. + + foreach (string file in Directory.GetFiles(publishOutputTempDir, "*", SearchOption.AllDirectories)) + { + AddSharedObject(file, tags: null, projectDataDirName); + } } } @@ -198,6 +216,12 @@ namespace GodotTools.Export if (Directory.Exists(aotTempDir)) Directory.Delete(aotTempDir, recursive: true); + foreach (string folder in _tempFolders) + { + Directory.Delete(folder, recursive: true); + } + _tempFolders.Clear(); + // TODO: The following is just a workaround until the export plugins can be made to abort with errors // We check for empty as well, because it's set to empty after hot-reloading diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index c7e47d2718..185a7e60cf 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -94,138 +94,63 @@ String _get_mono_user_dir() { class _GodotSharpDirs { public: - String res_data_dir; String res_metadata_dir; - String res_config_dir; - String res_temp_dir; - String res_temp_assemblies_base_dir; String res_temp_assemblies_dir; String mono_user_dir; - String mono_logs_dir; - - String api_assemblies_base_dir; String api_assemblies_dir; #ifdef TOOLS_ENABLED - String mono_solutions_dir; String build_logs_dir; - String data_editor_tools_dir; -#else - // Equivalent of res_assemblies_dir, but in the data directory rather than in 'res://'. - // Only defined on export templates. Used when exporting assemblies outside of PCKs. - String data_game_assemblies_dir; -#endif - - String data_mono_etc_dir; - String data_mono_lib_dir; - -#ifdef WINDOWS_ENABLED - String data_mono_bin_dir; #endif private: _GodotSharpDirs() { - res_data_dir = ProjectSettings::get_singleton()->get_project_data_path().path_join("mono"); + String res_data_dir = ProjectSettings::get_singleton()->get_project_data_path().path_join("mono"); res_metadata_dir = res_data_dir.path_join("metadata"); - res_config_dir = res_data_dir.path_join("etc").path_join("mono"); // TODO use paths from csproj - res_temp_dir = res_data_dir.path_join("temp"); - res_temp_assemblies_base_dir = res_temp_dir.path_join("bin"); - res_temp_assemblies_dir = res_temp_assemblies_base_dir.path_join(_get_expected_build_config()); - - api_assemblies_base_dir = res_data_dir.path_join("assemblies"); + res_temp_assemblies_dir = res_data_dir.path_join("temp").path_join("bin").path_join(_get_expected_build_config()); #ifdef WEB_ENABLED mono_user_dir = "user://"; #else mono_user_dir = _get_mono_user_dir(); #endif - mono_logs_dir = mono_user_dir.path_join("mono_logs"); - -#ifdef TOOLS_ENABLED - mono_solutions_dir = mono_user_dir.path_join("solutions"); - build_logs_dir = mono_user_dir.path_join("build_logs"); - - String base_path = ProjectSettings::get_singleton()->globalize_path("res://"); -#endif String exe_dir = OS::get_singleton()->get_executable_path().get_base_dir(); + String res_dir = OS::get_singleton()->get_bundle_resource_dir(); #ifdef TOOLS_ENABLED - String data_dir_root = exe_dir.path_join("GodotSharp"); data_editor_tools_dir = data_dir_root.path_join("Tools"); - api_assemblies_base_dir = data_dir_root.path_join("Api"); - - String data_mono_root_dir = data_dir_root.path_join("Mono"); - data_mono_etc_dir = data_mono_root_dir.path_join("etc"); - -#ifdef ANDROID_ENABLED - data_mono_lib_dir = gdmono::android::support::get_app_native_lib_dir(); -#else - data_mono_lib_dir = data_mono_root_dir.path_join("lib"); -#endif - -#ifdef WINDOWS_ENABLED - data_mono_bin_dir = data_mono_root_dir.path_join("bin"); -#endif - + String api_assemblies_base_dir = data_dir_root.path_join("Api"); + build_logs_dir = mono_user_dir.path_join("build_logs"); #ifdef MACOS_ENABLED if (!DirAccess::exists(data_editor_tools_dir)) { - data_editor_tools_dir = exe_dir.path_join("../Resources/GodotSharp/Tools"); + data_editor_tools_dir = res_dir.path_join("GodotSharp").path_join("Tools"); } - if (!DirAccess::exists(api_assemblies_base_dir)) { - api_assemblies_base_dir = exe_dir.path_join("../Resources/GodotSharp/Api"); - } - - if (!DirAccess::exists(data_mono_root_dir)) { - data_mono_etc_dir = exe_dir.path_join("../Resources/GodotSharp/Mono/etc"); - data_mono_lib_dir = exe_dir.path_join("../Resources/GodotSharp/Mono/lib"); + api_assemblies_base_dir = res_dir.path_join("GodotSharp").path_join("Api"); } #endif - -#else - + api_assemblies_dir = api_assemblies_base_dir.path_join(GDMono::get_expected_api_build_config()); +#else // TOOLS_ENABLED + String arch = Engine::get_singleton()->get_architecture_name(); String appname = ProjectSettings::get_singleton()->get("application/config/name"); String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); - String data_dir_root = exe_dir.path_join("data_" + appname_safe); + String data_dir_root = exe_dir.path_join("data_" + appname_safe + "_" + arch); if (!DirAccess::exists(data_dir_root)) { - data_dir_root = exe_dir.path_join("data_Godot"); + data_dir_root = exe_dir.path_join("data_Godot_" + arch); } - - String data_mono_root_dir = data_dir_root.path_join("Mono"); - data_mono_etc_dir = data_mono_root_dir.path_join("etc"); - -#ifdef ANDROID_ENABLED - data_mono_lib_dir = gdmono::android::support::get_app_native_lib_dir(); -#else - data_mono_lib_dir = data_mono_root_dir.path_join("lib"); - data_game_assemblies_dir = data_dir_root.path_join("Assemblies"); -#endif - -#ifdef WINDOWS_ENABLED - data_mono_bin_dir = data_mono_root_dir.path_join("bin"); -#endif - #ifdef MACOS_ENABLED - if (!DirAccess::exists(data_mono_root_dir)) { - data_mono_etc_dir = exe_dir.path_join("../Resources/GodotSharp/Mono/etc"); - data_mono_lib_dir = exe_dir.path_join("../Resources/GodotSharp/Mono/lib"); + if (!DirAccess::exists(data_dir_root)) { + data_dir_root = res_dir.path_join("data_" + appname_safe + "_" + arch); } - - if (!DirAccess::exists(data_game_assemblies_dir)) { - data_game_assemblies_dir = exe_dir.path_join("../Resources/GodotSharp/Assemblies"); + if (!DirAccess::exists(data_dir_root)) { + data_dir_root = res_dir.path_join("data_Godot_" + arch); } #endif - -#endif - -#ifdef TOOLS_ENABLED - api_assemblies_dir = api_assemblies_base_dir.path_join(GDMono::get_expected_api_build_config()); -#else api_assemblies_dir = data_dir_root; #endif } @@ -237,26 +162,10 @@ public: } }; -String get_res_data_dir() { - return _GodotSharpDirs::get_singleton().res_data_dir; -} - String get_res_metadata_dir() { return _GodotSharpDirs::get_singleton().res_metadata_dir; } -String get_res_config_dir() { - return _GodotSharpDirs::get_singleton().res_config_dir; -} - -String get_res_temp_dir() { - return _GodotSharpDirs::get_singleton().res_temp_dir; -} - -String get_res_temp_assemblies_base_dir() { - return _GodotSharpDirs::get_singleton().res_temp_assemblies_base_dir; -} - String get_res_temp_assemblies_dir() { return _GodotSharpDirs::get_singleton().res_temp_assemblies_dir; } @@ -265,23 +174,11 @@ String get_api_assemblies_dir() { return _GodotSharpDirs::get_singleton().api_assemblies_dir; } -String get_api_assemblies_base_dir() { - return _GodotSharpDirs::get_singleton().api_assemblies_base_dir; -} - String get_mono_user_dir() { return _GodotSharpDirs::get_singleton().mono_user_dir; } -String get_mono_logs_dir() { - return _GodotSharpDirs::get_singleton().mono_logs_dir; -} - #ifdef TOOLS_ENABLED -String get_mono_solutions_dir() { - return _GodotSharpDirs::get_singleton().mono_solutions_dir; -} - String get_build_logs_dir() { return _GodotSharpDirs::get_singleton().build_logs_dir; } @@ -289,23 +186,6 @@ String get_build_logs_dir() { String get_data_editor_tools_dir() { return _GodotSharpDirs::get_singleton().data_editor_tools_dir; } -#else -String get_data_game_assemblies_dir() { - return _GodotSharpDirs::get_singleton().data_game_assemblies_dir; -} #endif -String get_data_mono_etc_dir() { - return _GodotSharpDirs::get_singleton().data_mono_etc_dir; -} - -String get_data_mono_lib_dir() { - return _GodotSharpDirs::get_singleton().data_mono_lib_dir; -} - -#ifdef WINDOWS_ENABLED -String get_data_mono_bin_dir() { - return _GodotSharpDirs::get_singleton().data_mono_bin_dir; -} -#endif } // namespace GodotSharpDirs diff --git a/modules/mono/godotsharp_dirs.h b/modules/mono/godotsharp_dirs.h index 03e62ffd82..cdfb8e4787 100644 --- a/modules/mono/godotsharp_dirs.h +++ b/modules/mono/godotsharp_dirs.h @@ -35,34 +35,18 @@ namespace GodotSharpDirs { -String get_res_data_dir(); String get_res_metadata_dir(); -String get_res_config_dir(); -String get_res_temp_dir(); -String get_res_temp_assemblies_base_dir(); String get_res_temp_assemblies_dir(); String get_api_assemblies_dir(); -String get_api_assemblies_base_dir(); String get_mono_user_dir(); -String get_mono_logs_dir(); #ifdef TOOLS_ENABLED -String get_mono_solutions_dir(); String get_build_logs_dir(); - String get_data_editor_tools_dir(); -#else -String get_data_game_assemblies_dir(); #endif -String get_data_mono_etc_dir(); -String get_data_mono_lib_dir(); - -#ifdef WINDOWS_ENABLED -String get_data_mono_bin_dir(); -#endif } // namespace GodotSharpDirs #endif // GODOTSHARP_DIRS_H |