private static void CompileMod(BuildingMod mod, List<LoadingMod> refMods, bool forWindows,
ref byte[] dll, ref byte[] pdb) {
LoadReferences();
var terrariaModule = Assembly.GetExecutingAssembly();
bool generatePDB = mod.properties.includePDB && forWindows;
if (generatePDB && !windows) {
Console.WriteLine("PDB files can only be generated for windows, on windows.");
generatePDB = false;
}
var refs = new List<string>(terrariaReferences);
if (forWindows == windows) {
refs.Add(terrariaModule.Location);
}
else {
refs = refs.Where(path => {
var name = Path.GetFileName(path);
return name != "FNA.dll" && !name.StartsWith("Microsoft.Xna.Framework");
}).ToList();
var names = forWindows
? new[] {
"tModLoaderWindows.exe",
"Microsoft.Xna.Framework.dll",
"Microsoft.Xna.Framework.Game.dll",
"Microsoft.Xna.Framework.Graphics.dll",
"Microsoft.Xna.Framework.Xact.dll"
}
: new[] {
"tModLoaderMac.exe",
"FNA.dll"
};
refs.AddRange(names.Select(f => Path.Combine(modCompileDir, f)));
}
refs.AddRange(mod.properties.dllReferences.Select(refDll => Path.Combine(mod.path, "lib/" + refDll + ".dll")));
var tempDir = Path.Combine(ModPath, "compile_temp");
Directory.CreateDirectory(tempDir);
foreach (var resName in terrariaModule.GetManifestResourceNames().Where(n => n.EndsWith(".dll"))) {
var path = Path.Combine(tempDir, Path.GetFileName(resName));
using (Stream res = terrariaModule.GetManifestResourceStream(resName), file = File.Create(path))
res.CopyTo(file);
refs.Add(path);
}
foreach (var refMod in refMods) {
var path = Path.Combine(tempDir, refMod.Name + ".dll");
File.WriteAllBytes(path, refMod.modFile.GetMainAssembly(forWindows));
refs.Add(path);
foreach (var refDll in refMod.properties.dllReferences) {
path = Path.Combine(tempDir, refDll + ".dll");
File.WriteAllBytes(path, refMod.modFile.GetFile("lib/"+refDll+".dll"));
refs.Add(path);
}
}
var compileOptions = new CompilerParameters {
OutputAssembly = Path.Combine(tempDir, mod.Name + ".dll"),
GenerateExecutable = false,
GenerateInMemory = false,
TempFiles = new TempFileCollection(tempDir, true),
IncludeDebugInformation = generatePDB
};
compileOptions.ReferencedAssemblies.AddRange(refs.ToArray());
var files = Directory.GetFiles(mod.path, "*.cs", SearchOption.AllDirectories);
try {
CompilerResults results;
if (mod.properties.languageVersion == 6) {
if (Environment.Version.Revision < 10000) {
ErrorLogger.LogBuildError(".NET Framework 4.5 must be installed to compile C# 6.0");
return;
}
results = RoslynCompile(compileOptions, files);
}
else {
var options = new Dictionary<string, string> { { "CompilerVersion", "v" + mod.properties.languageVersion + ".0" } };
results = new CSharpCodeProvider(options).CompileAssemblyFromFile(compileOptions, files);
}
if (results.Errors.HasErrors) {
ErrorLogger.LogCompileErrors(results.Errors);
return;
}
dll = File.ReadAllBytes(compileOptions.OutputAssembly);
if (generatePDB)
pdb = File.ReadAllBytes(Path.Combine(tempDir, mod.Name + ".pdb"));
}
finally {
int numTries = 10;
while (numTries > 0) {
try {
Directory.Delete(tempDir, true);
numTries = 0;
}
catch {
System.Threading.Thread.Sleep(1);
numTries--;
}
}
}
}