Visual Studio 2015 во время выполнения или как избавиться от Universal CRT?

Скомпилирована пара DLL с использованием visual studio 2015 и попыталась развернуть на некоторых старых версиях Windows 7/64 бит. Пробовал также угадать, какая dll необходима для приложения для запуска и копирования MSVCP140.DLL и VCRUNTIME140.DLL - но приложение не могло загрузить dll vs2015. Начал анализировать, что не так - и ходун зависимостей показал зависимости от следующих 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

Это было особенно удивительно, поскольку, насколько я понимаю, CRT отвечает за запуск dll/exe, он не предоставляет услуг более высокого уровня.

Хорошо, попытался выяснить, как избавиться от них или, по крайней мере, свести к минимуму.

Найдена одна статья: 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" и даже попытался добавить include directory $(UniversalCRT_IncludePath), а также переопределить некоторые определить, как я пытался угадать, что они работают - ни одна из моих попыток не помогла.

В качестве промежуточного решения я вернулся к использованию Visual studio 2013, где DLL CRT всего две: msvcp120.dll, msvcr120.dll.

Конечно, вы, вероятно, порекомендуете установить время выполнения Visual Studio 2015, но одним из наших требований является поддержка автономного исполняемого файла, который работает без какой-либо установки, поэтому дополнительная установка на данный момент не обсуждается.

Можете ли вы порекомендовать мне что-нибудь еще, чем подождать Visual studio 2017?

Ответ 1

(Обновлено 11.10.2016).

Можно избавиться от универсального ЭЛТ, связав его статически, я позабочусь об этом позже, но позвольте посмотрите, продолжаете ли вы использовать универсальный CRT как таковой.

Согласно статье https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/ - можно запустить приложение, используя универсальные дистрибутивы crt dll из следующей папки: C:\Program Files (x86)\Windows Kits\10\Redist\ucrt

Всего в списке всего 41 файл размером 1,8 МБ. (пример для 64-битной платформы)

Конечно, этого недостаточно, вам понадобятся дополнительные файлы vcruntime140.dll и msvcp140.dll из следующей папки: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\x64\Microsoft.VC140.CRT

Итак, после этого вы отправите полностью 43 дополнительных dll помимо вашего приложения.

Также возможно статически компилировать библиотеку ucrt внутри вашего приложения, после чего вам не понадобится 43 dll - но будет ли статическая ссылка на ссылку после ссылки или нет - зависит от вашего приложения - сколько dll и какие api используются. Как правило, после того, как ucrt подключается к двум различным dll, они не обязательно разделяют одни и те же глобальные группы друг с другом, что может привести к ошибкам.

Вам нужно связать с vcruntime.lib/msvcrt.lib, но этого недостаточно - есть дополнительные _VCRTIMP= и _ACRTIMP= определяет, что необходимо отключить от вытягивания функций из ucrt.

Если вы используете premake5, вы можете настроить свой проект следующим образом:

defines { "_VCRTIMP="}
linkoptions { "/nodefaultlib:vcruntime.lib" }
links { "libvcruntime.lib" }

а затем:

defines { "_ACRTIMP="}
linkoptions { "/nodefaultlib:msvcrt.lib" }
links { "libcmt.lib" }

Определения не документируются Microsoft, поэтому возможно, что они будут изменены в будущем.

Помимо ваших собственных проектов, вам нужно будет перекомпилировать все статические библиотеки, которые используются в ваших проектах.

Как для boost-библиотек - мне удалось скомпилировать boost, используя 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=

При устранении проблем с связыванием - обратите внимание, что нерешенные имена функций __imp* из-за использования ключевого слова dllimport и если вы ссылаетесь на libvcruntime.lib, у вас не должно быть ссылок __imp*.

Ответ 2

Я смог решить это, установив C/C++ > Code Generation > Runtime Library вариант компилятора

  • Для отладки: от /MDd до /MTd
  • Для выпуска: от /MD до /MT

Это удалило все ссылки API-MS-WIN-CRT-* и runtime dll и заставило весь код CRT статически привязан.

Подробная информация о новом VS2015 Universal CRT (динамическом и статическом) приведена здесь: https://msdn.microsoft.com/en-us/library/abx4dbyh.aspx

Ответ 3

Я тоже сражался со статической связью решения с несколькими зависимостями зависимостей между компонентами/библиотекой проектов от различных частей MSVCRT, UCRT и Kernel. Надеюсь, что EXE можно просто скопировать туда, где это было необходимо (это не было продуктом, который бы оправдал полную установку MSI).

После почти отказа от работы я нашел лучшее решение, следуя рекомендациям, скрытым в объявлении Universal C Runtime, в частности:

Мы настоятельно рекомендуем использовать статические ссылки Visual С++ библиотеки, как для производительности, так и для удобства обслуживания

Просто удалите все "специальные" параметры компоновщика, которые вы попробовали, отбрасываете в /MT |/MD (Multi-Threaded CRT DLL Release | Debug) выборку библиотеки времени выполнения, и она работает повсюду, например. более новые рабочие станции Windows 10, серверы R2 R2 R2 и Windows 7). Просто установите/перераспределите MSVCRT (VC_Redist *.exe) и KB2999226 ( UCRT через Центр обновления Windows), как Microsoft говорит нам, потому что, как они также говорят:

Универсальная ЭЛТ является компонентом операционной системы Windows. Это входит в состав Windows 10, начиная с января Технический просмотр, и он доступен для более старых версий операционной системы через Центр обновления Windows.

Таким образом, логически единственная дополнительная зависимость для развертывания наших С++-решений для клиента - это MSVCRT, потому что UCRT уже должен быть на современных/ухоженных машинах. Конечно, это добавляет некоторую неопределенность; вы не можете просто скопировать EXE и запустить на любой машине, хорошо или плохо.

Если вы создадите достойный пакет развертывания, такой как MSI, тогда его просто включить, когда у вас есть такие инструменты, как WIX. Также следует отметить, что с недавнего SDK вы можете включить 40 нечетных DLL локально, но это не соответствует принципу обновления безопасности, поэтому я бы этого не делал.

Это действительно единственный способ сделать это, см. другой пример здесь. В этой статье также говорится, что мы ссылаемся на "mincore_downlevel.lib", который является важным советом, решающим для того, получаете ли вы эти ошибки "api-ms-win *", отсутствующие в DLL. Например:

  • Версия SDK проекта установлена ​​в 10, ссылка на mincore.lib = Работает только на Windows 10, но не на сервере 8.1/2012 R2 или Windows 7/2008 R2.
  • Версия SDK проекта установлена ​​в 8.1, ссылка на mincore.lib = Работает как на сервере Windows 10, так и на 8.1/2012 R2, но не на сервере Windows 7/2008 R2.
  • Версия SDK проекта установлена ​​в 10, ссылка на mincore_downlevel.lib = Выполняется на всех!

Вкратце:

  • Не связывайте статически, оставьте стандартные значения времени выполнения DLL C, выбранные в настройках проекта.
  • Вам не нужны старые SDK, они могут разрабатываться с последними версиями Windows 10 SDK, но вы должны связываться с "mincore_downlevel.lib", а не "mincore.lib", если хотите поддерживать старые версии Windows.
  • Для удобства использования добавьте это в свой targetver.h или stdafx.h, который также документирует ваш выбор (удалите другую строку):
// Libraries
#pragma comment(lib, "mincore.lib")             // Lowest OS support is same as SDK
#pragma comment(lib, "mincore_downlevel.lib")   // Support OS older than SDK

Ответ 4

Я слишком сильно искал поиск DLL времени выполнения, необходимых для запуска приложения, которое было создано в Visual Studio 2015.

Здесь я нашел следующие вещи, которые позволяют запускать VS-2015 приложение.

Примечание. Поместите версии dll в соответствии с архитектурой вашего системного процессора (x86, x64..).