ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

unity2017自定义编译dll

2021-09-10 10:01:30  阅读:262  来源: 互联网

标签:Assembly 自定义 mono dll 编译 unity2017 CSharp mcs


适用于自定义编译平台和编译符合,把C#源码文件编译成dll。(用于InjectFix之类的热更方案)
适用于unity2017环境,代码暂时不方便贴出记述一下思路。

参考:Unity官方C#源码 https://github.com/Unity-Technologies/UnityCsReference

1. 通过反射取用一些访问不到的Editor代码

  • GetCompilationDefines(EditorScriptCompilationOptions, BuildTargetGroup, BuildTarget)
  • GetUnityAssmblies(bool, BuildTargetGroup, BuildTarget)
  • GetPrecompiledAssemblies(bool, BuildTargetGroup, BuildTarget)
  • CompatibilityProfileToClassLibFolder(ApiCompatibilityLevel)

直接复制源码过来改动

  • struct PrecompiledAssembly
  • enum EditorScriptCompilationOptions
  • class MonoInstallationFinder

2. Unity编译dll的原理

  • 先生成一个编译参数的清单文件,包括编译符号定义、源代码文件、库引用等,可以在项目目录下的Temp/UnityTempFile-XXXXX查看。
  • 之后会通过类似mono.exe mcs.exe @Temp/UnityTempFile-XXX的命令来启动编译器进行编译

已经很明显了,要实现自定义编译dll,主要解决两个问题:

  • 怎么找到mono和mcs的路径
  • 怎么生成清单文件

3. 找到mono和mcs的路径

MonoInstallationFinder.cs中直接增加函数

public static string GetMonoProfileLibDirectory(BuildTarget group)
{
    ApiCompatibilityLevel compatibilityLevel = PlayerSettings.GetApiCompatibilityLevel(group);
    string profile;
    string monoInstall;

    // 因为生产环境配置比较固定, 写的比较糙
    // 具体可查阅"mono"和"MonoBleedingEdge"文件夹的区别(旧版本|新版本)
    if (compatibilityLevel == ApiCompatibilityLevel.NET_2_0)
    {
        profile = "2.0-api";
        monoInstall = MonoBleedingEdgeInstallation;
    }
    else
    {
        profile = "unity"; // .net-2.0-subset
        monoInstall = MonoInstallation;
    }
}

4. 生成清单文件

unity2017对自定义dll名称有一定支持,但不是太好,还是使用默认的"Assembly-CSharp"这些,参考官方说明 https://docs.unity3d.com/2017.4/Documentation/Manual/ScriptCompileOrderFolders.html

写一个枚举方便使用


enum UnityDllNames
{
    Assembly_CSharp_firstpass,
    Assembly_CSharp,
    Assembly_CSharp_Editor_firstpass,
    Assembly_CSharp_Editor,
}

可以写出根据文件路径判断所属dll的函数UnityDllNames GetDllType(string path), 根据这四个dll的依赖关系,可以写出判断dll是否需要引用的参数bool NeedDllRef(UnityDllNames dll, UnityDllNames refDll),源代码文件很容易就可以列出来了

项目内的dll文件,结合路径和PluginImporter的值来判断是否引用;比较难处理的是Unity自己提供的引用

  • 通过最开始提到的GetUnityAssemblies()GetPrecompiledAssemblies()可以获取部分,非编辑器构建下需要额外排除名字带有"Editor"的引用
  • 还有一些额外的固定引用,通过GetMonoProfileLibDirectory()获取路径拼接,System.Runtime.Serialization.dll,System.Xml.Linq.dll,UnityScript.dll,UnityScript.Lang.dll,Boo.Lang.dll
  • 可能还有一些遗漏或不一致的。如果不是直接在实际游戏中用到这个编译出来的dll,不需要做到和Unity生成的完全一致

通过GetCompilationDefines()获取编译符号定义

存在mcs.rsp的加一下

5. 执行编译

生成清单文件后,找到对应的mono、mcs路径,拼接执行即可,一般是MonoBleedingEdge/bin/mono.exeMonoBleedingEdge/lib/mono/4.5/mcs.exe

标签:Assembly,自定义,mono,dll,编译,unity2017,CSharp,mcs
来源: https://www.cnblogs.com/lunoctis/p/15250109.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有