Skip to content

Commit f0b8124

Browse files
committed
Support Unity 5.6
1 parent 8499061 commit f0b8124

File tree

8 files changed

+110
-40
lines changed

8 files changed

+110
-40
lines changed

extra/CompilerPlugin/CustomCSharpCompiler.cs

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.IO;
33
using System.Linq;
44
using System.Reflection;
5+
using UnityEditor;
56
using UnityEditor.Scripting;
67
using UnityEditor.Scripting.Compilers;
78
using UnityEditor.Utils;
@@ -55,6 +56,7 @@ protected override Program StartCompiler()
5556
"-target:library",
5657
"-nowarn:0169",
5758
"-out:" + PrepareFileName(_island._output),
59+
"-unsafe"
5860
};
5961
foreach (var reference in _island._references)
6062
{
@@ -74,7 +76,7 @@ protected override Program StartCompiler()
7476
var additionalReferences = GetAdditionalReferences();
7577
foreach (string path in additionalReferences)
7678
{
77-
var text = Path.Combine(GetProfileDirectory(), path);
79+
var text = Path.Combine(GetProfileDirectoryViaReflection(), path);
7880
if (File.Exists(text))
7981
{
8082
arguments.Add("-r:" + PrepareFileName(text));
@@ -85,19 +87,80 @@ protected override Program StartCompiler()
8587
if (universalCompilerPath != null)
8688
{
8789
// use universal compiler.
88-
var defaultCompilerName = Path.GetFileNameWithoutExtension(GetCompilerPath(arguments));
8990
arguments.Add("-define:__UNITY_PROCESSID__" + System.Diagnostics.Process.GetCurrentProcess().Id);
90-
arguments.Add("-define:__UNITY_PROFILE__" + Path.GetFileName(base.GetProfileDirectory()).Replace(".", "_"));
91-
var rspFileName = "Assets/" + defaultCompilerName + ".rsp";
91+
92+
// this function should be run because it addes an item to arguments
93+
var compilerPath = GetCompilerPath(arguments);
94+
95+
var rspFileName = "Assets/mcs.rsp";
9296
if (File.Exists(rspFileName))
97+
{
9398
arguments.Add("@" + rspFileName);
99+
}
100+
else
101+
{
102+
var defaultCompilerName = Path.GetFileNameWithoutExtension(compilerPath);
103+
rspFileName = "Assets/" + defaultCompilerName + ".rsp";
104+
if (File.Exists(rspFileName))
105+
arguments.Add("@" + rspFileName);
106+
}
107+
94108
return StartCompiler(_island._target, universalCompilerPath, arguments);
95109
}
96110
else
97111
{
98112
// fallback to the default compiler.
99113
Debug.LogWarning($"Universal C# compiler not found in project directory. Use the default compiler");
100-
return StartCompiler(_island._target, GetCompilerPath(arguments), arguments);
114+
return base.StartCompiler();
101115
}
102116
}
117+
118+
// In Unity 5.5 and earlier GetProfileDirectory() was an instance method of MonoScriptCompilerBase class.
119+
// In Unity 5.6 the method is removed and the profile directory is detected differently.
120+
private string GetProfileDirectoryViaReflection()
121+
{
122+
var monoScriptCompilerBaseType = typeof(MonoScriptCompilerBase);
123+
var getProfileDirectoryMethodInfo = monoScriptCompilerBaseType.GetMethod("GetProfileDirectory", BindingFlags.NonPublic | BindingFlags.Instance);
124+
if (getProfileDirectoryMethodInfo != null)
125+
{
126+
// For any Unity version prior to 5.6
127+
string result = (string)getProfileDirectoryMethodInfo.Invoke(this, null);
128+
return result;
129+
}
130+
131+
// For Unity 5.6
132+
var monoIslandType = typeof(MonoIsland);
133+
var apiCompatibilityLevelFieldInfo = monoIslandType.GetField("_api_compatibility_level");
134+
var apiCompatibilityLevel = (ApiCompatibilityLevel)apiCompatibilityLevelFieldInfo.GetValue(_island);
135+
136+
string profile;
137+
if (apiCompatibilityLevel != ApiCompatibilityLevel.NET_2_0)
138+
{
139+
profile = GetMonoProfileLibDirectory(apiCompatibilityLevel);
140+
}
141+
else
142+
{
143+
profile = "2.0-api";
144+
}
145+
146+
string profileDirectory = GetProfileDirectory(profile, "MonoBleedingEdge");
147+
return profileDirectory;
148+
}
149+
150+
private static string GetMonoProfileLibDirectory(ApiCompatibilityLevel apiCompatibilityLevel)
151+
{
152+
var buildPipelineType = typeof(BuildPipeline);
153+
var compatibilityProfileToClassLibFolderMethodInfo = buildPipelineType.GetMethod("CompatibilityProfileToClassLibFolder", BindingFlags.NonPublic | BindingFlags.Static);
154+
string profile = (string)compatibilityProfileToClassLibFolderMethodInfo.Invoke(null, new object[] { apiCompatibilityLevel });
155+
156+
var apiCompatibilityLevelNet46 = (ApiCompatibilityLevel)3;
157+
string monoInstallation = apiCompatibilityLevel != apiCompatibilityLevelNet46 ? "Mono" : "MonoBleedingEdge";
158+
return GetProfileDirectory(profile, monoInstallation);
159+
}
160+
161+
private static string GetProfileDirectory(string profile, string monoInstallation)
162+
{
163+
string monoInstallation2 = MonoInstallationFinder.GetMonoInstallation(monoInstallation);
164+
return Path.Combine(monoInstallation2, Path.Combine("lib", Path.Combine("mono", profile)));
165+
}
103166
}

extra/UniversalCompiler/Compilers/Compiler.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ protected Compiler(Logger logger, string compilerPath, string pbd2MdbPath = null
2929
this.pbd2MdbPath = pbd2MdbPath;
3030
}
3131

32-
public int Compile(Platform platform, string monoProfile, string unityEditorDataDir, string responseFile)
32+
public int Compile(Platform platform, string monoProfileDir, string unityEditorDataDir, string responseFile)
3333
{
34-
var process = CreateCompilerProcess(platform, monoProfile, unityEditorDataDir, responseFile);
34+
var process = CreateCompilerProcess(platform, monoProfileDir, unityEditorDataDir, responseFile);
3535
process.OutputDataReceived += (sender, e) => outputLines.Add(e.Data);
3636
process.ErrorDataReceived += (sender, e) => errorLines.Add(e.Data);
3737

@@ -77,12 +77,7 @@ where string.IsNullOrEmpty(trimmedLine) == false
7777
}
7878
}
7979

80-
public static string GetMonoDllPath(string unityEditorDataDir, string monoProfile, string fileName)
81-
{
82-
return Path.Combine(unityEditorDataDir, @"Mono/lib/mono/" + monoProfile + "/" + fileName);
83-
}
84-
85-
protected abstract Process CreateCompilerProcess(Platform platform, string monoProfile, string unityEditorDataDir, string responseFile);
80+
protected abstract Process CreateCompilerProcess(Platform platform, string monoProfileDir, string unityEditorDataDir, string responseFile);
8681

8782
public virtual void ConvertDebugSymbols(Platform platform, string libraryPath, string unityEditorDataDir) { }
8883

extra/UniversalCompiler/Compilers/Incremental60Compiler.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ public Incremental60Compiler(Logger logger, string directory)
1313

1414
public static bool IsAvailable(string directory) => File.Exists(Path.Combine(directory, "IncrementalCompiler.exe"));
1515

16-
protected override Process CreateCompilerProcess(Platform platform, string monoProfile, string unityEditorDataDir, string responseFile)
16+
protected override Process CreateCompilerProcess(Platform platform, string monoProfileDir, string unityEditorDataDir, string responseFile)
1717
{
18-
var systemDllPath = GetMonoDllPath(unityEditorDataDir, monoProfile, "System.dll");
19-
var systemCoreDllPath = GetMonoDllPath(unityEditorDataDir, monoProfile, "System.Core.dll");
20-
var systemXmlDllPath = GetMonoDllPath(unityEditorDataDir, monoProfile, "System.Xml.dll");
21-
var mscorlibDllPath = GetMonoDllPath(unityEditorDataDir, monoProfile, "mscorlib.dll");
18+
var systemDllPath = Path.Combine(monoProfileDir, "System.dll");
19+
var systemCoreDllPath = Path.Combine(monoProfileDir, "System.Core.dll");
20+
var systemXmlDllPath = Path.Combine(monoProfileDir, "System.Xml.dll");
21+
var mscorlibDllPath = Path.Combine(monoProfileDir, "mscorlib.dll");
2222

2323
string processArguments = "-nostdlib+ -noconfig "
2424
+ $"-r:\"{mscorlibDllPath}\" "

extra/UniversalCompiler/Compilers/Microsoft60Compiler.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ public Microsoft60Compiler(Logger logger, string directory)
1414
public static bool IsAvailable(string directory) => File.Exists(Path.Combine(directory, "csc.exe")) &&
1515
File.Exists(Path.Combine(directory, "pdb2mdb.exe"));
1616

17-
protected override Process CreateCompilerProcess(Platform platform, string monoProfile, string unityEditorDataDir, string responseFile)
17+
protected override Process CreateCompilerProcess(Platform platform, string monoProfileDir, string unityEditorDataDir, string responseFile)
1818
{
19-
var systemDllPath = GetMonoDllPath(unityEditorDataDir, monoProfile, "System.dll");
20-
var systemCoreDllPath = GetMonoDllPath(unityEditorDataDir, monoProfile, "System.Core.dll");
21-
var systemXmlDllPath = GetMonoDllPath(unityEditorDataDir, monoProfile, "System.Xml.dll");
22-
var mscorlibDllPath = GetMonoDllPath(unityEditorDataDir, monoProfile, "mscorlib.dll");
19+
var systemDllPath = Path.Combine(monoProfileDir, "System.dll");
20+
var systemCoreDllPath = Path.Combine(monoProfileDir, "System.Core.dll");
21+
var systemXmlDllPath = Path.Combine(monoProfileDir, "System.Xml.dll");
22+
var mscorlibDllPath = Path.Combine(monoProfileDir, "mscorlib.dll");
2323

2424
string processArguments = "-nostdlib+ -noconfig -nologo "
2525
+ $"-r:\"{mscorlibDllPath}\" "

extra/UniversalCompiler/Compilers/Mono30Compiler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ internal class Mono30Compiler : Compiler
55
public Mono30Compiler(Logger logger, string compilerPath) : base(logger, compilerPath, null) { }
66
public override string Name => "Mono C# 3.0";
77

8-
protected override Process CreateCompilerProcess(Platform platform, string monoProfile, string unityEditorDataDir, string responseFile)
8+
protected override Process CreateCompilerProcess(Platform platform, string monoProfileDir, string unityEditorDataDir, string responseFile)
99
{
1010
var process = new Process();
1111
process.StartInfo = CreateOSDependentStartInfo(platform, ProcessRuntime.CLR20, compilerPath, responseFile, unityEditorDataDir);

extra/UniversalCompiler/Compilers/Mono50Compiler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ internal class Mono50Compiler : Compiler
66
public Mono50Compiler(Logger logger, string compilerPath) : base(logger, compilerPath, null) { }
77
public override string Name => "Mono C# 5.0";
88

9-
protected override Process CreateCompilerProcess(Platform platform, string monoProfile, string unityEditorDataDir, string responseFile)
9+
protected override Process CreateCompilerProcess(Platform platform, string monoProfileDir, string unityEditorDataDir, string responseFile)
1010
{
11-
var systemCoreDllPath = GetMonoDllPath(unityEditorDataDir, monoProfile, "System.Core.dll");
11+
var systemCoreDllPath = Path.Combine(monoProfileDir, "System.Core.dll");
1212

1313
string processArguments;
1414
if (platform == Platform.Windows)

extra/UniversalCompiler/Compilers/Mono60Compiler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ public Mono60Compiler(Logger logger, string directory)
88

99
public override string Name => "Mono C# 6.0";
1010

11-
protected override Process CreateCompilerProcess(Platform platform, string monoProfile, string unityEditorDataDir, string responseFile)
11+
protected override Process CreateCompilerProcess(Platform platform, string monoProfileDir, string unityEditorDataDir, string responseFile)
1212
{
13-
var systemCoreDllPath = GetMonoDllPath(unityEditorDataDir, monoProfile, "System.Core.dll");
13+
var systemCoreDllPath = Path.Combine(monoProfileDir, "System.Core.dll");
1414

1515
string processArguments;
1616
if (platform == Platform.Windows)

extra/UniversalCompiler/Program.cs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,15 @@ private static int Compile(string[] args, Logger logger, Settings settings)
5151
var responseFile = args[0];
5252
var compilationOptions = File.ReadAllLines(responseFile.TrimStart('@'));
5353
var unityEditorDataDir = GetUnityEditorDataDir();
54+
var monoProfileDir = GetMonoProfileDir(compilationOptions);
5455
var projectDir = Directory.GetCurrentDirectory();
5556
var targetAssembly = compilationOptions.First(line => line.StartsWith("-out:")).Substring(10).Trim('\'');
56-
var monoProfile = compilationOptions.First(line => line.StartsWith("-define:__UNITY_PROFILE__")).Substring(25);
57-
if (monoProfile == "2_0") monoProfile = "2.0";
5857

5958
logger?.Append($"CSharpCompilerWrapper.exe version: {Assembly.GetExecutingAssembly().GetName().Version}");
6059
logger?.Append($"Platform: {CurrentPlatform}");
61-
logger?.Append($"Mono profile: {monoProfile}");
6260
logger?.Append($"Target assembly: {targetAssembly}");
6361
logger?.Append($"Project directory: {projectDir}");
62+
logger?.Append($"Mono profile directory: {monoProfileDir}");
6463
logger?.Append($"Unity 'Data' or 'Frameworks' directory: {unityEditorDataDir}");
6564

6665
if (CurrentPlatform == Platform.Linux)
@@ -70,15 +69,15 @@ private static int Compile(string[] args, Logger logger, Settings settings)
7069
return -1;
7170
}
7271

73-
var compiler = CreateCompiler(settings.Compiler, logger, CurrentPlatform, monoProfile, projectDir, compilationOptions, unityEditorDataDir);
72+
var compiler = CreateCompiler(settings.Compiler, logger, CurrentPlatform, monoProfileDir, projectDir, compilationOptions, unityEditorDataDir);
7473

7574
logger?.Append($"Compiler: {compiler.Name}");
7675
logger?.Append("");
7776
logger?.Append("- Compilation -----------------------------------------------");
7877
logger?.Append("");
7978

8079
var stopwatch = Stopwatch.StartNew();
81-
var exitCode = compiler.Compile(CurrentPlatform, monoProfile, unityEditorDataDir, responseFile);
80+
var exitCode = compiler.Compile(CurrentPlatform, monoProfileDir, unityEditorDataDir, responseFile);
8281
stopwatch.Stop();
8382

8483
logger?.Append($"Elapsed time: {stopwatch.ElapsedMilliseconds / 1000f:F2} sec");
@@ -108,19 +107,19 @@ private static int Compile(string[] args, Logger logger, Settings settings)
108107
return 0;
109108
}
110109

111-
private static Compiler CreateCompiler(CompilerType compilerType, Logger logger, Platform platform, string monoProfile, string projectDir, string[] compilationOptions, string unityEditorDataDir)
110+
private static Compiler CreateCompiler(CompilerType compilerType, Logger logger, Platform platform, string monoProfileDir, string projectDir, string[] compilationOptions, string unityEditorDataDir)
112111
{
113112
var compilerDirectory = Path.Combine(projectDir, LANGUAGE_SUPPORT_DIR);
114113

115114
switch (compilerType)
116115
{
117116
case CompilerType.Auto:
118-
return FindSuitableCompiler(logger, platform, monoProfile, projectDir, compilationOptions, unityEditorDataDir);
117+
return FindSuitableCompiler(logger, platform, monoProfileDir, projectDir, compilationOptions, unityEditorDataDir);
119118

120119
case CompilerType.Mono3:
121-
var stockCompilerPath = monoProfile == "2.0"
120+
var stockCompilerPath = monoProfileDir.IndexOf("2.0") != -1
122121
? Path.Combine(unityEditorDataDir, @"Mono/lib/mono/2.0/gmcs.exe")
123-
: Path.Combine(unityEditorDataDir, @"Mono/lib/mono/" + monoProfile + "/smcs.exe");
122+
: Path.Combine(monoProfileDir, "smcs.exe");
124123
return new Mono30Compiler(logger, stockCompilerPath);
125124

126125
case CompilerType.Mono5:
@@ -147,7 +146,7 @@ private static Compiler CreateCompiler(CompilerType compilerType, Logger logger,
147146
return null;
148147
}
149148

150-
private static Compiler FindSuitableCompiler(Logger logger, Platform platform, string monoProfile, string projectDir, string[] compilationOptions, string unityEditorDataDir)
149+
private static Compiler FindSuitableCompiler(Logger logger, Platform platform, string monoProfileDir, string projectDir, string[] compilationOptions, string unityEditorDataDir)
151150
{
152151
Compiler compiler = null;
153152

@@ -190,9 +189,9 @@ private static Compiler FindSuitableCompiler(Logger logger, Platform platform, s
190189
if (compiler == null)
191190
{
192191
// Using stock Mono C# 3.0 compiler
193-
var stockCompilerPath = monoProfile == "2.0"
192+
var stockCompilerPath = monoProfileDir.IndexOf("2.0") != -1
194193
? Path.Combine(unityEditorDataDir, @"Mono/lib/mono/2.0/gmcs.exe")
195-
: Path.Combine(unityEditorDataDir, @"Mono/lib/mono/" + monoProfile + "/smcs.exe");
194+
: Path.Combine(monoProfileDir, "smcs.exe");
196195
compiler = new Mono30Compiler(logger, stockCompilerPath);
197196
}
198197

@@ -242,4 +241,17 @@ private static string GetUnityEditorDataDir()
242241
var path = monoPath.Substring(0, index);
243242
return path;
244243
}
244+
245+
private static string GetMonoProfileDir(string[] compilationOptions)
246+
{
247+
/* Looking for something like
248+
-r:"C:\Program Files\Unity\Editor\Data\Mono\lib\mono\unity\System.Xml.Linq.dll"
249+
or
250+
-r:'C:\Program Files\Unity\Editor\Data\Mono\lib\mono\unity\System.Xml.Linq.dll'
251+
*/
252+
var reference = compilationOptions.First(line => line.StartsWith("-r:") && line.Contains("System.Xml.Linq.dll"));
253+
var systemXmlLinqPath = reference.Replace("'", "").Replace("\"", "").Substring(3);
254+
var profileDir = Path.GetDirectoryName(systemXmlLinqPath);
255+
return profileDir;
256+
}
245257
}

0 commit comments

Comments
 (0)