Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions Editor/Core/ShortPath.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System.Runtime.InteropServices;
using System.Text;
using UnityEngine;

namespace SplashEdit.EditorCode
{
/// <summary>
/// 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.
/// </summary>
public static class ShortPath
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint GetShortPathNameW(string lpszLongPath, StringBuilder lpszShortPath, uint cchBuffer);

/// <summary>
/// Resolves <paramref name="dir"/> 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 <paramref name="error"/> if the path
/// contains a space and cannot be made safe (non-Windows, or 8.3 names disabled).
/// </summary>
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 <drive>: 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();
}
}
}
2 changes: 2 additions & 0 deletions Editor/Core/ShortPath.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 16 additions & 4 deletions Editor/Core/SplashControlPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1907,14 +1907,20 @@ private async Task<Dictionary<string, byte[]>> CompileLuaAsync(Dictionary<LuaFil
/// </summary>
private async Task<bool> 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,
Expand Down Expand Up @@ -1993,6 +1999,12 @@ private async Task<bool> 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)
Expand Down Expand Up @@ -2029,8 +2041,8 @@ private async Task<bool> 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,
Expand Down
Loading