[成功]又一次自己编译Mono,这次是在Windows上,玩Bundle

作者:V君 发布于:2017-10-30 21:07 Monday 分类:折腾手记

目标 -- 将 .net 应用程序用只用一个 exe 承载, 并极大缩减体积, 且能保证工作正常.


(这次不是针对性的解决问题, 不TL;DR (´∀((☆ミつ 


■前言

 

虽然早早就知道 Mono 可以自行编译独立运行, 就像 unity3d 之类的玩法, 

也了解过 bundle 工具可以打包程序集进 exe 内, 还知道 Mono 有个 linker 

可以像静态库一样链接 IL 捡出只需要的部分, 缩减程序集体积

(尽管不会推断动态调用--挂掉 -_- ,彻底检查然后设定排除规则即可)

 

不过却没有尝试把他们串起来用: 先把 IL link 一下, 首次缩减体积

然后 bundle 把依赖的程序集打包到exe里 -- 出来的东西是原生的哟!

意味着可以加压缩壳, upx -9 要不要太爽, 进一步缩小最终 exe 的体积,

-- 真·一个 EXE 带走你全家...  (´∀((☆ミつ

 

■动手尝试


先从安装版开始 mkbundle -- 各种失败...过程略过吧, 不愿再想起.

要不要再试试自己编译? 


■自己编译


还是回到 Mono 官方 GitHub 上看看, 发现这回 windows 的 build 变成 pass 了!

再次按照官网教程, 抓回源代码, configure && make,然后没有预期的那么顺利 -- 报错了

error while loading shared libraries: ?: cannot open shared object file: No such file or directory

找不到 DLL ? 你显示个问号啥意思?

咕狗一阵,爆栈上面说用 ldd 和 cygcheck 做依赖检查, 然并暖, 没查出问题

但是跑起来就挂掉, 估计是真·动态加载扑空, 继续咕狗也没有结果...

机智的我拿出诊断大杀器 procmon 可以抓到访问失败的操作, 于是盯着看了.

果不其然, 发现文件名 libgcc_s_seh-1.dll 在环境变量 PATH 里的目录溜了一圈都没找到

先是线程退出, 然后进程退出了. everything 发现这货藏在这里:

cygwin64\usr\x86_64-w64-mingw32\sys-root\mingw\bin

把它加到环境变量就能顺利通过编译~


接下来是在 VS 编译运行时,对应官网教程的x64操作

VS需要安装C++功能以及CLANG2,否则无法编译或执行 mkbundle 出现 ClangC2Version 丢失.

这次总算顺利通过编译.

 

■开始玩吧!


让我们来找到 mkbundle, 它在源码目录下的 /mcs/class/lib/net_4_x-win32/


启动之前需要设置环境变量,

LINK指定静态库路径

export LINK="/LIBPATH:Mono源码目录/msvc/build/sgen/x64/lib/Release"

然后进入源码目录, 打死我也不信它原来没提供参数设置 include 路径

那就粗暴的用当前路径碾过吧, 进入最终执行~


mkbundle 

  --deps z:/LoopPlay.exe -o z:/lp.exe

  --static -L Mono源码目录/mcs/class/lib/net_4_x-win32 


刷一会儿屏之后, exe 就出来辣! 尽管很大块头, 我的有 21MB 但是可以 link 再 upx 嘛.


作成脚本来初始化环境变量就可以了, 本例的文件夹是 mono-src-git, 那么可以写成:

set PATH=%~dp0mono-src-git\mcs\class\lib\net_4_x-win32;%PATH%

set LINK=/LIBPATH:%~dp0mono-src-git/msvc/build/sgen/x64/lib/Release

set I18N=%~dp0mono-src-git\mcs\class\lib\net_4_x-win32

cd /d %~dp0mono-src-git

@cmd

双击之后就可以在弹出的命令行打以下简短的命令来执行:

mkbundle -v --static -L %I18N% --deps z:\cil.exe -o z:\bun.exe

 

时间关系就先写到这里, 抽空再更新link和压缩壳.  (´∀((☆ミつ

更新: x86 以及 IL link 和 upx. 

按照官网教程把配置参数改成 x86 之后发现问题少了很多. 比如头文件,比如运行时错误.

IL link 可以工具在 %I18N% 目录找到, 用法有点繁琐.

并且不加排除参数直接link的话, 八成会让程序挂掉或者运行不正常. 用法是:

monolinker.exe -c link -d Z:\ -out z:\linked -a Z:\cli.exe

每个参数都是绝对路径 好烦 看来真不是直接用的玩意儿, 得做个界面来调用吧.

-c 的参数还可以是 copy, 出来的文件大一些, 起码能正常跑.

将 link 过的程序集打包成一个 exe 然后直接喂给 upx 

加上 -9 最高压缩, 后面跟上exe的绝对路径. 一般能压缩到 30% 左右.

嗯嗯 讲完了. (´∀((☆ミつ


标签: 软件开发 C# 命令行 mono 软件故障诊断

引用地址:

发表评论:

Powered by emlog 去你妹的备案 sitemap