Make //reference work most of the time when compiling with .NET core

This commit is contained in:
UnknownShadow200 2022-06-11 16:42:21 +10:00
parent eb41330637
commit ad68660649

View File

@ -80,6 +80,16 @@ namespace MCGalaxy.Modules.Compiling
static string Quote(string value) { return "\"" + value + "\""; } static string Quote(string value) { return "\"" + value + "\""; }
static string GetBinaryFile(string varName, string desc) {
string path = Environment.GetEnvironmentVariable(varName);
if (string.IsNullOrEmpty(path))
throw new InvalidOperationException("Env variable '" + varName + " must specify the path to " + desc);
// make sure file exists
using (Stream tmp = File.OpenRead(path)) { }
return path;
}
static int Compile(string path, string exeArgs, string args, List<string> output) { static int Compile(string path, string exeArgs, string args, List<string> output) {
// e.g. /home/test/.dotnet/dotnet exec "/home/test/.dotnet/sdk/6.0.300/Roslyn/bincore/csc.dll" [COMPILER ARGS] // e.g. /home/test/.dotnet/dotnet exec "/home/test/.dotnet/sdk/6.0.300/Roslyn/bincore/csc.dll" [COMPILER ARGS]
args = "exec " + Quote(exeArgs) + " " + args; args = "exec " + Quote(exeArgs) + " " + args;
@ -160,29 +170,22 @@ namespace MCGalaxy.Modules.Compiling
// https://stackoverflow.com/questions/58840995/roslyn-compilation-how-to-reference-a-net-standard-2-0-class-library // https://stackoverflow.com/questions/58840995/roslyn-compilation-how-to-reference-a-net-standard-2-0-class-library
// https://luisfsgoncalves.wordpress.com/2017/03/20/referencing-system-assemblies-in-roslyn-compilations/ // https://luisfsgoncalves.wordpress.com/2017/03/20/referencing-system-assemblies-in-roslyn-compilations/
// https://github.com/dotnet/roslyn/issues/34111 // https://github.com/dotnet/roslyn/issues/34111
// TODO investigate using AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")).Split(Path.PathSeparator); instead
string coreAssemblyFileName = typeof(object).Assembly.Location; string coreAssemblyFileName = typeof(object).Assembly.Location;
string[] sysAssemblyPaths = GetSystemAssemblyPaths();
if (!string.IsNullOrWhiteSpace(coreAssemblyFileName)) { if (!string.IsNullOrWhiteSpace(coreAssemblyFileName)) {
sb.Append("/nostdlib+ "); sb.Append("/nostdlib+ ");
sb.AppendFormat("/R:{0} ", Quote(coreAssemblyFileName.Trim())); sb.AppendFormat("/R:{0} ", Quote(coreAssemblyFileName.Trim()));
} }
//string[] trustedAssembliesPaths = ((string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")).Split(Path.PathSeparator); AddReferencedAssembly(sb, sysAssemblyPaths, "System.Runtime.dll");
//foreach (string trusted in trustedAssembliesPaths) AddReferencedAssembly(sb, sysAssemblyPaths, "netstandard.dll");
//{
// Console.WriteLine("TRUST: " + trusted);
//}
//Console.WriteLine("CORE FILE: " + coreAssemblyFileName);
LoadSystemAssembly(sb, "System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); foreach (string path in parameters.ReferencedAssemblies)
LoadSystemAssembly(sb, "netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"); {
AddReferencedAssembly(sb, sysAssemblyPaths, path);
foreach (string path in parameters.ReferencedAssemblies) {
sb.AppendFormat("/R:{0} ", Quote(path));
} }
sb.AppendFormat("/out:{0} ", Quote(parameters.OutputAssembly)); sb.AppendFormat("/out:{0} ", Quote(parameters.OutputAssembly));
// debug information // debug information
@ -196,34 +199,34 @@ namespace MCGalaxy.Modules.Compiling
sb.Append(parameters.CompilerOptions + " "); sb.Append(parameters.CompilerOptions + " ");
} }
foreach (string path in fileNames) { foreach (string path in fileNames)
{
sb.AppendFormat("{0} ", Quote(path)); sb.AppendFormat("{0} ", Quote(path));
} }
return sb.ToString(); return sb.ToString();
} }
static void LoadSystemAssembly(StringBuilder sb, string assemblyName) { static string[] GetSystemAssemblyPaths() {
string assemblyPath = null; string assemblies = AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES") as string;
try { if (string.IsNullOrEmpty(assemblies)) return new string[0];
var assembly = Assembly.Load(assemblyName);
assemblyPath = assembly.Location; return assemblies.Split(Path.PathSeparator);
} catch { }
// swallow any exceptions if we cannot find the assembly
static void AddReferencedAssembly(StringBuilder sb, string[] sysAssemblyPaths, string path) {
path = MapAssembly(sysAssemblyPaths, path);
sb.AppendFormat("/R:{0} ", Quote(path));
}
// Try to use full system .dll path (otherwise roslyn may not always find the .dll)
static string MapAssembly(string[] sysAssemblyPaths, string file) {
foreach (string sysPath in sysAssemblyPaths)
{
if (file == Path.GetFileName(sysPath)) return sysPath;
} }
return file;
if (assemblyPath == null) return;
sb.AppendFormat("/R:{0} ", Quote(assemblyPath));
} }
static string GetBinaryFile(string varName, string desc) {
string path = Environment.GetEnvironmentVariable(varName);
if (string.IsNullOrEmpty(path))
throw new InvalidOperationException("Env variable '" + varName + " must specify the path to " + desc);
// make sure file exists
using (Stream tmp = File.OpenRead(path)) { }
return path;
}
} }
} }
#endif #endif