C#: Use Godot's LipO implementation instead of Xcode's lipo command
This commit is contained in:
parent
1bd740d18d
commit
c2efbf3012
|
@ -355,24 +355,23 @@ namespace GodotTools.Export
|
||||||
if (outputPaths.Count > 2)
|
if (outputPaths.Count > 2)
|
||||||
{
|
{
|
||||||
// lipo the simulator binaries together
|
// lipo the simulator binaries together
|
||||||
// TODO: Move this to the native lipo implementation we have in the macos export plugin.
|
|
||||||
var lipoArgs = new List<string>();
|
|
||||||
lipoArgs.Add("-create");
|
|
||||||
lipoArgs.AddRange(outputPaths.Skip(1).Select(x => Path.Combine(x, $"{GodotSharpDirs.ProjectAssemblyName}.dylib")));
|
|
||||||
lipoArgs.Add("-output");
|
|
||||||
lipoArgs.Add(Path.Combine(outputPaths[1], $"{GodotSharpDirs.ProjectAssemblyName}.dylib"));
|
|
||||||
|
|
||||||
int lipoExitCode = OS.ExecuteCommand(XcodeHelper.FindXcodeTool("lipo"), lipoArgs);
|
string outputPath = Path.Combine(outputPaths[1], $"{GodotSharpDirs.ProjectAssemblyName}.dylib");
|
||||||
if (lipoExitCode != 0)
|
string[] files = outputPaths
|
||||||
throw new InvalidOperationException($"Command 'lipo' exited with code: {lipoExitCode}.");
|
.Skip(1)
|
||||||
|
.Select(path => Path.Combine(path, $"{GodotSharpDirs.ProjectAssemblyName}.dylib"))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (!Internal.LipOCreateFile(outputPath, files))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Failed to 'lipo' simulator binaries.");
|
||||||
|
}
|
||||||
|
|
||||||
outputPaths.RemoveRange(2, outputPaths.Count - 2);
|
outputPaths.RemoveRange(2, outputPaths.Count - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
var xcFrameworkPath = Path.Combine(GodotSharpDirs.ProjectBaseOutputPath, publishConfig.BuildConfig,
|
string xcFrameworkPath = Path.Combine(GodotSharpDirs.ProjectBaseOutputPath, publishConfig.BuildConfig, $"{GodotSharpDirs.ProjectAssemblyName}_aot.xcframework");
|
||||||
$"{GodotSharpDirs.ProjectAssemblyName}_aot.xcframework");
|
if (!BuildManager.GenerateXCFrameworkBlocking(outputPaths, xcFrameworkPath))
|
||||||
if (!BuildManager.GenerateXCFrameworkBlocking(outputPaths,
|
|
||||||
Path.Combine(GodotSharpDirs.ProjectBaseOutputPath, publishConfig.BuildConfig, xcFrameworkPath)))
|
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Failed to generate xcframework.");
|
throw new InvalidOperationException("Failed to generate xcframework.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace GodotTools.Export
|
|
||||||
{
|
|
||||||
public static class XcodeHelper
|
|
||||||
{
|
|
||||||
private static string? _XcodePath = null;
|
|
||||||
|
|
||||||
public static string XcodePath
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_XcodePath == null)
|
|
||||||
{
|
|
||||||
_XcodePath = FindXcode();
|
|
||||||
|
|
||||||
if (_XcodePath == null)
|
|
||||||
throw new FileNotFoundException("Could not find Xcode.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return _XcodePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string? FindSelectedXcode()
|
|
||||||
{
|
|
||||||
var outputWrapper = new Godot.Collections.Array();
|
|
||||||
|
|
||||||
int exitCode = Godot.OS.Execute("xcode-select", new string[] { "--print-path" }, output: outputWrapper);
|
|
||||||
|
|
||||||
if (exitCode == 0)
|
|
||||||
{
|
|
||||||
string output = (string)outputWrapper[0];
|
|
||||||
return output.Trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.Error.WriteLine($"'xcode-select --print-path' exited with code: {exitCode}");
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string? FindXcode()
|
|
||||||
{
|
|
||||||
string? selectedXcode = FindSelectedXcode();
|
|
||||||
if (selectedXcode != null)
|
|
||||||
{
|
|
||||||
if (Directory.Exists(Path.Combine(selectedXcode, "Contents", "Developer")))
|
|
||||||
return selectedXcode;
|
|
||||||
|
|
||||||
// The path already pointed to Contents/Developer
|
|
||||||
var dirInfo = new DirectoryInfo(selectedXcode);
|
|
||||||
if (dirInfo is not { Parent.Name: "Contents", Name: "Developer" })
|
|
||||||
{
|
|
||||||
Console.WriteLine(Path.GetDirectoryName(selectedXcode));
|
|
||||||
Console.WriteLine(System.IO.Directory.GetParent(selectedXcode)?.Name);
|
|
||||||
Console.Error.WriteLine("Unrecognized path for selected Xcode");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return System.IO.Path.GetFullPath($"{selectedXcode}/../..");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.Error.WriteLine("Could not find the selected Xcode; trying with a hint path");
|
|
||||||
}
|
|
||||||
|
|
||||||
const string XcodeHintPath = "/Applications/Xcode.app";
|
|
||||||
|
|
||||||
if (Directory.Exists(XcodeHintPath))
|
|
||||||
{
|
|
||||||
if (Directory.Exists(Path.Combine(XcodeHintPath, "Contents", "Developer")))
|
|
||||||
return XcodeHintPath;
|
|
||||||
|
|
||||||
Console.Error.WriteLine($"Found Xcode at '{XcodeHintPath}' but it's missing the 'Contents/Developer' sub-directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string FindXcodeTool(string toolName)
|
|
||||||
{
|
|
||||||
string XcodeDefaultToolchain = Path.Combine(XcodePath, "Contents", "Developer", "Toolchains", "XcodeDefault.xctoolchain");
|
|
||||||
|
|
||||||
string path = Path.Combine(XcodeDefaultToolchain, "usr", "bin", toolName);
|
|
||||||
if (File.Exists(path))
|
|
||||||
return path;
|
|
||||||
|
|
||||||
throw new FileNotFoundException($"Cannot find Xcode tool: {toolName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -35,6 +35,13 @@ namespace GodotTools.Internals
|
||||||
return godot_icall_Internal_IsMacOSAppBundleInstalled(bundleIdIn);
|
return godot_icall_Internal_IsMacOSAppBundleInstalled(bundleIdIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool LipOCreateFile(string outputPath, string[] files)
|
||||||
|
{
|
||||||
|
using godot_string outputPathIn = Marshaling.ConvertStringToNative(outputPath);
|
||||||
|
using godot_packed_string_array filesIn = Marshaling.ConvertSystemArrayToNativePackedStringArray(files);
|
||||||
|
return godot_icall_Internal_LipOCreateFile(outputPathIn, filesIn);
|
||||||
|
}
|
||||||
|
|
||||||
public static bool GodotIs32Bits() => godot_icall_Internal_GodotIs32Bits();
|
public static bool GodotIs32Bits() => godot_icall_Internal_GodotIs32Bits();
|
||||||
|
|
||||||
public static bool GodotIsRealTDouble() => godot_icall_Internal_GodotIsRealTDouble();
|
public static bool GodotIsRealTDouble() => godot_icall_Internal_GodotIsRealTDouble();
|
||||||
|
@ -121,6 +128,8 @@ namespace GodotTools.Internals
|
||||||
|
|
||||||
private static partial bool godot_icall_Internal_IsMacOSAppBundleInstalled(in godot_string bundleId);
|
private static partial bool godot_icall_Internal_IsMacOSAppBundleInstalled(in godot_string bundleId);
|
||||||
|
|
||||||
|
private static partial bool godot_icall_Internal_LipOCreateFile(in godot_string outputPath, in godot_packed_string_array files);
|
||||||
|
|
||||||
private static partial bool godot_icall_Internal_GodotIs32Bits();
|
private static partial bool godot_icall_Internal_GodotIs32Bits();
|
||||||
|
|
||||||
private static partial bool godot_icall_Internal_GodotIsRealTDouble();
|
private static partial bool godot_icall_Internal_GodotIsRealTDouble();
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "editor/editor_paths.h"
|
#include "editor/editor_paths.h"
|
||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
|
#include "editor/export/lipo.h"
|
||||||
#include "editor/gui/editor_run_bar.h"
|
#include "editor/gui/editor_run_bar.h"
|
||||||
#include "editor/plugins/script_editor_plugin.h"
|
#include "editor/plugins/script_editor_plugin.h"
|
||||||
#include "editor/themes/editor_scale.h"
|
#include "editor/themes/editor_scale.h"
|
||||||
|
@ -117,6 +118,13 @@ bool godot_icall_Internal_IsMacOSAppBundleInstalled(const godot_string *p_bundle
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool godot_icall_Internal_LipOCreateFile(const godot_string *p_output_path, const godot_packed_array *p_files) {
|
||||||
|
String output_path = *reinterpret_cast<const String *>(p_output_path);
|
||||||
|
PackedStringArray files = *reinterpret_cast<const PackedStringArray *>(p_files);
|
||||||
|
LipO lip;
|
||||||
|
return lip.create_file(output_path, files);
|
||||||
|
}
|
||||||
|
|
||||||
bool godot_icall_Internal_GodotIs32Bits() {
|
bool godot_icall_Internal_GodotIs32Bits() {
|
||||||
return sizeof(void *) == 4;
|
return sizeof(void *) == 4;
|
||||||
}
|
}
|
||||||
|
@ -258,6 +266,7 @@ static const void *unmanaged_callbacks[]{
|
||||||
(void *)godot_icall_EditorProgress_Step,
|
(void *)godot_icall_EditorProgress_Step,
|
||||||
(void *)godot_icall_Internal_FullExportTemplatesDir,
|
(void *)godot_icall_Internal_FullExportTemplatesDir,
|
||||||
(void *)godot_icall_Internal_IsMacOSAppBundleInstalled,
|
(void *)godot_icall_Internal_IsMacOSAppBundleInstalled,
|
||||||
|
(void *)godot_icall_Internal_LipOCreateFile,
|
||||||
(void *)godot_icall_Internal_GodotIs32Bits,
|
(void *)godot_icall_Internal_GodotIs32Bits,
|
||||||
(void *)godot_icall_Internal_GodotIsRealTDouble,
|
(void *)godot_icall_Internal_GodotIsRealTDouble,
|
||||||
(void *)godot_icall_Internal_GodotMainIteration,
|
(void *)godot_icall_Internal_GodotMainIteration,
|
||||||
|
|
Loading…
Reference in New Issue