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;
            }
        }
Esempio n. 2
0
		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;
      }
Esempio n. 3
0
 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));
 }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        /// <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);
        }
Esempio n. 6
0
        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;
            }
        }
Esempio n. 7
0
        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);
            }
        }
Esempio n. 8
0
    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();
    }
Esempio n. 9
0
        /// <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);
        }
Esempio n. 10
0
        /// <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);
        }
Esempio n. 11
0
        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);
            }
        }
    }
Esempio n. 13
0
        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;
            }
        }
Esempio n. 14
0
        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);
        }
Esempio n. 16
0
        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;
                    }
                }
            }
        }
Esempio n. 17
0
        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;
            }
        }
Esempio n. 18
0
        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);
            }
        }
Esempio n. 19
0
    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);
        }
    }
Esempio n. 20
0
        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;
            }
        }