Использовать C++ DLL из одной и той же VS, скомпилированной в разное время / команды - совместимость ABI?

Повторюсь: я ищу совместимость ABI между библиотеками одной и той же версии Visual-C++!

Мы хотим смешивать и сопоставлять некоторые внутренние библиотеки C++ DLL из разных команд - созданные в разное время с разными файлами проекта. Из-за длительного времени сборки мы точно хотим избежать больших монолитных сборок, когда каждая команда перекомпилирует исходный код библиотеки другой команды.

При использовании библиотек DLL C++ с интерфейсами C++ совершенно очевидно, что вы можете сделать это, только если все библиотеки DLL скомпилированы с одинаковой версией компилятора / Visual Studio.

Что мне не совсемпонятно, так это то,что должно быть точно так же, чтобы получить совместимость с ABI.

  • Очевидно, отладка (_DEBUG) и выпустить (NDEBUG) нельзя смешивать - но это также очевидно из того факта, что они ссылаются на разные версии общего времени выполнения.
  • Нужна ли вам точно такая же версия компилятора, или достаточно, чтобы результирующая DLL ссылалась на одну и ту же общую среду выполнения C++ - то есть, в основном, на один и тот же распространяемый? (Я думаю, что static не вылетает при передаче полных объектов C++ вокруг)
  • Есть ли документированный список опций компилятора(и компоновщика), которые должны быть одинаковыми для совместимости двух DLL C++ одной и той же версии vC++?
    • Например, это то же самое/Oнеобходимо переключение - влияет ли уровень оптимизации на совместимость ABI? (Я уверен, что нет.)
    • Или обе версии должны использовать один и тот же/EH переключатель?
    • Или же/volatile:ms|iso...?

По сути, я хотел бы предложить набор (мета) данных для связи с Visual-C++ DLL, который описывает его совместимость с ABI.

Если есть различия, я сосредоточен на VS2015 только на данный момент.

1 ответ

Я думал об этом последние дни, и я попытался выяснить, существуют ли какие-то варианты использования, где разработчикам уже нужно было классифицировать их сборку C++, чтобы убедиться, что двоичные файлы совместимы.

Одним из таких мест являются Native Packages от nuget. Поэтому я посмотрел на один пакет, в частности, на cpprestsdk:

Двоичные файлы в загружаемом пакете разделены следующим образом:

native\v120\windesktop\msvcstl\dyn\rt-dyn\x64\Release\
        ^      ^         ^      ^    ^     
  VS version   |       not sure |    uses cpp-runtime dynamically
               |               lib itself dynamic (as opposed to static)
    or WinXP or WinApp(WinRT?)

Я извлек это из этого примера, потому что я не мог найти другие документы. Я также знаю, что каталог сборки бинарных файлов Boost разделен аналогичным образом.

Итак, чтобы получить список метаданных для определения совместимости ABI, я могу предварительно перечислить следующее:

  • Версия VC (то есть версия используемых библиотек времени выполнения C и CPP)
    • один момент здесь в том, что, например, vc140 в настоящее время должно быть достаточно - учитывая, как CRT связан, все возможные исправления для версионных компонентов CRT должны быть в любом случае совместимы с ABI, поэтому не должно иметь значения, с какой версией была создана данная предварительно скомпилированная библиотека.
  • чистый родной | управляемый (/CLI) | WinRT
  • как потребляется ЭЛТ (статически / динамически)
  • битность / платформа (Win32, x64, ARM и т. д.)
  • Релиз или отладочная версия (т.е. на какую версию CRT мы ссылаемся)
  • плюс: _ITERATOR_DEBUG_LEVEL... если все идут с настройками по умолчанию, хорошо, если проект не делает, он должен объявить так

Кроме того, я предпочитаю следующие пункты:

  • /O не должно иметь значения - мы постоянно смешиваем и сопоставляем двоичные файлы с различными настройками оптимизации - в частности, это работает даже для объектных файлов в одном двоичном файле
  • /volatile - так как это дело кодов, мне трудно представить, как это может сломать ABI
  • /EH - за исключением опции отключения всех исключений, в этом случае вы, очевидно, не можете вызывать ничего, что выдает, я вполне уверен, что это сохранение с точки зрения ABI: здесь возможны подводные камни, но я думаю, что они не могут на самом деле быть классифицированы в ABI Compat. (Может быть, можно сказать, что некоторые сложные цепочки обратных вызовов несовместимы с ABI, не уверен)

Другие:

  • Соглашение о вызовах по умолчанию (/G..): Я думаю, что это сломалось бы во время ссылки, когда искаженные символы экспорта и объявления заголовков не совпадают.
  • /Zc:wchar_t - сломается во время соединения (на самом деле это совместимо с ABI, но символы не будут отображаться.)
  • Включить RTTI (/GR) - не слишком уверен насчет этого - я никогда не работал с этим отключенным.
Другие вопросы по тегам