Подтвердить что ты не робот

Связывание файлов DLL Windows из статических библиотек с использованием CMake без ручного создания неразрешенных имен символов

Ситуация

Я использую Visual Studio 2008 SP1 (Professional Edition, как для 32-разрядных, так и для 64-разрядных строит). Я ищу обходной путь к тому, что, как я считаю, очень unhelpful " ограничение" в Visual Studio.

Я нахожу это довольно удивительно, что компоновщик и компилятор Visual Studio не делают это прямо в файле DLL время создания, чтобы автоматически сканировать все указанные статические библиотеки для всех экспортированных символов таким же образом, как указано в Создание Импортировать библиотеку и файл экспорта и в StackOverflow комментарии. Я подтвердил, что недостаточно просто применить __declspec(dllexport) и __declspec(dllimport) атрибуты класса, функции и данных в файлах, которые содержат статические библиотеки.

Компонент не сканирует все статические библиотеки для экспортированных символов и, следовательно, не будет втягивать их в DLL файл (символы должны ссылаться на файлы .obj в командной строке DLL-ссылки или другими способами, которые я покажу ниже). Без явных ссылок на каждый экспортированный символ, DLL файл все еще может быть создан, но связанный с ним файл библиотеки импорта не создается.

Из того, что я могу собрать, Microsoft рекомендует использовать LIB.EXE для создания файла DEF, но, к сожалению, LIB.EXE страница применяет ограничение:

Обратите внимание: если вы создадите свою библиотеку импорта на предварительном этапе, перед созданием .dll необходимо передать один и тот же набор объектных файлов при построении .dll, когда вы проходили при создании импорта библиотека.

Это несчастливое ограничение, учитывая, что я также использую CMake в моя новая среда сборки. CMake скрывает детали того, что на самом деле передан линкеру (и я считаю, что это хорошо в 99% случаев времени), но в этом случае мне нужно получить доступ к некоторой Время выполнения CMake, а не после использования скриптов вручную или другие хрупкие skulduggery.

Вопросы:

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

Мои вопросы:

  • Как получить набор объектных файлов и используемых статических библиотек в последней командной строке DLL-ссылки, используя только синтаксис CMake?

  • Выполняется ли порядок файлов, перечисленных в строке LIB.EXE (тот, который использовался для генерации файла DEF) должны соответствовать точно тому порядку, который используется на линия DLL-ссылки?

  • Существуют ли другие трудности, которые могут возникнуть при использовании LIB.EXE для создания DEF файл?

  • Есть ли лучший способ сделать это, что не требует вызов отдельной утилиты, такой LIB.EXE, до, вызывающий окончательная ссылка? Меня беспокоит добавленная стоимость накладных расходов за пределами связать себя для LIB.EXE для повторного сканирования всех статических библиотек снова, даже если он просто написал их в отдельных исполнениях.

Не ответы:

Ниже перечислены решения, которые я не могу рассмотреть прямо сейчас:

  • Вручную указывая символы без ссылок в любом месте, кроме в исходных файлах .h или .cpp, так как это происходит прерывать каждый раз, когда разработчик забывает обновить файл, который перечисляет (возможно, с именем). И он сломается с неприемлемыми линкерами ошибок относительно неразрешенных символов что будет дорогостоящим для разработчиков для отладки. Этот неответ включает следующие подходы:

    • Явно добавил файлы .obj в командную строку DLL-ссылки, (варианты этого включают добавление "поддельных" .obj файлов, которые фиктивные ссылки на иначе не отображаемые, но экспортированные символов (и обратите внимание, что это то, что моя старая среда сборки сегодня, и он воняет)), и

    • Ручная работа файлы DEF, чтобы включить unreferenced, но экспортированные символы и

    • Параметры командной строки компоновщика, которые конкретно ссылаются на символы без ссылок, но экспортированные символы.

  • Прекратить использование статических библиотек в целом. Я не могу этого сделать в в краткосрочной перспективе, поскольку это слишком большая часть структурных изменений от старого строить среду, от которой я отхожу. Вполне вероятно, что я возьмите этот маршрут в будущем, как только все остатки старой сборки среда находится в "корзине мусора", но это не мое внимание здесь.

Справочный материал:

4b9b3361

Ответ 1

Я только отвечаю, чтобы понять, правильно ли вы не используете статические библиотеки.

DLRdave уже сказал в комментариях, что ваша система сборки подвергается злоупотреблениями с помощью файлов LIB. Файл LIB очень похож на настоящую библиотеку, вы просто уходите с вещами, о которых вы просите, а не в библиотеке.

Если в наборе Visual Studio 2008 есть пробел, он не поддерживает частичную привязку. Ввод в частичную ссылку представляет собой набор OBJ файлов, а выход представляет собой один OBJ файл, содержащий весь код и данные из входных файлов OBJ.

Разница между архивом/библиотекой и частичной ссылкой описана для g++ в ответе на этот вопрос: g++ частичное связывание вместо архивов?, где GNU linker (ld) поддерживает частичное связывание.

Что касается возможного краткосрочного смягчения - лично, я бы попытался использовать скрипты для динамической сборки DEF файла во время сборки с помощью LIB /List или DUMPBIN /ARCHIVEMEMBERS, чтобы получить файлы obj и LIB /DEF для генерации DEF файл из этого списка. Или, как я предполагаю, _declspec(dllexport), вы могли бы также использовать DUMPBIN /DIRECTIVES, искали /EXPORT и сами создавали файл DEF.