diff --git a/Editor/Core/ShortPath.cs b/Editor/Core/ShortPath.cs
new file mode 100644
index 0000000..ef49b56
--- /dev/null
+++ b/Editor/Core/ShortPath.cs
@@ -0,0 +1,87 @@
+using System.Runtime.InteropServices;
+using System.Text;
+using UnityEngine;
+
+namespace SplashEdit.EditorCode
+{
+ ///
+ /// Resolves filesystem paths for safe use as a make working directory.
+ /// GNU make and the psyqo makefiles derive their own root via
+ /// $(abspath $(lastword $(MAKEFILE_LIST))) resolved against make's CWD, and neither
+ /// handles a space in that path correctly. On Windows we can usually dodge the
+ /// problem with the legacy 8.3 short path; everywhere else a space is fatal.
+ ///
+ public static class ShortPath
+ {
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
+ private static extern uint GetShortPathNameW(string lpszLongPath, StringBuilder lpszShortPath, uint cchBuffer);
+
+ ///
+ /// Resolves into a path make can safely use as its working
+ /// directory. On Windows, a path containing spaces is converted to its 8.3 short
+ /// path. Returns false with a descriptive if the path
+ /// contains a space and cannot be made safe (non-Windows, or 8.3 names disabled).
+ ///
+ public static bool TryResolveForMake(string dir, out string resolvedDir, out string error)
+ {
+ if (Application.platform != RuntimePlatform.WindowsEditor)
+ {
+ if (dir.IndexOf(' ') >= 0)
+ {
+ resolvedDir = null;
+ error = SpacesInPathError(dir);
+ return false;
+ }
+
+ resolvedDir = dir;
+ error = null;
+ return true;
+ }
+
+ if (dir.IndexOf(' ') < 0)
+ {
+ resolvedDir = dir;
+ error = null;
+ return true;
+ }
+
+ string shortPath = GetShortPath(dir);
+ if (string.IsNullOrEmpty(shortPath) || shortPath.IndexOf(' ') >= 0)
+ {
+ resolvedDir = null;
+ error = SpacesInPathError(dir) +
+ " On Windows this can usually be fixed by enabling 8.3 short names on the " +
+ "drive (run `fsutil 8dot3name set : 0` as Administrator - this only " +
+ "affects files created afterwards, so the project may need to be recreated " +
+ "at its current path once enabled).";
+ return false;
+ }
+
+ resolvedDir = shortPath;
+ error = null;
+ return true;
+ }
+
+ private static string SpacesInPathError(string dir) =>
+ $"The project path contains spaces (\"{dir}\"), which GNU make and the psyqo " +
+ "makefiles cannot handle. Move the project to a path without spaces.";
+
+ private static string GetShortPath(string longPath)
+ {
+ var buffer = new StringBuilder(260);
+ uint length = GetShortPathNameW(longPath, buffer, (uint)buffer.Capacity);
+ if (length == 0)
+ return null;
+
+ if (length > buffer.Capacity)
+ {
+ buffer = new StringBuilder((int)length);
+ length = GetShortPathNameW(longPath, buffer, (uint)buffer.Capacity);
+ if (length == 0)
+ return null;
+ }
+
+ return buffer.ToString();
+ }
+ }
+}
diff --git a/Editor/Core/ShortPath.cs.meta b/Editor/Core/ShortPath.cs.meta
new file mode 100644
index 0000000..24fac87
--- /dev/null
+++ b/Editor/Core/ShortPath.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 65e1672c263d4fdb8217a7a77b994e27
\ No newline at end of file
diff --git a/Editor/Core/SplashControlPanel.cs b/Editor/Core/SplashControlPanel.cs
index ca736c4..2825e8f 100644
--- a/Editor/Core/SplashControlPanel.cs
+++ b/Editor/Core/SplashControlPanel.cs
@@ -1907,14 +1907,20 @@ private async Task> CompileLuaAsync(Dictionary
private async Task BuildLuacPsxAsync(string luacDir)
{
+ if (!ShortPath.TryResolveForMake(luacDir, out string luacWorkDir, out string pathError))
+ {
+ Log(pathError, LogType.Error);
+ return false;
+ }
+
int jobCount = Math.Max(1, SystemInfo.processorCount - 1);
string makeCmd = $"make -j{jobCount}";
var psi = new ProcessStartInfo
{
FileName = Application.platform == RuntimePlatform.WindowsEditor ? "cmd.exe" : "/bin/bash",
- Arguments = WrapCommandForMacOS(luacDir, makeCmd),
- WorkingDirectory = luacDir,
+ Arguments = WrapCommandForMacOS(luacWorkDir, makeCmd),
+ WorkingDirectory = luacWorkDir,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
@@ -1993,6 +1999,12 @@ private async Task CompileNativeAsync()
return false;
}
+ if (!ShortPath.TryResolveForMake(nativeDir, out string nativeWorkDir, out string pathError))
+ {
+ Log(pathError, LogType.Error);
+ return false;
+ }
+
string buildArg = SplashSettings.Mode == BuildMode.Debug ? "BUILD=Debug" : "";
if (SplashSettings.Target == BuildTarget.ISO)
@@ -2029,8 +2041,8 @@ private async Task CompileNativeAsync()
var psi = new ProcessStartInfo
{
FileName = Application.platform == RuntimePlatform.WindowsEditor ? "cmd.exe" : "/bin/bash",
- Arguments = WrapCommandForMacOS(nativeDir, makeCmd),
- WorkingDirectory = nativeDir,
+ Arguments = WrapCommandForMacOS(nativeWorkDir, makeCmd),
+ WorkingDirectory = nativeWorkDir,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,