VC-LTL 编译精巧的程序原来如此简单

发布于 2021-06-04 23:49:24 字数 11627 浏览 2224 评论 0

1. 关于 VC-LTL

VC-LTL 是一个基于微软 VC 修改的开源运行时,有效减少应用程序体积并摆脱微软运行时DLL,比如msvcr120.dll、api-ms-win-crt-time-l1-1-0.dll等依赖。

VC-LTL 最初是 Dism++ 专用运行时。2017年3月6号从 Dism++ 源代码中分离,并正式对外开源,为社区贡献自己的微薄之力。

在大型项目中往往有众多模块,如果都采用静态编译那么造成的空间浪费先不说,最后也会因为 Fls上限导致程序无法正常运行。

而VC-LTL能让你的项目如同系统文件一样共享系统内置 msvcrt.dll,有效的解决 Fls上限 以及 运行时部署问题,同时 大大缩减程序体积,可以说一箭三雕!

所有人都可以无条件、免费使用,包括用于商业环境。当然如果大家在自己的程序说明文件中声明使用了 VC-LTL 那就更好了。

1.1. 原理

使用 VC-LTL 后可以将程序动态链接到系统自带的 msvcrt.dll 中,来减少程序体积。目前使用 CRT 以及 STL 的工程一般都可以使用。但是 MFC 工程不能使用,因为 MFC 类库太复杂了,尚未适配。

使用VC-LTL,C++ 程序体积大约缩减 30%,而纯 C 程序则大约缩减 50%。

1.2. 亮点

  • 晚起的鸟儿也有虫虫吃,优雅的引用方式,仅添加一个属性表就能享受极致的体积体验。
  • 无缝使用最新 C/C++ 库以及最新编译器,尽情的使用最新规范。神马异常流防护(guard:cf)、静态对象线程安全初始化(threadSafeInit)……统统放马过来吧!!
  • 拥有比微软原版更好的兼容性,即使想兼容 Windows XP RTM 也可以安心的对新编译器说 Yes。
  • 完全的开放代码,广泛的接受用户意见,希望大家能踊跃的 pull requests,为 VC-LTL 添砖加瓦。

让我们一起跟 VS 2008 说拜拜!

2. VC-LTL 兼容性

此表展示了 VC-LTL,C/C++ 库函数覆盖率,通过覆盖情况,可以大致了解 VC-LTL 的完善程度。

模块XP模式Vista模式UCRT模式相关文件
CRT94.716%96.347%100%vcruntime.lib、libvcruntime.lib、msvcrt.lib、msvcmrt.lib、msvcrt_Platform.lib、libucrt.lib、ucrt.lib、libucrt_shared.lib、vc.lib
STL100%100%100%libcpmt.lib、msvcprt.lib
ConcRT100%100%100%libconcrt.lib、concrt.lib
WinRTX100%Xvccorlib.lib(仅支持Windows 8.1以及更高版本)
ATL100%100%100%-
MFCXX100%-
AMPXXX-
OpenMP100%100%100%Visual Studio自身提供,需要带上vcomp140.dll

2.1. 支持的 IDE

  • Visual Studio 2015(包含 Clang with Microsoft CodeGen、Clang 3.7 with Microsoft CodeGen、Clang-LLVM)
  • Visual Studio 2017(包含 Clang with Microsoft CodeGen、Clang-LLVM)
  • Visual Studio 2019(包含 Clang-LLVM)

2.2. 支持的编译工具

编译工具支持文件
Visual StudioVC-LTL helper for Visual Studio.props
CMakeVC-LTL helper for cmake.cmake
NMake、CLVC-LTL helper for nmake.cmd
QMakeVC-LTL helper for qmake.pri

2.3. 支持的操作系统

操作系统x86x64armarm64
Windows XP、Windows Server 2003--
Windows Vista、Windows Server 2008--
Windows 7、Windows Server 2008 R2--
Windows 8、Windows Server 2012、Windows RT-
Windows 8.1、Windows Server 2012 R2、Windows RT 8.1-
Windows 10、Windows Server 2016、Windows Server 2019

采用 VC-LTL 编译后的程序能兼容Windows XP RTM以上所有操作系统,无需安装任何SP补丁包。

3. 使用方法

下面我们将进入主题,我们给大家准备了丰富的 VC-LTL示例 供大家参考,也欢迎加入我们的QQ群(633710173)。

3.1. 在Visual Studio中使用VC-LTL

3.1.1. 引用VC-LTL

3.1.1.1. 通过 NuGet 引用(推荐)

在 项目右键,选择“管理 NuGet 程序包”,然后搜索 VC-LTL 并选择适合您的版本,最后点击安装即可。

3.1.1.2. 通过注册表引用

假如,你将 VC-LTL Binary 下载并解压至 D:\Src\VC-LTL(具体位置无任何要求),双击 D:\Src\VC-LTL\Install.cmd 即可。

脚本会在 HKCU\Code\VC-LTL 创建注册表。

将属性表 VC-LTL helper for Visual Studio.props 复制到你的工程目录,你可以打开属性管理器(视图 - 属性管理器),然后Release配置上右键 添加现有属性表,然后选择 VC-LTL helper for Visual Studio.props即可。

3.1.2. 配置工程属性

C/C++ - 代码生成 -【运行库】调整为【多线程 (/MT)】

如需支持 XP,请右键项目 - 属性 - 初雨团队 VC-LTL - 启用 Windows XP 兼容 -『是』 即可。

3.2. 在 CMake 中使用 VC-LTL

假如,你将 VC-LTL Binary 下载并解压至 D:\Src\VC-LTL(具体位置无任何要求),双击 D:\Src\VC-LTL\Install.cmd 即可。

脚本会在 HKCU\Code\VC-LTL 创建注册表。

3.2.1. 添加VC-LTL配置文件

将模块文件 VC-LTL helper for cmake.cmake 复制到你的工程目录(顶层CMakeLists.txt同级目录)。然后在 CMakeLists.txt 中添加一行 include("VC-LTL helper for cmake.cmake") 即可。

示例:

cmake_minimum_required(VERSION 3.5.2)
project(ltltest)

include("VC-LTL helper for cmake.cmake")

add_subdirectory(src)

3.2.2. 调整配置工程

务必确保使用/MT编译代码。如需支持XP,请修改VC-LTL helper for cmake.cmake启用 set(SupportWinXP "true") 即可。

3.3. 在 NMake / 纯 CL 中使用 VC-LTL

假如,你将 VC-LTL Binary 下载并解压至 D:\Src\VC-LTL(具体位置无任何要求),双击 D:\Src\VC-LTL\Install.cmd 即可。

脚本会在 HKCU\Code\VC-LTL 创建注册表。

3.3.1. 运行 VC-LTL 辅助脚本

将辅助脚本VC-LTL helper for nmake.cmd复制到你的工程目录。启动vcvars32.bat/vcvars64.bat执行此脚本即可,脚本将自动修改include以及lib环境变量。

示例:

call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat"
call "D:\VC-LTL\VC-LTL helper for nmake.cmd"

nmake /f Test.mak

3.3.2. 配置工程属性

务必确保使用/MT编译代码。如需支持XP,请修改VC-LTL helper for nmake.cmd 启用 set SupportWinXP=true

3.4. 重新编译(仅 Release)

现在是不是体积就小了很多。如果你编译不通过,可以先参考 4. 常见问题。如果还是不通过可以反馈,共同改进VC-LTL。

如果正确引用VC-LTL,那么 会在生成时输出:note: 进入ltl普通模式,已准备引用到VC-LTL。定义 _DISABLE_DEPRECATE_LTL_MESSAGE 可关闭信息提示。

使用VC-LTL编译时必须采用 /MT 编译,并且所有依赖的静态库也必须使用 VC-LTL 重新编译。

4. 常见问题

4.1. 未共享到 msvcrt.dll

问题原因

未正确引用VC-LTL。建议看看生成日志,是否包含:note: 进入ltl普通模式,已准备引用到VC-LTL。定义 _DISABLE_DEPRECATE_LTL_MESSAGE 可关闭信息提示。

解决方案

1:请务必确保 VC-LTL helper for Visual Studio.props 已经添加到工程。

2:确保以下设置正确:

  • VC++ 目录 - 包含目录 - 【√ 从父项或项目默认设置继承(I)】
  • VC++ 目录 - 库目录 - 【√ 从父项或项目默认设置继承(I)】

4.2. 无法解析外部符号 delete 等

问题原因

没有正确引入vc.lib、msvcrt_Platform.lib。

解决方案

  • VC++ 目录 - 包含目录 - 【√ 从父项或项目默认设置继承(I)】
  • VC++ 目录 - 库目录 - 【√ 从父项或项目默认设置继承(I)】

4.3. 检测到RuntimeLibrary的不匹配项

问题原因

引入了没有使用VC-LTL编译的静态lib文件。

解决方案

使用VC-LTL重新编译对应的静态lib(具体lib名称错误日志会给出)。

5. 已知问题

  • 由于WinXP本身Bug,printf相关函数输入缓冲区最大字符数为0x3FFFFFFF(包含)。当你需要兼容XP时,请务必确认缓冲区输入长度小于0x3FFFFFFF,或者直接使用 _CRT_STDIO_SIZE_MAX 宏。(4.0.2.5 Advanced模式已经修正此问题)。
  • 由于WinXP本身Bug,printf相关函数无法正常支持%ll。当你需要兼容XP时,请优先考虑使用%I64代替。(4.0.2.5 Advanced模式已经修正此问题)。
  • 由于msvcrt本身限制,setlocale/_create_locale相关函数不支持UCRT的locale name,使用时必须按VC 2008规范使用,比如 setlocale(0, "chs"); 这样调用,而不是传入 setlocale(0, "zh-CN");

附:已知使用VC-LTL的官方项目

项目备注
NSudo一个强大的系统管理工具。VC-LTL的帮助下减少30%的程序体积,包括NSudo for arm64。
Menu98经典样式可自定义的开始按钮右键菜单。使用VC-LTL移除运行时依赖。
壁虎浏览器一款专业解决DNS劫持的浏览器。使用VC-LTL有效减少程序体积,减少安装包大小。
librech551开源跨平台的CH55x ISP软件。使用VC-LTL移除运行时依赖。
Dism++Dism GUI版。初雨团队自身项目,使用VC-LTL有效减少程序体积,减少安装包大小。
360安全卫士奇虎360推出的上网安全软件。360EvtMgr.exe、360leakfixer.exe、360Util.dll、leakrepair.dll等文件使用VC-LTL编译,在VC-LTL的支持下:升级新编译器,减少文件尺寸,完美兼容WinXP,一箭三雕。

附:第三方依赖项许可

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

已经忘了多久

文章 0 评论 0

15867725375

文章 0 评论 0

LonelySnow

文章 0 评论 0

走过海棠暮

文章 0 评论 0

轻许诺言

文章 0 评论 0

信馬由缰

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文