• Возможно ли перенести "внешний" интерфейс одной библиотеки в другую через статическую связку?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Судя по описанию вопроса, проблема в том, что между кодом основного модуля сборки и кодом статической библиотеки, от которой зависит основной код, нет прямой функциональной связи.

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

    Все дело в том, что полная компоновка (linkage) кода производится только для базового модуля сборки, т.е. для самого плагина. Все статические библиотеки, от которых зависит твой базовый модуль, проходят сортировку по зависимостям и компонуются со строгой фильтрацией.
    Это значит, что если уже скомпонованный код не ссылается на какую-то функцию из статической библиотеки, эта функция не будет скомпонована. Сортировка библиотек по зависимостям требуется для того, чтобы как раз позволить за один проход по очереди библиотек скомпоновать весь необходимый код.

    Есть несколько способов обойти правило компоновки библиотек.
    Первый и самый простой: вынудить компоновщик обработать всю библиотеку целиком. Это делается через представление библиотеки как Whole Archive[?].
    Однако, в этом случае вся статическая библиотека будет скомпонована в исполняемый код. Это не всегда бывает удобно. Особенно если в библиотеке находится много отладочного кода.

    Второй вариант - это использовать __attribute__((used))[?] или [[gnu::used]] на новый лад.
    В коде для Visual C++ можно использовать #pragma comment(linker: "/include:")[?].
    Данные конструкции помечают функцию как важную для компоновки, в результате чего функция всегда будет компоноваться из статической библиотеки в бинарный код.

    Вариант третий - это использовать опцию -u[?] компоновщика.
    Для Visual C++ такой опцией будет /INCLUDE[?].
    Указание важных функций для принудительной компоновки прямо в сценарии сборки является наиболее прозрачным и удобным методом с точки зрения дальнейшей поддержки кода.
    Ответ написан
    2 комментария