找回密码
 立即注册
查看: 348|回复: 0

[Unity 3d] 编辑器程序集编译API - 笔记

[复制链接]
发表于 2022-5-11 10:47 | 显示全部楼层 |阅读模式
本文是个笔记,记录 2 个编辑器下编译程序集的逻辑。
一 . 编译 Runtime 用的程序集

Runtime 用的程序集:特征是会剔除 #if UNITY_EDITOR 注释的逻辑块)
  public static void OnAssemblyBuildRequired()        {            // todo 目前是全部都编译,有木有方法只编译需要的 程序集呢?            var buildDir = Application.temporaryCachePath;            var files = new DirectoryInfo(buildDir).GetFiles();            foreach (var file in files)            {                FileUtil.DeleteFileOrDirectory(file.FullName);            }                        var target = EditorUserBuildSettings.activeBuildTarget;            var group = BuildPipeline.GetBuildTargetGroup(target);            ScriptCompilationSettings scriptCompilationSettings = default;            scriptCompilationSettings.group = group;            scriptCompilationSettings.target = target;            ScriptCompilationResult scriptCompilationResult = PlayerBuildInterface.CompilePlayerScripts(scriptCompilationSettings, buildDir);            var lib_dir = Path.Combine(Application.dataPath, "..", "Library\\ScriptAssemblies");            foreach (var item in Instance.assemblies)            {                if (item.IsValid)    // 如果配置正确则尝试转存储文件                {                    var file = new FileInfo(Path.Combine(lib_dir, item.Dll));                    var lastWriteTime = file.LastWriteTime.Ticks;                    if (item.lastWriteTime < lastWriteTime)                    {                        item.lastWriteTime = lastWriteTime;                        FileUtil.ReplaceFile(Path.Combine(buildDir, item.Dll), item.OutputPath);                        item.UpdateInformation();                    }                }                else                {                    Debug.LogError($"{nameof(AssemblyHotfixManager)}: 请先完善 Hotfix Configuration 配置项!");                }            }            EditorUtility.SetDirty(Instance);        }
    Build App 使用的这个APIAddressable 也是这个API
二 . 编译指定 .asmdef 定义的程序集

   public static void SyncAssemblyRawData(bool forceCompilie = false)    {                  // 1.  dll 编译存放处            var lib_dir = Path.Combine(Application.dataPath, "..", "Library\\ScriptAssemblies");            foreach (var item in Instance.assemblies)            {                // 如果配置正确则开始尝试编译                if (item.IsValid)                {                    var data = JsonUtility.FromJson<SimplifiedAssemblyData>(item.assembly.text);                    var dll = Path.Combine(lib_dir, $"{data.name}.dll");                    var temp = Path.Combine(Application.temporaryCachePath, $"{data.name}.bytes");                    var file = new FileInfo(dll);                    if (file.Exists)                    {                        var lastWriteTime = file.LastWriteTime.Ticks;                        if (forceCompilie || item.lastWriteTime < lastWriteTime)                        {                            item.lastWriteTime = lastWriteTime;                            var assembly = CompilationPipeline.GetAssemblies(AssembliesType.Player).FirstOrDefault(v => v.name == item.assembly.name);                            if (null != assembly)                            {                                // Compiles scripts outside the Assets folder into a managed assembly that can be used inside the Assets folder.                                AssemblyBuilder builder = new AssemblyBuilder(temp, assembly.sourceFiles);                                builder.compilerOptions.AllowUnsafeCode = item.AllowUnsafeCode;                                BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);                                builder.compilerOptions.ApiCompatibilityLevel = PlayerSettings.GetApiCompatibilityLevel(buildTargetGroup);                                builder.additionalReferences = assembly.allReferences;                                builder.flags = AssemblyBuilderFlags.None;                                // todo: 以下动作会导致程序集完成编译后IDE 报错,待确认:减少编译频率,变成 aa build 时编译,同时看能不能将 csproj 回到原点                                builder.referencesOptions = ReferencesOptions.UseEngineModules;                                builder.buildTarget = EditorUserBuildSettings.activeBuildTarget;                                builder.buildTargetGroup = buildTargetGroup;                                builder.excludeReferences = new string[] { assembly.outputPath };                                builder.additionalDefines = assembly.defines;                                builder.compilerOptions = assembly.compilerOptions;                                builder.buildFinished += (arg1, arg2) =>                                {                                    bool noErr = true;                                    foreach (var msg in arg2)                                    {                                        if (msg.type == CompilerMessageType.Error)                                        {                                            Debug.LogError(msg.message);                                            noErr = false;                                        }                                        else if (msg.type == CompilerMessageType.Warning)                                        {                                            Debug.LogWarning(msg.message);                                        }                                        else                                        {                                            Debug.Log(msg.message);                                        }                                    }                                    if (noErr)                                    {                                        FileUtil.ReplaceFile(temp, item.OutputPath);                                        item.UpdateInformation();                                    }                                };                                if (!builder.Build())                                {                                    Debug.LogError($"{nameof(AssemblyHotfixManager)}: Assembly {item.Dll} Build Fail!");                                }                                else                                {                                    Debug.Log($"{nameof(AssemblyHotfixManager)} 热更程序集: <color=yellow>{item.Dll} </color> 完成构建!");                                }                            }                        }                    }                }                else                {                    Debug.LogError($"{nameof(AssemblyHotfixManager)}: 请先完善 Hotfix Configuration 配置项!");                }                EditorUtility.SetDirty(Instance);                AssetDatabase.Refresh();            }        }
    builder.referencesOptions = ReferencesOptions.UseEngineModules; 编译为 Runtime 程序集这个类主要用于将 Assets 文件夹以外的 Assembly 进行编译并放回到 Assets 中使用这个类使用的编译器不同于 PlayerBuildInterface.CompilePlayerScripts ,编译时会修改所有的 .sln 和 .csproj 文件上述代码并不完善,剩余部分在:这里
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-22 11:33 , Processed in 0.134877 second(s), 22 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表