Статическое связывание сторонних библиотек вместе с моим кодом обёртки C ++ - PullRequest
0 голосов
/ 19 сентября 2019

Я работаю над небольшим проектом, чтобы лучше понять цепочку компилятора и компоновщика.

Предположим, у меня есть библиотеки libfoo.a и libbar.a.Я хочу создать библиотеку libmy.a, которая действует как оболочка или API верхнего уровня для обеих библиотек.Цель состоит в том, чтобы для сборки исполняемого файла требовалось только libmy.a, которое использует мои определенные функции-оболочки.Я создал проект cmake и настроил библиотеку

cmake_minimum_required(VERSION 3.14)
project(Wrapper)

set(CMAKE_CXX_STANDARD 11)


add_library(my STATIC ${SOME_SRC_FILES})

#set up the lib/inc paths and libs to link
target_include_directories(my PUBLIC /path/to/Foo/inc/ /path/to/Bar/inc/)
target_link_directories(my PUBLIC /path/to/Foo/lib/ /path/to/Bar/lib)
target_link_libraries(my PUBLIC foo bar)

, которая отлично работает и нет проблем при компиляции.Однако, если я пытаюсь ссылаться на объект из внешнего проекта, он говорит мне, что у меня есть неопределенные ссылки на функции в libfoo.a и libbar.a.Насколько я понимаю проблема, компоновщик создает объявление только в libmy.a, не включая его определение из внешней библиотеки.Я проверил это, открыв libmy.a с помощью команды nm libmy.a, где используемые функции внешних библиотек объявлены, но не определены.

Я столкнулся с одним решением, которое использовало ar для объединения нескольких файлов библиотеки.Однако я хотел бы избежать таких методов, потому что, если это не отдельная библиотека, а группа, скажем, из 10 библиотек, не подходит для поиска в каждой библиотеке определения и копирования его в libmy.a.Простое объединение всех библиотек также не является решением, поскольку файл станет слишком большим.

Важно отметить, что один из этих библиотечных пакетов - CUDA?

Я уверенесть решение, но я не смог его найти.Любая помощь будет оценена

1 Ответ

1 голос
/ 20 сентября 2019

Цель состоит в том, что для сборки исполняемого файла требуется только libmy.a

Это уже нетрадиционная цель для статических библиотек.

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

Инструменты, подобные ar, можно использовать для объединения нескольких статических библиотек.вместе, так как они просто архивы объектного кода.Инструмент не может предсказать, какой объектный код будет использовать конечный пользователь, поэтому он объединит целые библиотеки.В противном случае конечный пользователь может искать определение, которое вы пропустили, и затем ему необходимо в любом случае связать 2-ую копию lib зависимости.

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

Вы можете принудительно заставить весьхотя статические библиотеки должны быть включены в общие библиотеки.
В GCC вы можете использовать аргумент компоновщика: --whole-archive, чтобы обеспечить включение всего объектного кода из следующих библиотек.
В MSVC вы можете использовать/WHOLEARCHIVE:<library file name> аргумент, чтобы сделать то же самое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...