public void Update() { switch (builder.status) { case AssemblyBuilderStatus.NotStarted: if (dependencies.All(dep => dep.IsDone())) { if (dependencies.All(dep => dep.Success())) { builder.Build(); // all references are built, we can kick off this builder } else { m_Done = true; // this assembly won't be built since it's missing dependencies } } break; case AssemblyBuilderStatus.IsCompiling: return; // nothing to do case AssemblyBuilderStatus.Finished: m_Done = true; break; } }
private Assembly Generate() { var assemblyPath = Path.GetDirectoryName(this.assembly.Location); var trees = new ConcurrentBag<SyntaxTree>(); var allowUnsafe = false; Parallel.ForEach(assembly.GetExportedTypes() .Where(_ => string.IsNullOrWhiteSpace(_.Validate(this.options.Serialization, new AssemblyNameGenerator(_))) && !typeof(Array).IsAssignableFrom(_) && !typeof(Enum).IsAssignableFrom(_) && !typeof(ValueType).IsAssignableFrom(_) && !typeof(Delegate).IsAssignableFrom(_)), _ => { var builder = new AssemblyBuilder(_, new ReadOnlyDictionary<int, ReadOnlyCollection<HandlerInformation>>( new Dictionary<int, ReadOnlyCollection<HandlerInformation>>()), new SortedSet<string>(), this.options); builder.Build(); trees.Add(builder.Tree); allowUnsafe |= builder.IsUnsafe; }); var referencedAssemblies = this.assembly.GetReferencedAssemblies().Select(_ => Assembly.Load(_)).ToList(); referencedAssemblies.Add(this.assembly); var compiler = new AssemblyCompiler(trees, this.options.Optimization, new AssemblyNameGenerator(this.assembly).AssemblyName, referencedAssemblies.AsReadOnly(), currentDirectory, allowUnsafe, this.options.AllowWarnings); compiler.Compile(); return compiler.Result; }
public CompilationContext(SyntaxTree syntaxTree, CompilationOptions options) { SyntaxTree = syntaxTree; Options = options; _assembly = new Lazy <AssemblyDefinition>(() => AssemblyBuilder.Build(this)); _module = new Lazy <ModuleDefinition>(() => ModuleBuilder.Build(this)); _typeDef = new Lazy <TypeDefinition>(() => TypeBuilder.Build(this)); }
public static AssemblyDefinition Build(IWeaverLogger logger) { AssemblyDefinition assembly = null; var assemblyBuilder = new AssemblyBuilder(Path.Combine(OutputDirectory, OutputFile), SourceFiles.ToArray()) { referencesOptions = ReferencesOptions.UseEngineModules }; if (AllowUnsafe) { assemblyBuilder.compilerOptions.AllowUnsafeCode = true; } assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { CompilerMessages.AddRange(compilerMessages); foreach (CompilerMessage cm in compilerMessages) { if (cm.type == CompilerMessageType.Error) { Debug.Log($"Error At: {cm.file}:{ cm.line} -- {cm.message}"); CompilerErrors = true; } } Debug.LogWarning($"Test Assembler errors: {CompilerErrors} for {OutputFile}"); // assembly builder does not call ILPostProcessor (WTF Unity?), so we must invoke it ourselves. var compiledAssembly = new CompiledAssembly(assemblyPath) { Defines = assemblyBuilder.defaultDefines, References = assemblyBuilder.defaultReferences }; var weaver = new Weaver(logger); assembly = weaver.Weave(compiledAssembly); }; // Start build of assembly if (!assemblyBuilder.Build()) { Debug.LogErrorFormat("Failed to start build of assembly {0}", assemblyBuilder.assemblyPath); return(assembly); } while (assemblyBuilder.status != AssemblyBuilderStatus.Finished) { System.Threading.Thread.Sleep(10); } return(assembly); }
/// <summary> /// Builds and Weaves an Assembly with references to unity engine and other asmdefs. /// <para> /// NOTE: Does not write the weaved assemble to disk /// </para> /// </summary> public AssemblyDefinition Build(IWeaverLogger logger) { AssemblyDefinition assembly = null; // This will compile scripts with the same references as files in the asset folder. // This means that the dll will get references to all asmdef just as if it was the default "Assembly-CSharp.dll" var assemblyBuilder = new AssemblyBuilder(ProjectPathFile, sourceFiles.ToArray()) { referencesOptions = ReferencesOptions.UseEngineModules }; assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { #if !UNITY_2020_2_OR_NEWER CompilerMessages.AddRange(compilerMessages); foreach (CompilerMessage cm in compilerMessages) { if (cm.type == CompilerMessageType.Error) { Debug.LogErrorFormat("{0}:{1} -- {2}", cm.file, cm.line, cm.message); CompilerErrors = true; } } #endif // assembly builder does not call ILPostProcessor (WTF Unity?), so we must invoke it ourselves. var compiledAssembly = new CompiledAssembly(assemblyPath) { Defines = assemblyBuilder.defaultDefines, References = assemblyBuilder.defaultReferences }; var weaver = new Weaver(logger); assembly = weaver.Weave(compiledAssembly); }; // Start build of assembly if (!assemblyBuilder.Build()) { Debug.LogErrorFormat("Failed to start build of assembly {0}", assemblyBuilder.assemblyPath); return(assembly); } while (assemblyBuilder.status != AssemblyBuilderStatus.Finished) { System.Threading.Thread.Sleep(10); } return(assembly); }
public void Execute() { var scriptPaths = Directory.GetFiles(_sourcesDir, "*.cs", SearchOption.AllDirectories); var ab = new AssemblyBuilder(_outputAssemblyPath, scriptPaths); ab.compilerOptions = new ScriptCompilerOptions(); ab.additionalReferences = GetDepends(); ab.buildFinished += OnFinished; if (false == ab.Build()) { onFinished?.Invoke(this, false); onFinished = null; } }
public void Run(FSSnapshot source) { // create syntax tree var trees = source .Files .OfType <FSTextFile>() .Where(f => f.Name.EndsWith(".cs")) .ToDictionary(f => f.Name, f => CSharpSyntaxTree.ParseText(f.Content)); // compile into assembly and load into library var builder = new AssemblyBuilder(); var library = builder.Build(trees.Values); // translate each source file foreach (var tree in trees) { var fileName = Path.GetFileNameWithoutExtension(tree.Key); var context = new TranslationContext() { Library = library, Root = tree.Value, FileName = fileName, }; var content = new SourceFileVisitor().Translate(context, tree.Value); Result.Files.Add(new FSTextFile() { Name = $"{fileName}.h", Content = content["h"] }); Result.Files.Add(new FSTextFile() { Name = $"{fileName}.cpp", Content = content["cpp"] }); SOCResources.AddRange(context.SOCResources); } }
public static void DoBuild(bool debugMode, bool waitComplete = true) { CheckOutputPath(); var csFiles = Directory.GetFiles(ScriptsPath, "*.cs", SearchOption.AllDirectories); List <string> files = new List <string>(csFiles.Length); foreach (var file in csFiles) { files.Add(file.Replace("\\", "/")); } var builder = new AssemblyBuilder(DllFullPath, files.ToArray()) { flags = debugMode ? AssemblyBuilderFlags.DevelopmentBuild : AssemblyBuilderFlags.None }; builder.excludeReferences = new string[] { "Library/ScriptAssemblies/Hotfix.dll", "Library/ScriptAssemblies/Hotfix.Framework.dll", "Library/ScriptAssemblies/Hotfix.Logic.dll", "Library/ScriptAssemblies/Hotfix.View.dll", }; if (!debugMode) { var buildOption = builder.compilerOptions; buildOption.CodeOptimization = CodeOptimization.Release; builder.compilerOptions = buildOption; } builder.buildFinished += OnBuildFinished; builder.buildStarted += delegate(string path) { Debug.Log("开始编译Hotfix"); }; builder.Build(); while (waitComplete && builder.status != AssemblyBuilderStatus.Finished) { EditorUtility.DisplayProgressBar("编译", "等待编译结束", 0.5f); } EditorUtility.ClearProgressBar(); }
/// <summary> /// Compiles C# files using AssemblyBuilder API. /// </summary> /// <param name="assemblyPath">Path to .dll to be created (directory must exist and be writable).</param> /// <param name="scriptPaths">Paths to C# files.</param> /// <returns>Value indicating if operation was succesful.</returns> internal static bool Compile(string assemblyPath, params string[] scriptPaths) { var assemblyBuilder = new AssemblyBuilder(assemblyPath, scriptPaths) { referencesOptions = ReferencesOptions.UseEngineModules, buildTargetGroup = BuildTargetGroup.Standalone, additionalReferences = GetAdditionalReferences() }; assemblyBuilder.buildFinished += AssemblyBuilder_buildFinished; try { if (!assemblyBuilder.Build()) { Debug.LogError($"Failed to start build of assembly {assemblyPath}."); return(false); } while (assemblyBuilder.status != AssemblyBuilderStatus.Finished) { System.Threading.Thread.Sleep(10); } } finally { assemblyBuilder.buildFinished -= AssemblyBuilder_buildFinished; } if (!File.Exists(assemblyPath)) { Debug.LogError($"Failed to build {assemblyPath}."); return(false); } return(true); }
/// <summary> /// Builds and Weaves an Assembly with references to unity engine and other asmdefs. /// <para> /// NOTE: Does not write the weaved assemble to disk /// </para> /// </summary> public async Task <AssemblyDefinition> BuildAsync(IWeaverLogger logger) { Log($"Assembler.Build for {OutputFile}"); if (UnityEditor.EditorApplication.isCompiling) { Debug.LogWarning("Assembler.Build Already compiling, AssemblyBuilder build may fail"); } this.logger = logger; // This will compile scripts with the same references as files in the asset folder. // This means that the dll will get references to all asmdef just as if it was the default "Assembly-CSharp.dll" builder = new AssemblyBuilder(ProjectPathFile, sourceFiles.ToArray()) { referencesOptions = ReferencesOptions.UseEngineModules, }; builder.buildFinished += buildFinished; var started = builder.Build(); // Start build of assembly if (!started) { Debug.LogErrorFormat("Failed to start build of assembly {0}", builder.assemblyPath); return(builtAssembly); } while (builder.status != AssemblyBuilderStatus.Finished) { await Task.Yield(); } return(builtAssembly); }
private static void BuildMuteAssembly(string Name, string[] CodeDirectorys) { List <string> Scripts = new List <string>(); for (int i = 0; i < CodeDirectorys.Length; i++) { DirectoryInfo dti = new DirectoryInfo(CodeDirectorys[i]); FileInfo[] fileInfos = dti.GetFiles("*.cs", System.IO.SearchOption.AllDirectories); for (int j = 0; j < fileInfos.Length; j++) { Scripts.Add(fileInfos[j].FullName); } } string outputAssembly = "Temp/MyAssembly/" + Name + ".dll"; Directory.CreateDirectory("Temp/MyAssembly"); AssemblyBuilder assemblyBuilder = new AssemblyBuilder(outputAssembly, Scripts.ToArray()); //启用UnSafe assemblyBuilder.compilerOptions.AllowUnsafeCode = true; BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); assemblyBuilder.compilerOptions.ApiCompatibilityLevel = PlayerSettings.GetApiCompatibilityLevel(buildTargetGroup); // assemblyBuilder.compilerOptions.ApiCompatibilityLevel = ApiCompatibilityLevel.NET_4_6; assemblyBuilder.flags = AssemblyBuilderFlags.None; //AssemblyBuilderFlags.None 正常发布 //AssemblyBuilderFlags.DevelopmentBuild 开发模式打包 //AssemblyBuilderFlags.EditorAssembly 编辑器状态 assemblyBuilder.referencesOptions = ReferencesOptions.UseEngineModules; assemblyBuilder.buildTarget = EditorUserBuildSettings.activeBuildTarget; assemblyBuilder.buildTargetGroup = buildTargetGroup; //添加额外的宏定义 // assemblyBuilder.additionalDefines = new[] // { // "" // }; //需要排除自身的引用 //assemblyBuilder.excludeReferences = new[] //{ // "Library/ScriptAssemblies/Unity.Model.dll", // "Library/ScriptAssemblies/Unity.ModelView.dll", // "Library/ScriptAssemblies/Unity.Hotfix.dll", // "Library/ScriptAssemblies/Unity.HotfixView.dll" //}; assemblyBuilder.buildStarted += delegate(string assemblyPath) { Debug.LogFormat("build start:" + assemblyPath); }; assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { int errorCount = compilerMessages.Count(m => m.type == CompilerMessageType.Error); int warningCount = compilerMessages.Count(m => m.type == CompilerMessageType.Warning); Debug.LogFormat("Warnings: {0} - Errors: {1}", warningCount, errorCount); if (warningCount > 0) { Debug.LogFormat("有{0}个Warning!!!", warningCount); } if (errorCount > 0) { for (int i = 0; i < compilerMessages.Length; i++) { if (compilerMessages[i].type == CompilerMessageType.Error) { Debug.LogError(compilerMessages[i].message); } } } }; //开始构建 if (!assemblyBuilder.Build()) { Debug.LogErrorFormat("build fail:" + assemblyBuilder.assemblyPath); return; } AfterCompiling(assemblyBuilder).Coroutine(); }
public static void BuildAssembly() { // 创建目录 if (Directory.Exists(ILRDefine.StrAssemblyTemperDir) == false) { Directory.CreateDirectory(ILRDefine.StrAssemblyTemperDir); } string csprojPath = $"{ILRDefine.StrHotfixAssemblyName}.csproj"; string outputPath = $"{ILRDefine.StrAssemblyTemperDir}/{ILRDefine.StrHotfixAssemblyName}.dll"; string[] scripts = GetScripts(csprojPath); var assemblyBuilder = new AssemblyBuilder(outputPath, scripts); assemblyBuilder.compilerOptions = new ScriptCompilerOptions(); assemblyBuilder.compilerOptions.AllowUnsafeCode = false; assemblyBuilder.compilerOptions.ApiCompatibilityLevel = ApiCompatibilityLevel.NET_4_6; assemblyBuilder.flags = AssemblyBuilderFlags.None; assemblyBuilder.additionalReferences = GetRefrences(csprojPath); // Started assemblyBuilder.buildStarted += delegate(string assemblyPath) { Debug.Log($"Assembly build started for {assemblyPath}"); }; // Finished assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { var errorCount = compilerMessages.Count(m => m.type == CompilerMessageType.Error); var warningCount = compilerMessages.Count(m => m.type == CompilerMessageType.Warning); Debug.Log($"Assembly build finished for {assemblyPath}"); Debug.Log($"Warnings: {warningCount} - Errors: {errorCount}"); foreach (var cm in compilerMessages) { if (cm.type == CompilerMessageType.Warning) { Debug.LogWarning(cm.message); } if (cm.type == CompilerMessageType.Error) { Debug.LogError(cm.message); } } if (errorCount == 0) { CopyAssemblyFiles(); } }; // 开始构建程序集 if (!assemblyBuilder.Build()) { Debug.LogErrorFormat("Failed to start build of assembly {0}!", assemblyBuilder.assemblyPath); return; } // 等待编译结束 if (true) { while (assemblyBuilder.status != AssemblyBuilderStatus.Finished) { System.Threading.Thread.Sleep(10); } } }
private static void BuildMuteAssembly(string assemblyName, string[] CodeDirectorys, string[] additionalReferences, CodeOptimization codeOptimization) { List <string> scripts = new List <string>(); for (int i = 0; i < CodeDirectorys.Length; i++) { DirectoryInfo dti = new DirectoryInfo(CodeDirectorys[i]); FileInfo[] fileInfos = dti.GetFiles("*.cs", System.IO.SearchOption.AllDirectories); for (int j = 0; j < fileInfos.Length; j++) { scripts.Add(fileInfos[j].FullName); } } string dllPath = Path.Combine(Define.BuildOutputDir, $"{assemblyName}.dll"); string pdbPath = Path.Combine(Define.BuildOutputDir, $"{assemblyName}.pdb"); File.Delete(dllPath); File.Delete(pdbPath); Directory.CreateDirectory(Define.BuildOutputDir); AssemblyBuilder assemblyBuilder = new AssemblyBuilder(dllPath, scripts.ToArray()); //启用UnSafe //assemblyBuilder.compilerOptions.AllowUnsafeCode = true; BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); assemblyBuilder.compilerOptions.CodeOptimization = codeOptimization; assemblyBuilder.compilerOptions.ApiCompatibilityLevel = PlayerSettings.GetApiCompatibilityLevel(buildTargetGroup); // assemblyBuilder.compilerOptions.ApiCompatibilityLevel = ApiCompatibilityLevel.NET_4_6; assemblyBuilder.additionalReferences = additionalReferences; assemblyBuilder.flags = AssemblyBuilderFlags.None; //AssemblyBuilderFlags.None 正常发布 //AssemblyBuilderFlags.DevelopmentBuild 开发模式打包 //AssemblyBuilderFlags.EditorAssembly 编辑器状态 assemblyBuilder.referencesOptions = ReferencesOptions.UseEngineModules; assemblyBuilder.buildTarget = EditorUserBuildSettings.activeBuildTarget; assemblyBuilder.buildTargetGroup = buildTargetGroup; assemblyBuilder.buildStarted += delegate(string assemblyPath) { Debug.LogFormat("build start:" + assemblyPath); }; assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { int errorCount = compilerMessages.Count(m => m.type == CompilerMessageType.Error); int warningCount = compilerMessages.Count(m => m.type == CompilerMessageType.Warning); Debug.LogFormat("Warnings: {0} - Errors: {1}", warningCount, errorCount); if (warningCount > 0) { Debug.LogFormat("有{0}个Warning!!!", warningCount); } if (errorCount > 0) { for (int i = 0; i < compilerMessages.Length; i++) { if (compilerMessages[i].type == CompilerMessageType.Error) { Debug.LogError(compilerMessages[i].message); } } } }; //开始构建 if (!assemblyBuilder.Build()) { Debug.LogErrorFormat("build fail:" + assemblyBuilder.assemblyPath); return; } }
private static void BuildMuteAssembly(string assemblyName, string[] CodeDirectorys, string[] additionalReferences, CodeOptimization codeOptimization, Action completed) { List <string> scripts = new List <string>(); for (int i = 0; i < CodeDirectorys.Length; i++) { DirectoryInfo dti = new DirectoryInfo(CodeDirectorys[i]); FileInfo[] fileInfos = dti.GetFiles("*.cs", System.IO.SearchOption.AllDirectories); for (int j = 0; j < fileInfos.Length; j++) { scripts.Add(fileInfos[j].FullName); } } string dllPath = "Assets/StreamingAssets/DLL/" + assemblyName + ".dll"; AssemblyBuilder assemblyBuilder = new AssemblyBuilder(dllPath, scripts.ToArray()); BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); assemblyBuilder.compilerOptions.CodeOptimization = codeOptimization; assemblyBuilder.compilerOptions.ApiCompatibilityLevel = PlayerSettings.GetApiCompatibilityLevel(buildTargetGroup); // assemblyBuilder.compilerOptions.ApiCompatibilityLevel = ApiCompatibilityLevel.NET_4_6; assemblyBuilder.additionalReferences = additionalReferences; assemblyBuilder.flags = AssemblyBuilderFlags.None; //AssemblyBuilderFlags.None 正常发布 //AssemblyBuilderFlags.DevelopmentBuild 开发模式打包 //AssemblyBuilderFlags.EditorAssembly 编辑器状态 assemblyBuilder.referencesOptions = ReferencesOptions.UseEngineModules; assemblyBuilder.buildTarget = EditorUserBuildSettings.activeBuildTarget; assemblyBuilder.buildTargetGroup = buildTargetGroup; assemblyBuilder.buildStarted += delegate(string assemblyPath) { Debug.LogFormat("热更代码编译开始"); }; assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { AssetDatabase.Refresh(); int errorCount = compilerMessages.Count(m => m.type == CompilerMessageType.Error); int warningCount = compilerMessages.Count(m => m.type == CompilerMessageType.Warning); Debug.LogFormat("Warnings: {0} - Errors: {1}", warningCount, errorCount); if (warningCount > 0) { Debug.LogFormat("有{0}个Warning!!!", warningCount); } if (errorCount == 0) { Debug.Log("热更代码编译成功"); completed?.Invoke(); } else { for (int i = 0; i < compilerMessages.Length; i++) { if (compilerMessages[i].type == CompilerMessageType.Error) { Debug.LogError(compilerMessages[i].message); } } } }; //开始构建 if (!assemblyBuilder.Build()) { Debug.LogErrorFormat("热更代码编译失败"); return; } while (assemblyBuilder.status != AssemblyBuilderStatus.Finished) { System.Threading.Thread.Sleep(10); } }
internal static bool BuildAssembly(string[] paths, string outputPath, string[] excludeReferences = null, string[] additionalReferences = null, string[] additionalDefines = null) { if (paths == null || paths.Length == 0) { return(false); } Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); additionalReferences = additionalReferences == null ? predefinedReferences : predefinedReferences.Concat(additionalReferences).ToArray(); var assemblyBuilder = new AssemblyBuilder(outputPath, paths) { additionalDefines = additionalDefines, excludeReferences = excludeReferences, referencesOptions = ReferencesOptions.UseEngineModules, additionalReferences = additionalReferences, compilerOptions = new ScriptCompilerOptions() { AllowUnsafeCode = true } }; bool buildSucceed = false; assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { foreach (var m in compilerMessages) { switch (m.type) { case CompilerMessageType.Warning: Debug.LogWarning(m.message); break; case CompilerMessageType.Error: Debug.LogError(m.message); break; default: Debug.Log(m.message); break; } } var errorCount = compilerMessages.Count(m => m.type == CompilerMessageType.Error); var warningCount = compilerMessages.Count(m => m.type == CompilerMessageType.Warning); if (warningCount > 0 || errorCount > 0) { Debug.Log($"Assembly build finished for {assemblyPath} -- Warnings: {warningCount} - Errors: {errorCount}"); } if (errorCount != 0) { return; } buildSucceed = true; }; if (!assemblyBuilder.Build()) { Debug.LogErrorFormat("Failed to start build of assembly {0}!", assemblyBuilder.assemblyPath); return(false); } while (assemblyBuilder.status != AssemblyBuilderStatus.Finished) { Thread.Sleep(10); } return(buildSucceed); }
static void BuildAssembly(bool wait) { for (int i = 0; i < AssembliesToolsConfig.GetInstance().buildPathList.Count; i++) { var buildInfo = AssembliesToolsConfig.GetInstance().buildPathList[i]; if (!string.IsNullOrEmpty(buildInfo.srcPath) && !string.IsNullOrEmpty(buildInfo.buildPath) && !string.IsNullOrEmpty(buildInfo.projectPath)) { bool[] editorFlags = { true, true, true, true }; List <string> csFilePaths = new List <string>(); XFolderTools.TraverseFiles(buildInfo.srcPath, (string fullPath) => { if (Path.GetExtension(fullPath) == ".cs") { csFilePaths.Add(fullPath); } }, true); string srcPathName = Path.GetFileNameWithoutExtension(buildInfo.srcPath); string outputAssembly = XPathTools.Combine(buildInfo.buildPath, string.Format("{0}.dll", srcPathName)); string assemblyProjectPath = XPathTools.Combine(buildInfo.projectPath, string.Format("{0}.dll", srcPathName)); if (csFilePaths.Count > 0) { if (!XFolderTools.Exists(buildInfo.buildPath)) { XFolderTools.CreateDirectory(buildInfo.buildPath); } if (!XFolderTools.Exists(buildInfo.projectPath)) { XFolderTools.CreateDirectory(buildInfo.projectPath); } bool editorFlag = editorFlags[i]; var assemblyBuilder = new AssemblyBuilder(outputAssembly, csFilePaths.ToArray()); // Exclude a reference to the copy of the assembly in the Assets folder, if any. assemblyBuilder.excludeReferences = new string[] { assemblyProjectPath }; if (editorFlag) { assemblyBuilder.flags = AssemblyBuilderFlags.EditorAssembly; } // Called on main thread assemblyBuilder.buildStarted += delegate(string assemblyPath) { Debug.LogFormat("Assembly build started for {0}", assemblyPath); }; // Called on main thread assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { foreach (var v in compilerMessages) { if (v.type == CompilerMessageType.Error) { Debug.LogError(v.message); } else { Debug.LogWarning(v.message); } } var errorCount = compilerMessages.Count(m => m.type == CompilerMessageType.Error); var warningCount = compilerMessages.Count(m => m.type == CompilerMessageType.Warning); Debug.LogFormat("Assembly build finished for {0}", assemblyPath); Debug.LogFormat("Warnings: {0} - Errors: {0}", errorCount, warningCount); if (errorCount == 0) { File.Copy(outputAssembly, assemblyProjectPath, true); AssetDatabase.ImportAsset(assemblyProjectPath); } }; // Start build of assembly if (!assemblyBuilder.Build()) { Debug.LogErrorFormat("Failed to start build of assembly {0}!", assemblyBuilder.assemblyPath); return; } if (wait) { while (assemblyBuilder.status != AssemblyBuilderStatus.Finished) { System.Threading.Thread.Sleep(10); } } } else { XFileTools.Delete(assemblyProjectPath); continue; } } } }
void BuildInternal(buildCompleteAction onComplete) { Output = null; if (!BuildDirectory.Exists) { BuildDirectory.Create(); } var outputPath = PathUtilities.AddSlash(BuildDirectory.FullName) + FileName; //Debug.Log("Build Output Path = " + outputPath); //Debug.Log("Build Directory = " + BuildDirectory.FullName); //Debug.Log("Filename = " + FileName); AssemblyBuilder builder = new AssemblyBuilder(outputPath, Scripts.ToArray()); builder.additionalDefines = Defines.ToArray(); builder.additionalReferences = References.ToArray(); builder.buildTarget = Target; builder.buildTargetGroup = TargetGroup; builder.excludeReferences = VerifyPaths(ExcludedReferences); builder.flags = Flags; Action <string, CompilerMessage[]> buildCompleteAction = null; var outputInfo = new OutputDetails(); outputInfo.OutputPath = outputPath; buildCompleteAction = (dest, messages) => { //Debug.Log("---------Dest = " + dest); outputInfo.CompilerMessages = messages; Building = false; if (messages.Any(cm => cm.type == CompilerMessageType.Error)) { Debug.LogError("Error building assembly = " + FileName); string assemblyReferences = "References: " + Environment.NewLine; foreach (var reference in References.Concat(GetDefaultReferences())) { assemblyReferences += reference + Environment.NewLine; } Debug.LogError(assemblyReferences); string assemblyExclusions = "Exclusions: " + Environment.NewLine; foreach (var exclusion in ExcludedReferences) { assemblyExclusions += exclusion + Environment.NewLine; } Debug.LogError(assemblyExclusions); outputInfo.Success = false; foreach (var message in messages) { if (message.type == CompilerMessageType.Error) { Debug.LogError(message.message); } else { //Debug.LogWarning(message.message); } } } else { outputInfo.Success = true; } //Debug.Log("_____SUCCESS = " + outputInfo.Success); builder.buildFinished -= buildCompleteAction; Output = outputInfo; if (onComplete != null) { onComplete(Output); } }; Building = true; try { builder.buildFinished += buildCompleteAction; builder.Build(); } catch (Exception) { builder.buildFinished -= buildCompleteAction; Building = false; throw; } }
public static void Build(Action <string> OnWarning, Action <string> OnError) { AssemblyBuilder assemblyBuilder = new AssemblyBuilder(Path.Combine(OutputDirectory, OutputFile), SourceFiles.ToArray()) { // "The type 'MonoBehaviour' is defined in an assembly that is not referenced" referencesOptions = ReferencesOptions.UseEngineModules }; if (AllowUnsafe) { assemblyBuilder.compilerOptions.AllowUnsafeCode = true; } #if UNITY_2020_3_OR_NEWER // Unity automatically invokes ILPostProcessor after // AssemblyBuilder.Build() (on windows at least. not on mac). // => .buildFinished() below CompilerMessages would already contain // the weaver messages, failing tests. // => SyncVarTests->SyncVarSyncList fails too if ILPP was // already applied by Unity, and we apply it again. // // we need to not run ILPP for WeaverTests assemblies here. // -> we can't set member variables because Unity creates a new // ILPP instance internally and invokes it // -> define is passed through ILPP though, and avoids static state. assemblyBuilder.additionalDefines = new [] { ILPostProcessorHook.IgnoreDefine }; #endif assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { // CompilerMessages from compiling the original test assembly. // note that we can see weaver messages here if Unity runs // ILPostProcessor after AssemblyBuilder.Build(). // => that's why we pass the ignore define above. CompilerMessages.AddRange(compilerMessages); foreach (CompilerMessage cm in compilerMessages) { if (cm.type == CompilerMessageType.Error) { Debug.LogError($"{cm.file}:{cm.line} -- {cm.message}"); CompilerErrors = true; } } #if UNITY_2020_3_OR_NEWER // on 2018/2019, CompilationFinishedHook weaves after building. // on 2020, ILPostProcessor weaves after building. // on windows, it runs after AssemblyBuilder.Build() // on mac, it does not run after AssemblyBuidler.Build() // => run it manually in all cases // => this way we can feed result.Logs to test results too // NOTE: we could simply call Weaver.Weave() here. // but let's make all tests run through ILPP. // just like regular projects would. // helps catch issues early. // copy references from assemblyBuilder's references List <string> references = new List <string>(); if (assemblyBuilder.defaultReferences != null) { references.AddRange(assemblyBuilder.defaultReferences); } if (assemblyBuilder.additionalReferences != null) { references.AddRange(assemblyBuilder.additionalReferences); } // invoke ILPostProcessor with an assembly from file. // NOTE: code for creating and invoking the ILPostProcessor has // to be in Weaver.dll where 'CompilationPipeline' is // available due to name being of form 'Unity.*.CodeGen'. // => we can't change tests to that Unity.*.CodeGen // because some tests need to be weaved, but ILPP isn't // ran on Unity.*.CodeGen assemblies itself. ILPostProcessorFromFile.ILPostProcessFile(assemblyPath, references.ToArray(), OnWarning, OnError); #endif }; // Start build of assembly if (!assemblyBuilder.Build()) { Debug.LogError($"Failed to start build of assembly {assemblyBuilder.assemblyPath}"); return; } while (assemblyBuilder.status != AssemblyBuilderStatus.Finished) { Thread.Sleep(10); } }
public static void Build() { var getFilePath = Application.dataPath + "/" + HotFixCodePath; Debug.Log("getFilePath" + getFilePath); string[] scritpsFilePaths = Directory.GetFiles(getFilePath, "*.cs", SearchOption.AllDirectories).Where( x => !x.Contains("AssemblyInfo") && !x.Contains("TemporaryGeneratedFile")).ToArray(); #region 根据csproj过滤工程 //var csProjTxt= File.ReadAllText(Application.dataPath + "/" +HotFixCsproj); //XMLParser p =new XMLParser(); //p.Parse(csProjTxt); //var projXml = p.ToXml(); //projXml.GetChildNodeList("ItemGroup"); #endregion AssemblyBuilder assemblyBuilder = new AssemblyBuilder("Assets/Resources/Data/HotfixCode/Hotfix_dll.bytes", scritpsFilePaths); assemblyBuilder.buildTarget = EditorUserBuildSettings.activeBuildTarget; List <string> assemblyNamesList = new List <string>(); foreach (UnityEditor.Compilation.Assembly assembly in CompilationPipeline.GetAssemblies()) { if ((assembly.flags & AssemblyFlags.EditorAssembly) == AssemblyFlags.None) { if (assembly.name.Contains("spine")) { continue; } assemblyNamesList.Add("Temp/UnityVS_bin/Debug/" + assembly.name + ".dll"); } } //EditorBuildRules assemblyBuilder.additionalReferences = assemblyNamesList.ToArray(); assemblyBuilder.flags = AssemblyBuilderFlags.DevelopmentBuild; //assemblyBuilder.c assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { var errorCount = compilerMessages.Count(m => m.type == CompilerMessageType.Error); var warningCount = compilerMessages.Count(m => m.type == CompilerMessageType.Warning); Debug.LogFormat("Assembly build finished for {0}", assemblyPath); Debug.LogFormat("Warnings: {0} - Errors: {0}", errorCount, warningCount); if (errorCount > 0) { foreach (var _compilerMessage in compilerMessages) { if (_compilerMessage.type == CompilerMessageType.Error) { Debug.LogErrorFormat("File {0} Msg {1} ", _compilerMessage.file, _compilerMessage.message); } else { Debug.LogFormat("File {0} Msg {1} ", _compilerMessage.file, _compilerMessage.message); } } } }; if (assemblyBuilder.Build()) { Debug.Log("BuildSuccess"); } else { Debug.LogErrorFormat("Failed to start build of assembly {0}!", assemblyBuilder.assemblyPath); } }
public static void BuildMuteAssembly() { List <string> scripts = new List <string>(); for (int i = 0; i < s_OriginScriptsDirs.Length; i++) { DirectoryInfo dti = new DirectoryInfo(s_OriginScriptsDirs[i]); FileInfo[] fileInfos = dti.GetFiles("*.cs", System.IO.SearchOption.AllDirectories); for (int j = 0; j < fileInfos.Length; j++) { scripts.Add(fileInfos[j].FullName); } } string outputAssembly = s_ScriptAssembliesDir + s_FinalHotfixDllName + ".dll"; Directory.CreateDirectory(s_ScriptAssembliesDir); BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); AssemblyBuilder assemblyBuilder = new AssemblyBuilder(outputAssembly, scripts.ToArray()); //启用UnSafe assemblyBuilder.compilerOptions.AllowUnsafeCode = true; assemblyBuilder.compilerOptions.ApiCompatibilityLevel = PlayerSettings.GetApiCompatibilityLevel(buildTargetGroup); assemblyBuilder.compilerOptions.CodeOptimization = CodeOptimization.Release; assemblyBuilder.flags = AssemblyBuilderFlags.DevelopmentBuild; //AssemblyBuilderFlags.None 正常发布 //AssemblyBuilderFlags.DevelopmentBuild 开发模式打包 //AssemblyBuilderFlags.EditorAssembly 编辑器状态 assemblyBuilder.referencesOptions = ReferencesOptions.UseEngineModules; assemblyBuilder.buildTarget = EditorUserBuildSettings.activeBuildTarget; assemblyBuilder.buildTargetGroup = buildTargetGroup; //添加额外的宏定义 // assemblyBuilder.additionalDefines = new[] // { // "" // }; //需要排除自身的引用 assemblyBuilder.excludeReferences = s_OriginDllDirs; assemblyBuilder.buildStarted += delegate(string assemblyPath) { Debug.LogFormat("程序集开始构建:" + assemblyPath); }; assemblyBuilder.buildFinished += delegate(string assemblyPath, CompilerMessage[] compilerMessages) { int errorCount = compilerMessages.Count(m => m.type == CompilerMessageType.Error); int warningCount = compilerMessages.Count(m => m.type == CompilerMessageType.Warning); Debug.LogFormat("程序集构建完成:" + assemblyPath); Debug.LogFormat("Warnings: {0} - Errors: {1}", warningCount, errorCount); for (int i = 0; i < compilerMessages.Length; i++) { if (compilerMessages[i].type == CompilerMessageType.Error) { Debug.LogError(compilerMessages[i].message); } if (compilerMessages[i].type == CompilerMessageType.Warning) { Debug.LogWarning(compilerMessages[i].message); } } if (errorCount == 0) { CopyDllAndPdb(s_FinalHotfixDllName); } }; //开始构建 if (!assemblyBuilder.Build()) { Debug.LogErrorFormat("构建程序集失败:" + assemblyBuilder.assemblyPath + "构建程序集时遇到致命错误,请修复!"); return; } }