dotnet publish 🔗
dotnet publish
- Publishes the application and its dependencies to a folder for deployment to a hosting system.
试验了一下打包应用,放到别的 Linux 机器(没有.Net 运行时)上跑。
自包含应用 🔗
$ dotnet publish -h
...
-f, --framework <FRAMEWORK> The target framework to publish for.
-r, --runtime <RUNTIME_IDENTIFIER> The target runtime to publish for.
...
--self-contained Publish the .NET runtime with your application so the runtime
does not need to be installed on the target machine.
The default is 'true' if a runtime identifier is specified.
$ dotnet publish -r linux-x64 -f net5.0 -o ./linux-publish
$ du -sh linux-publish/
76M linux-publish/
$ ls -1 linux-publish/*.dll | wc -l
193
看了一下 dotnet publish -h
的输出,有一个 --self-contained
选项,
可以用来打包自包含应用,且 -r
指定了目标运行时的话就隐含了自包含。打包的结果是个文件夹,包含了应用本身以及依赖的库。
自包含单体应用 🔗
显然,这没有 go build
生成出来一个单体应用方便。网上搜了一下,有个额外参数 -p:PublishSingleFile=true
.
$ dotnet publish -r linux-x64 -f net5.0 -p:PublishSingleFile=true -o ./linux-publish
$ du -sh linux-publish/
64M linux-publish/
$ ls linux-publish/
MyApp MyApp.pdb
$ file linux-publish/MyApp
linux-publish/MyApp: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV),
dynamically linked, interpreter/lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32,
BuildID[sha1]=42c923debe410c089a93997a66ef968f8574a077, stripped, too many notes (256)
是个已经去掉符号表的可执行程序,虽然 64MB 比之前 76MB 小一点,但还是偏大。
upx-ucl 🔗
拿 upx-ucl
压缩一下?
$ upx-ucl MyApp
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2018
UPX 3.95 Markus Oberhumer, Laszlo Molnar & John Reiser Aug 26th 2018
File size Ratio Format Name
-------------------- ------ ----------- -----------
66467643 -> 27944636 42.04% linux/amd64 MyApp
Packed 1 file.
$ du -h MyApp
27M MyApp
64 MB 压缩到 27 MB,很可观。
./MyApp
Failure processing application bundle; possible file corruption.
Arithmetic overflow while reading bundle.
A fatal error occured while processing application bundle
又有什么用?
自包含单体应用 - 瘦身 🔗
去官网查看PublishSingleFile
的文档,查到了两个信息:
-p:PublishSingleFile=true 🔗
Packages the app into a platform-specific single-file executable. The executable is self-extracting and contains all dependencies (including native) that are required to run the app. When the app is first run, the application is extracted to a directory based on the app name and build identifier. Startup is faster when the application is run again. The application doesn’t need to extract itself a second time unless a new version is used. Available since .NET Core 3.0 SDK.
For more information about single-file publishing, see thesingle-file bundler design document.
We recommend that you specify this option in a publish profile rather than on the command line. For more information, see MSBuild.
-p:PublishTrimmed=true 🔗
Trims unused libraries to reduce the deployment size of an app when publishing a self-contained executable. For more information, seeTrim self-contained deployments and executables. Available since .NET Core 3.0 SDK as a preview feature.
We recommend that you specify this option in a publish profile rather than on the command line. For more information, see MSBuild.
首先,single-file executable 其实是个打包了依赖的自解压程序;另外其实有 PublishTrimmed
来做这个瘦身工作。
$ dotnet publish -r linux-x64 -f net5.0 -p:PublishSingleFile=true \
-p:PublishTrimmed=true -o ./linux-publish
$ du -sh linux-publish/
34M linux-publish/
64 MB 瘦身到 34 MB,但明显运行耗时长很多。Single-file publish
的设计文档
里提到:bundler 里面其实打包了 PEImage Loader. 因此,Linux下这个单体程序其实是个披着 ELF 外壳的 PE 程序。