c++ - microsoft - ¿Las dependencias de Visual Studio 2015 en tiempo de ejecución o cómo deshacerse de Universal CRT?
visual c++ redistributable 2017 (4)
(Actualizado 11.10.2016).
Es posible deshacerse de CRT universal al vincularlo de forma estática, lo veré más adelante, pero echemos un vistazo si continúas usando CRT universal como tal.
De acuerdo con el artículo https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/ - es posible iniciar su aplicación usando distribuciones universales de dll crt desde la siguiente carpeta: C:/Program Files (x86)/Windows Kits/10/Redist/ucrt
Hay 41 archivos totalmente en la lista con 1,8 Mb de tamaño total. (Ejemplo para plataforma de 64 bits)
Por supuesto, no es suficiente, necesitará además vcruntime140.dll y msvcp140.dll provenientes de la siguiente carpeta: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/redist/x64/Microsoft.VC140.CRT
Entonces, después de eso, enviará un total de 43 DLL adicionales además de su aplicación.
También es posible compilar estáticamente la biblioteca ucrt dentro de su aplicación, después de lo cual no necesitará 43 dll, pero si el enlace estático se vinculará o no, depende de su aplicación, cuántas dll y qué api están en uso. En general, después de que ucrt se vincula en dos archivos DLL diferentes, no necesariamente comparten las mismas variables globales entre sí, lo que puede generar errores.
Debe vincularse con vcruntime.lib / msvcrt.lib, pero no es suficiente, hay _VCRTIMP=
y _ACRTIMP=
que deben desactivarse para que no se puedan extraer funciones de ucrt.
Si está utilizando premake5, puede configurar su proyecto de esta manera:
defines { "_VCRTIMP="}
linkoptions { "/nodefaultlib:vcruntime.lib" }
links { "libvcruntime.lib" }
seguido por:
defines { "_ACRTIMP="}
linkoptions { "/nodefaultlib:msvcrt.lib" }
links { "libcmt.lib" }
Las definiciones no están documentadas por Microsoft, por lo que es posible que esté sujeto a cambios en el futuro.
Además de sus propios proyectos, deberá volver a compilar todas las bibliotecas estáticas que están en uso en sus proyectos.
En cuanto a las bibliotecas de boost, también he conseguido compilar boost, utilizando 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-thread --with-date_time --with-filesystem define=_VCRTIMP= define=_ACRTIMP=
Al solucionar problemas de vinculación, observe que los nombres de las funciones __imp*
no resueltos se __imp*
uso de la palabra clave dllimport
y, si vincula con libvcruntime.lib, no debe tener ninguna referencia __imp*
.
Compilé un par de archivos .dll utilizando Visual Studio 2015 e intenté implementar en algunas ventanas antiguas de 7/64 bits. También intenté adivinar qué archivos dll son necesarios para que la aplicación se inicie y copió MSVCP140.DLL & VCRUNTIME140.DLL, pero la aplicación no pudo cargar el archivo vs2015 dll. Comenzó a analizar lo que está mal, y el caminante de dependencias mostró dependencias de los siguientes archivos DLL:
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
Esto fue especialmente sorprendente, ya que, según mi entender, CRT es responsable de iniciar dll / exe, no proporciona servicios de nivel superior.
Ok, traté de averiguar cómo deshacerse de ellos o al menos minimizarlos.
Encontré un artículo: https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/
Menciona la liberación de bibliotecas estáticas, así que pensé que podría enlazar contra ellas y librarme del infierno de dependencia * L1-1-0.DLL *, pero no importa lo que haya intentado, no tuve éxito. He intentado enlazar contra libvcruntime.lib, libucrt.lib, libcmt.lib, he intentado deshabilitar el uso de la opción de vinculador "/nodefaultlib:vcruntime.lib", e incluso he intentado agregar el directorio de inclusión $ (UniversalCRT_IncludePath), y también anular algunos De definir como he tratado de adivinar que funcionan, ninguno de mis intentos ayudó.
Como solución intermedia, he recurrido a Visual Studio 2013, donde los archivos DLL de CRT son solo dos: msvcp120.dll, msvcr120.dll.
Por supuesto, es probable que recomiende instalar los tiempos de ejecución de Visual Studio 2015, pero uno de nuestros requisitos es que sea compatible con el ejecutable independiente, que funciona sin ninguna instalación, por lo que la instalación adicional está fuera de discusión por ahora.
¿Me puede recomendar algo más que esperar a que Visual Studio 2017 llegue?
Me costó mucho descubrir las DLL de tiempo de ejecución necesarias para ejecutar una aplicación que se creó en Visual Studio 2015.
Aquí encontré las siguientes cosas que permiten ejecutar la aplicación construida VS-2015.
- Descargue el redistribuible desde https://www.microsoft.com/en-us/download/details.aspx?id=52685
- Coloque el archivo msvcp140d.dll, vccorlib140d.dll, vcruntime140d.dll y ucrtbased.dll.
Nota: Coloque las versiones dlls de acuerdo con la arquitectura del procesador de su sistema (x86, x64 ..).
Pude resolver esto configurando la opción del compilador C/C++ > Code Generation > Runtime Library
ejecución
- Para la depuración: de
/MDd
a/MTd
- Para publicación: de
/MD
a/MT
Esto eliminó todas las referencias API-MS-WIN-CRT-*
y dll de tiempo de ejecución y causó que todo el código CRT se vinculara estáticamente.
Los detalles sobre el nuevo CRT universal VS2015 (dinámico y estático) están aquí: https://msdn.microsoft.com/en-us/library/abx4dbyh.aspx
Yo también luchaba por vincular estáticamente una solución con múltiples componentes / dependencias de biblioteca de proyectos que importan funciones de varias partes de MSVCRT, UCRT y Kernel. La esperanza era que el EXE resultante pudiera ser simplemente copiado alrededor de donde se necesitaba (no era un producto que justificara una instalación completa de MSI).
Después de casi rendirme, encontré que la mejor solución era seguir las pautas ocultas en el https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/ , específicamente:
Recomendamos encarecidamente el enlace estático de las bibliotecas de Visual C ++, tanto por razones de rendimiento como de servicio.
Simplemente elimine todas las opciones de vinculador "especiales" que probó, vaya a la opción de biblioteca en tiempo de ejecución / MT | / MD (Multi-Threaded CRT DLL Release | Debug) y funciona en todas partes, por ejemplo, estaciones de trabajo Windows 10 más nuevas, servidores 2012 R2 y Windows 7). Simplemente instale / redistribuya MSVCRT (VC_Redist * .exe) y KB2999226 (UCRT a través de Windows Update) como Microsoft nos dice que hagamos, porque como también dicen:
El CRT universal es un componente del sistema operativo Windows . Se incluye como parte de Windows 10, a partir de la Presentación técnica previa de enero, y está disponible para versiones anteriores del sistema operativo a través de Windows Update.
Por lo tanto, lógicamente, la única dependencia de implementación adicional que nuestras soluciones de C ++ agregan para el cliente es el MSVCRT, porque el UCRT ya debería estar allí en máquinas actualizadas y en buen estado. Por supuesto que añade un poco de incertidumbre; no puedes simplemente copiar el EXE y ejecutarlo en cualquier máquina, buena o mala.
Si produce un paquete de implementación decente como un MSI, es sencillo incluirlo cuando tiene herramientas como WIX. También se debe tener en cuenta que, desde el reciente SDK, puede incluir los 40 DLL de forma local, pero eso no satisface el principio de actualización de seguridad, así que no lo haría.
Esta es realmente la única forma compatible de hacerlo, vea otro ejemplo aquí . Este artículo también sugiere que vinculemos contra "mincore_downlevel.lib", que es un consejo importante, crucial para obtener estos errores DLL que faltan "api-ms-win *". Por ejemplo:
- La versión del SDK del proyecto está establecida en 10, enlace con mincore.lib = Se ejecuta solo en Windows 10, pero no en el servidor 8.1 / 2012 R2 o Windows 7/2008 R2.
- La versión del SDK del proyecto está establecida en 8.1, enlace con mincore.lib = Se ejecuta en los servidores Windows 10 y 8.1 / 2012 R2, pero no en el servidor Windows 7/2008 R2.
- La versión del SDK del proyecto está establecida en 10, enlace con mincore_downlevel.lib = ¡Se ejecuta en todos!
En resumen:
- No vincule estáticamente, deje los tiempos de ejecución predeterminados de DLL C seleccionados en la configuración del proyecto.
- No necesita los SDK anteriores, puede desarrollarlos con el último SDK de Windows 10, pero debe vincular con "mincore_downlevel.lib" no "mincore.lib" si desea admitir versiones anteriores de Windows.
- Para facilitar su uso, agregue esto a su targetver.h o stdafx.h que también documenta su elección (elimine la otra línea):
// Libraries
#pragma comment(lib, "mincore.lib") // Lowest OS support is same as SDK
#pragma comment(lib, "mincore_downlevel.lib") // Support OS older than SDK