예제 #1
0
        private void CompileMod(BuildingMod mod, List <LocalMod> refMods, bool forWindows, ref byte[] dll, ref byte[] pdb)
        {
            status.SetProgress(forWindows ? 0 : 1, 2);

            // use an assembly compiled by msbuild, instead of supplying our own
            if (Program.LaunchParameters.ContainsKey("-eac") && forWindows == windows)
            {
                var path = Program.LaunchParameters["-eac"];
                status.SetStatus(Language.GetTextValue("tModLoader.LoadingPrecompiled", forWindows ? "Windows.dll" : "Mono.dll"));
                PostProcess(path, !forWindows, mod.properties.includePDB && !forWindows);                 //post-processing still required on mono
                dll = File.ReadAllBytes(path);
                if (mod.properties.includePDB)
                {
                    pdb = File.ReadAllBytes(Path.ChangeExtension(path, forWindows ? "pdb" : "dll.mdb"));
                }
                return;
            }

            status.SetStatus(Language.GetTextValue("tModLoader.Compiling" + (forWindows ? "Windows" : "Mono"), mod));
            if (!DeveloperModeReady(out string msg))
            {
                status.LogError(msg);
                return;
            }

            //collect all dll references
            var tempDir = Path.Combine(ModPath, "compile_temp");

            Directory.CreateDirectory(tempDir);
            var refs = new List <string>();

            //everything used to compile the tModLoader for the target platform
            refs.AddRange(GetTerrariaReferences(tempDir, forWindows));

            // add framework assemblies
            refs.AddRange(Directory.GetFiles(referenceAssembliesPath, "*.dll", SearchOption.AllDirectories)
                          .Where(path => !path.EndsWith("Thunk.dll") && !path.EndsWith("Wrapper.dll")));

            //libs added by the mod
            refs.AddRange(mod.properties.dllReferences.Select(refDll => Path.Combine(mod.path, "lib/" + refDll + ".dll")));

            //all dlls included in all referenced mods
            foreach (var refMod in refMods)
            {
                using (refMod.modFile.EnsureOpen()) {
                    var path = Path.Combine(tempDir, refMod + ".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.GetBytes("lib/" + refDll + ".dll"));
                        refs.Add(path);
                    }
                }
            }

            var compileOptions = new CompilerParameters {
                OutputAssembly          = Path.Combine(tempDir, mod + ".dll"),
                GenerateExecutable      = false,
                GenerateInMemory        = false,
                TempFiles               = new TempFileCollection(tempDir, true),
                IncludeDebugInformation = mod.properties.includePDB,
                CompilerOptions         = "/optimize"
            };

            compileOptions.ReferencedAssemblies.AddRange(refs.ToArray());
            var files = Directory.GetFiles(mod.path, "*.cs", SearchOption.AllDirectories).Where(file => !mod.properties.ignoreFile(file.Substring(mod.path.Length + 1))).ToArray();

            try {
                var results = RoslynCompile(compileOptions, files);
                if (results.Errors.HasErrors)
                {
                    status.LogCompileErrors(mod.Name + (forWindows ? "/Windows.dll" : "/Mono.dll"), results.Errors,
                                            forWindows != windows ? Language.GetTextValue("tModLoader.BuildErrorModCompileFolderHint") : null);
                    return;
                }

                PostProcess(compileOptions.OutputAssembly, !forWindows, mod.properties.includePDB);

                dll = File.ReadAllBytes(compileOptions.OutputAssembly);
                if (mod.properties.includePDB)
                {
                    pdb = File.ReadAllBytes(Path.ChangeExtension(compileOptions.OutputAssembly, forWindows ? "pdb" : "dll.mdb"));
                }
            }
            finally {
                int numTries = 10;
                while (numTries > 0)
                {
                    try {
                        Directory.Delete(tempDir, true);
                        numTries = 0;
                    }
                    catch {
                        System.Threading.Thread.Sleep(1);
                        numTries--;
                    }
                }
            }
        }
예제 #2
0
        private void CompileMod(BuildingMod mod, List <LocalMod> refMods, bool forWindows,
                                ref byte[] dll, ref byte[] pdb)
        {
            if (!LoadCompilationReferences())
            {
                return;
            }

            bool generatePDB = mod.properties.includePDB && forWindows;

            if (generatePDB && !windows)
            {
                Console.WriteLine(Language.GetTextValue("tModLoader.BuildErrorPDBWindowsOnly"));
                generatePDB = false;
            }

            //collect all dll references
            var tempDir = Path.Combine(ModPath, "compile_temp");

            Directory.CreateDirectory(tempDir);
            var refs = new List <string>();

            //everything used to compile the tModLoader for the target platform
            refs.AddRange(GetTerrariaReferences(tempDir, forWindows));

            //libs added by the mod
            refs.AddRange(mod.properties.dllReferences.Select(refDll => Path.Combine(mod.path, "lib/" + refDll + ".dll")));

            //all dlls included in all referenced mods
            foreach (var refMod in refMods)
            {
                using (refMod.modFile.EnsureOpen()) {
                    var path = Path.Combine(tempDir, refMod + ".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.GetBytes("lib/" + refDll + ".dll"));
                        refs.Add(path);
                    }
                }
            }

            var compileOptions = new CompilerParameters {
                OutputAssembly          = Path.Combine(tempDir, mod + ".dll"),
                GenerateExecutable      = false,
                GenerateInMemory        = false,
                TempFiles               = new TempFileCollection(tempDir, true),
                IncludeDebugInformation = generatePDB,
                CompilerOptions         = "/optimize"
            };

            compileOptions.ReferencedAssemblies.AddRange(refs.ToArray());
            var files = Directory.GetFiles(mod.path, "*.cs", SearchOption.AllDirectories).Where(file => !mod.properties.ignoreFile(file.Substring(mod.path.Length + 1))).ToArray();

            try {
                var results = RoslynCompile(compileOptions, files);
                if (results.Errors.HasErrors)
                {
                    status.LogCompileErrors(mod.Name + (forWindows ? "/Windows.dll" : "/Mono.dll"), results.Errors,
                                            forWindows != windows ? Language.GetTextValue("tModLoader.BuildErrorModCompileFolderHint") : null);
                    return;
                }

                dll = File.ReadAllBytes(compileOptions.OutputAssembly);
                dll = PostProcess(dll, forWindows);
                if (generatePDB)
                {
                    pdb = File.ReadAllBytes(Path.Combine(tempDir, mod + ".pdb"));
                }
            }
            finally {
                int numTries = 10;
                while (numTries > 0)
                {
                    try {
                        Directory.Delete(tempDir, true);
                        numTries = 0;
                    }
                    catch {
                        System.Threading.Thread.Sleep(1);
                        numTries--;
                    }
                }
            }
        }