Visual Studio 2015 运行时依赖项或如何摆脱 Universal CRT?
使用 Visual Studio 2015 编译了几个 .dll,并尝试在一些较旧的 Windows 7/64 位上进行部署.还试图猜测应用程序启动和复制 MSVCP140.DLL & 需要哪些 dll.VCRUNTIME140.DLL - 但应用程序无法加载 vs2015 dll.开始分析出了什么问题 - 依赖遍历器显示了来自以下 dll 的依赖:
Compiled couple of .dll's using visual studio 2015, and tried to deploy on some older windows 7 / 64 bit. Tried also to guess which dll's are needed for application to start and copied MSVCP140.DLL & VCRUNTIME140.DLL - but application could not load vs2015 dll. Started to analyze what is wrong - and dependency walker showed dependencies from following dll's:
API-MS-WIN-CRT-MATH-L1-1-0.DLL
API-MS-WIN-CRT-HEAP-L1-1-0.DLL
API-MS-WIN-CRT-CONVERT-L1-1-0.DLL
API-MS-WIN-CRT-STRING-L1-1-0.DLL
API-MS-WIN-CRT-STDIO-L1-1-0.DLL
API-MS-WIN-CRT-RUNTIME-L1-1-0.DLL
API-MS-WIN-CRT-FILESYSTEM-L1-1-0.DLL
API-MS-WIN-CRT-TIME-L1-1-0.DLL
这特别令人惊讶,因为据我所知,CRT 负责启动 dll/exe,它不提供任何更高级别的服务.
This was especially surprising since to my best understanding CRT is responsible for starting dll/exe, it does not provide any higher level services.
好的,我想弄清楚如何摆脱它们或至少最小化它们.
Ok, tried to figure out how to get rid of them or at least to minimize.
找到一篇文章:https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/
它提到了发布静态库 - 所以我认为我可以链接它们并摆脱 *L1-1-0.DLL* 依赖地狱,但无论我尝试过什么 - 我都没有成功.我尝试链接 libvcruntime.lib、libucrt.lib、libcmt.lib,尝试禁用使用链接器选项/nodefaultlib:vcruntime.lib",甚至尝试添加包含目录 $(UniversalCRT_IncludePath),并且还覆盖了一些定义的,因为我试图猜测它们有效 - 我的尝试都没有帮助.
It mentions about release static libraries - so I thought that I could link against them and get rid from *L1-1-0.DLL* dependency hell, but no matter what I have tried - I had no success. I've tried to link against libvcruntime.lib, libucrt.lib, libcmt.lib, tried to disable using linker option "/nodefaultlib:vcruntime.lib", and even tried to add include directory $(UniversalCRT_IncludePath), and also overriding some of define's as I have tried to guess they works - none of my attempts helped.
作为中间解决方案,我已经回退到使用 Visual Studio 2013,其中 CRT dll 只有两个:msvcp120.dll、msvcr120.dll.
As an intermediate solution I've fall back to using Visual studio 2013, where CRT dll's are only two: msvcp120.dll, msvcr120.dll.
当然,您可能会建议安装 Visual Studio 2015 运行时,但我们的要求之一是支持独立的可执行文件 - 无需任何安装即可运行 - 所以现在额外安装是不可能的.
Of course you will probably recommend to install Visual studio 2015 run-times, but one of our requirement is to support standalone executable - which works without any installation - so additional installation is out of question for now.
除了等待 Visual Studio 2017 到来之外,您还能向我推荐什么吗?
Can you recommend me anything else than to wait Visual studio 2017 to arrive ?
推荐答案
(11.10.2016 更新).
(Updated 11.10.2016).
可以通过静态链接来摆脱通用 CRT,我稍后会讲到,但让我们继续看看你是否继续使用通用 CRT.
It's possible to get rid of universal CRT by linking it statically, I'll get to it later on, but let's take a look if you continue to use universal CRT as such.
根据文章 https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/ -可以使用以下文件夹中的通用 crt dll 可分发文件启动您的应用程序:C:Program Files (x86)Windows Kits10Redistucrt
According to article https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/ -
it's possible to launch your application using universal crt dll distributables from following folder:
C:Program Files (x86)Windows Kits10Redistucrt
列表中共有 41 个文件,总共 1.8 Mb 大小.(以 64 位平台为例)
There are 41 files totally in list with 1.8 Mb size in total. (example for 64-bit platform)
当然还不够,还需要额外的vcruntime140.dll &msvcp140.dll 来自以下文件夹:C:Program Files (x86)Microsoft Visual Studio 14.0VCedistx64Microsoft.VC140.CRT
Of course it's not enough, you will need additionally vcruntime140.dll & msvcp140.dll coming from following folder:
C:Program Files (x86)Microsoft Visual Studio 14.0VCedistx64Microsoft.VC140.CRT
所以在那之后,除了您的应用程序之外,您还将总共发送 43 个额外的 dll.
So after that you will ship totally 43 additional dll's besides your application.
也可以在您的应用程序中静态编译 ucrt 库,之后您将不需要 43 个 dll -但是静态链接是否会在链接后使用 - 取决于您的应用程序 - 使用了多少个 dll 和哪些 api.通常,在 ucrt 链接到两个不同的 dll 之后,它们不一定会彼此共享相同的全局变量 - 这可能会导致错误.
It's also possible to statically compile ucrt library inside your application after which you will not need 43 dll's - but whether static link will for after linking or not - depends on your application - how many dll's and which api's are in use. Generally after ucrt gets linked into two different dll's they don't necessarily share same globals with each other - which can results in errors.
您需要链接 vcruntime.lib/msvcrt.lib,但这还不够 - 还有额外的 _VCRTIMP=
和 _ACRTIMP=
定义哪些需要从 ucrt 拉取函数中禁用.
You need to link against vcruntime.lib / msvcrt.lib, but it's not sufficient - there are extra _VCRTIMP=
and _ACRTIMP=
defines which needs to be disabled from pulling functions from ucrt.
如果您使用的是 premake5,您可以像这样配置您的项目:
If you're using premake5 you can configure your project like this:
defines { "_VCRTIMP="}
linkoptions { "/nodefaultlib:vcruntime.lib" }
links { "libvcruntime.lib" }
紧随其后:
defines { "_ACRTIMP="}
linkoptions { "/nodefaultlib:msvcrt.lib" }
links { "libcmt.lib" }
Microsoft 未记录定义 - 因此将来可能会更改.
Defines are not documented by Microsoft - so it's possible that it's subject to change in future.
除了您自己的项目之外,您还需要重新编译您项目中使用的所有静态库.
Besides your own projects, you will need to re-compile all static libraries which are in use in your projects.
至于 boost 库 - 我也设法使用 b2.exe boostrapper 编译了 boost
As for boost libraries - I've managed to compile boost as well, using b2.exe boostrapper
boost>call b2 threading=multi toolset=msvc-14.0 address-model=64 --stagedir=release_64bit --build-dir=intermediate_64but release link=static,shared --with-atomic --with-线程 --with-date_time --with-filesystemdefine=_VCRTIMP=define=_ACRTIMP=
在对链接问题进行故障排除时 - 请注意由于 dllimport
关键字的使用而导致未解析的 __imp*
函数名称 -如果您链接到 libvcruntime.lib,则不应有任何 __imp*
引用.
When troubleshooting linking problems - notice that unresolved __imp*
function names from because of dllimport
keyword usage -
and if you link against libvcruntime.lib, you should not have any __imp*
references.
相关文章