Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
12 / 12 / 0
Регистрация: 29.09.2010
Сообщений: 66

Линковка одной статической библиотеки из другой

18.10.2024, 16:37. Показов 10296. Ответов 10
Метки .lib (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день.
Работаю над проектом, стоит задача оформить его в виде статической библиотеки. Проект также использует сторонние статические библиотеки. Проект компилируется в скажем goal.lib, при этом использует библиотеки A.lib и B.lib.
Одно из требований заказчика, это оформление всего в один файл, т.е. чтобы для компиляции приложения с функционалом goal.lib требовалась только она. Почитал интернет, добавил A и B в дополнительные зависимости библиотекаря, установил флаг компоновки библиотеки из зависимостей и после компиляции goal.lib, судя по ее размеру, она и правда включает в себя код из A.lib и B.lib.
Проблема заключается в том, что при попытке скомпилировать приложение с добавлением goal.lib (тестовое, просто вызывает метод из goal.lib), линковщик все равно требует файлы A.lib и B.lib. Если их показать проекту приложения(скинуть файлы в доступную папку), то все работает нормально. Как указать линковщику, что код A.lib и B.lib следует искать внутри goal.lib?

Все библиотеки точно статические, а не импорта.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.10.2024, 16:37
Ответы с готовыми решениями:

CMake. Линковка статической библиотеки
Всем привет. Попал в какую-то глупую ситуацию... На пальцах. Есть либа для примера с одной функцией hello, выводящей текст ...

Линковка статической либы не прекращается
Всем привет. У меня есть прокт на cmake. Состоит из исполняемого файла и нескольких статических либ. Файла самого исполняемого...

Линковка со статической библиотекой gsl
Всем привет! Скомпилировал в статическом и динамическом вариантах библиотеки gsl: libgsl, libgslcblas. Динамическая нормально...

10
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13177 / 6813 / 1821
Регистрация: 18.10.2014
Сообщений: 17,238
18.10.2024, 21:00
Цитата Сообщение от Itisme Посмотреть сообщение
Почитал интернет, добавил A и B в дополнительные зависимости библиотекаря, установил флаг компоновки библиотеки из зависимостей и после компиляции goal.lib, судя по ее размеру, она и правда включает в себя код из A.lib и B.lib.
Нет. Так не бывает.

Интересно, где вы вычитали в интернете, что это можно сделать установкой какого-то флага. Что за флаг?

Цитата Сообщение от Itisme Посмотреть сообщение
Проблема заключается в том, что при попытке скомпилировать приложение с добавлением goal.lib (тестовое, просто вызывает метод из goal.lib), линковщик все равно требует файлы A.lib и B.lib.
Как и должно быть.

Цитата Сообщение от Itisme Посмотреть сообщение
Как указать линковщику, что код A.lib и B.lib следует искать внутри goal.lib?
Никак. Никакого "кода A.lib и B.lib внутри goal.lib" не существует.

Если вы хотите физически засунуть содержимое A.lib и B.lib внутрь goal.lib, вам придется это делать вручную средствами библиотекаря lib.exe.
0
12 / 12 / 0
Регистрация: 29.09.2010
Сообщений: 66
19.10.2024, 23:31  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Интересно, где вы вычитали в интернете, что это можно сделать установкой какого-то флага. Что за флаг?
На stackoverflow наткнулся на следующее предложение:
"When creating a library, you can specify "Additional dependencies" in the "Librarian" properties of the project. The dependency may be another library. Also set "Link Library Dependencies" to "Yes" so that the whole library is included."

Кода для goal.lib я написал не то что бы много, а вот в сторонних библиотеках его хватает. Они размером в десятки Мб и там как бы понятно почему. Сам goal.lib после компиляции получается по размеру чуть больше, чем суммарно те сторонние библиотеки, что и навело меня на мысль, что они должны быть где-то там внутри.

Библиотекарем я тоже пытался пользоваться, но он выдает ошибку, что библиотеки скомпилированы под разные целевые машины, поэтому он не может их объединить, что странно, т.к. я все под x64 компилил(и сторонние библиотеки из исходников тоже), да и они же как-то совместно работают в итоге.
Хотя, сторонние библиотеки компилились всем скопом через Cmake и, хоть я флаги компиляции вроде как нужные выставил, для меня это какое-то сложное колдунство, мог и накосячить где. Можно ли как-то проверить под что в итоге получились библиотеки?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13177 / 6813 / 1821
Регистрация: 18.10.2014
Сообщений: 17,238
19.10.2024, 23:57
Цитата Сообщение от Itisme Посмотреть сообщение
На stackoverflow наткнулся на следующее предложение:
"When creating a library, you can specify "Additional dependencies" in the "Librarian" properties of the project. The dependency may be another library. Also set "Link Library Dependencies" to "Yes" so that the whole library is included."
На stackoverflow есть целое исследование на это ему и сводится оно к тому, что установка "Link Library Dependencies" to "Yes" приведет лишь к тому, что при добавлении новых references к проекту в свойствах этих references свойство "Link Library Dependencies" будет сразу выставляться в "True". Последнее означает, что линкер будет автоматически подхватывать не только эту библиотеку, но и ее зависимости. "Подхватывать" означает !"просто ссылаться". Это никак не означает, что зависимости будут физически засасываться в библиотеку и архивироваться внутрь нее. Такой возможности в настройках нет вообще.

То есть проектная настройка "Link Library Dependencies" - это не более чем инициализационное значение для свойства "Link Library Dependencies" при добавлении новых references.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13177 / 6813 / 1821
Регистрация: 18.10.2014
Сообщений: 17,238
20.10.2024, 19:15
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
То есть проектная настройка "Link Library Dependencies" - это не более чем инициализационное значение для свойства "Link Library Dependencies" при добавлении новых references.
... по этой причине изменение настройки "Link Library Dependencies" в настройках проекта не меняет вообще ничего в текущем состоянии проекта. Собственно, "исследование" на stackoverflow и посвящено этой теме: "что это за странная настройка такая, которая ни на что не влияет?"

Чтобы поменять настоящие настройки "Link Library Dependencies" вам нужно вручную лезть в properties каждого reference и менять там. Но, еще раз, в любом случае, эти настройки не делают то, что вы хотели получить.
0
12 / 12 / 0
Регистрация: 29.09.2010
Сообщений: 66
21.10.2024, 11:23  [ТС]
Спасибо TheCalligrapher, хоть вы были и не совсем правы, но натолкнули меня на определенные мысли.

Проблему решил, вдруг кому пригодится.
Сначала собираем все сторонние библиотеки в кучу с помощью библиотекаря:
(Visual Studio)
Средства -> Командная строка
в ней выполняем команду "lib /out:*желаемый путь до файла*\С.lib *путь до файла*\A.lib *путь до файла*\B.lib [можно добавить еще сколько нужно файлов библиотек]

Получаем вместо библиотек A.lib и B.lib одну библиотеку C.lib (У меня было больше сторонних на самом деле, но все собрались в один файл). При компиляции goal.lib добавляем в зависимости только С.lib, в инклудах сторонних библиотек правим в соответствующих местах обращения к A.lib/B.lib на С.lib. Компилим goal.lib.

При компиляции exe-приложения нужен только хедер нового в goal.lib кода(заголовки добавленных вами классов/методов) и goal.lib в зависимостях, но с небольшим нюансом. Линковщик из-за кода сторонних библиотек будет требовать С.lib (без предыдущего шага он бы требовал файлы всех сторонних библиотек), но его можно обмануть, переименовав предварительно goal.lib в С.lib и добавив ее в зависимости в таком виде. В итоге все скомпилилось и заработало.

Т.е. goal.lib таки включает в себя весь необходимый код, линковщик просто пытается его найти в указанных в инклудах сторонних библиотек местах(исходные A.lib/B.lib). Поэтому мы заставляем его искать весь код только в одном файле, сливая сторонние библиотеки вместе (C.lib), а затем подменяем файл со слитыми библиотеками своим файлом, который содержит и код библиотек и собственный добавленный функционал.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13177 / 6813 / 1821
Регистрация: 18.10.2014
Сообщений: 17,238
21.10.2024, 16:32
Цитата Сообщение от Itisme Посмотреть сообщение
хоть вы были и не совсем правы
Не смог разглядеть, где я был не прав.

Цитата Сообщение от Itisme Посмотреть сообщение
в ней выполняем команду "lib /out:*желаемый путь до файла*\С.lib *путь до файла*\A.lib *путь до файла*\B.lib [можно добавить еще сколько нужно файлов библиотек]
У вас в исходной постановке задачи вроде бы было сказано, что вы хотите поместить все внутрь goal.lib. А на этом шаге вы пока что лишь собираете все сторонние библиотеки в одну C.lib. Ну да ладно, будем читать дальше...

Цитата Сообщение от Itisme Посмотреть сообщение
При компиляции goal.lib добавляем в зависимости только С.lib, в инклудах сторонних библиотек правим в соответствующих местах обращения к A.lib/B.lib на С.lib. Компилим goal.lib.
Замечание о "в инклудах сторонних библиотек правим" видимо относится к странной редкой практике указывать в заголовочных файлах их библиотеки через #pragma comment... Просто не делайте так.

Цитата Сообщение от Itisme Посмотреть сообщение
Компилим goal.lib.
Прекрасно. Но при этом мы получим goal.lib отдельно и C.lib отдельно. Сторонние библиотеки как были в C.lib так и остались в C.lib. Внутри goal.lib кода C.lib при этом нет. Внутри goal.lib будет сидеть лишь ссылка на C.lib. То есть вашу исходную задачу вы пока не решили. ОК, будем читать дальше...

Цитата Сообщение от Itisme Посмотреть сообщение
При компиляции exe-приложения нужен только хедер нового в goal.lib кода(заголовки добавленных вами классов/методов) и goal.lib в зависимостях
Ничего не понял про "хедер нового в goal.lib кода". Что такое "хедер нового кода"?

Также, в зависимостях понадобится, разумеется, goal.lib и C.lib (см. выше). А надо ли явно указывать C.lib в зависимостях будет зависеть от ваших настроек, ибо зависимость от C.lib и так уже указана в goal.lib и может быть тихонько взята оттуда, если разрешено настройками.

Цитата Сообщение от Itisme Посмотреть сообщение
Линковщик из-за кода сторонних библиотек будет требовать С.lib (без предыдущего шага он бы требовал файлы всех сторонних библиотек)
Совершенно верно. Он будет требовать C.lib и из-за кода, и из-за того, что внутри goal.lib хранится "требование"/ссылка на C.lib (если вы не подавили это настройками).

Цитата Сообщение от Itisme Посмотреть сообщение
но его можно обмануть, переименовав предварительно goal.lib в С.lib и добавив ее в зависимости в таком виде.
??? Тут описана какая-то мистика.

Кода С.lib нет в goal.lib. Никаким "переименованием" вы это исправить не сможете. Так как кода С.lib нет в goal.lib, такое переименование ничего не даст. Файл линкер будет находить, конечно, но требуемых символов внутри он найти не сможет.

Цитата Сообщение от Itisme Посмотреть сообщение
В итоге все скомпилилось и заработало. Т.е. goal.lib таки включает в себя весь необходимый код,
С чего бы это вдруг? Ни на одном шаге выше вы не выполнили такого включения. По идее, это надо было делать точно так же, как вы описали выше - при помощи утилиты lib упаковать C.lib внутрь goal.lib. Но вы этого не сделали.

Либо вы что-то недоговариваете, либо что-то выдумываете.

Цитата Сообщение от Itisme Посмотреть сообщение
а затем подменяем файл со слитыми библиотеками своим файлом, который содержит и код библиотек и собственный добавленный функционал.
Лишь еще раз повторю: из вашего описания не ясно, каким образом получилось, что в "своем файле" внезапно оказался "код библиотек". Боюсь, что вы выдаете желаемое за действительно. Линковщик скорее всего по прежнему втихаря умудряется подтянуть код сторонних библиотек.
0
12 / 12 / 0
Регистрация: 29.09.2010
Сообщений: 66
21.10.2024, 17:26  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Не смог разглядеть, где я был не прав.
Примерно вот тут:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Никакого "кода A.lib и B.lib внутри goal.lib" не существует.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Замечание о "в инклудах сторонних библиотек правим" видимо относится к странной редкой практике указывать в заголовочных файлах их библиотеки через #pragma comment... Просто не делайте так.
Так и есть, но это вопросы не ко мне, а к разработчикам сторонних библиотек.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Ничего не понял про "хедер нового в goal.lib кода". Что такое "хедер нового кода"?
Очевидно, что я дописал какой-то свой функционал, который должен быть доступен из goal.lib. Ровно как к сторонним библиотекам прилагаются хедеры их методов, нужен хедер, описывающий уже мои методы в моей библиотеке.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Тут описана какая-то мистика.
Кода С.lib нет в goal.lib. Никаким "переименованием" вы это исправить не сможете. Так как кода С.lib нет в goal.lib, такое переименование ничего не даст. Файл линкер будет находить, конечно, но требуемых символов внутри он найти не сможет
Мистика скорее в том, что он все замечательно находит. Без флага на компоновку библиотек из зависимостей и упоминания С.lib в дополнительных зависимостях goal.lib компилится размером в 20 Мб, а с флагом и упоминанием в 150 Мб. что же это за дополнительные 130 Мб? С.lib как раз примерно столько и весит, чуть-чуть больше. Итоговому приложению неоткуда взять С.lib, о чем он честно сообщает, если рядом валяется только goal.lib. Зато если goal.lib переименовывается в С.lib, то у приложения появляется возможность и запускать мой код (дописанный в goal) и использовать функционал сторонних библиотек, который был в исходном C.lib. То есть одна статическая библиотека содержит и мой код и код сторонних библиотек, что как бы и было начальной целью.

Не совсем понимаю, что вас смущает? Возможно, на каком-то этапе сборки библиотек вызывается lib.exe просто с какими-то дополнительными настройками, поэтому в этом режиме получается слить мою библиотеку со сторонними, а у меня в лоб одним только lib.exe это не выходит.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13177 / 6813 / 1821
Регистрация: 18.10.2014
Сообщений: 17,238
21.10.2024, 19:00
Лучший ответ Сообщение было отмечено Itisme как решение

Решение

Цитата Сообщение от Itisme Посмотреть сообщение
Примерно вот тут:
Верно, я был не прав. Поэкспериментировал на практике - и действительно, установка "Link Library Dependencies" на конкретный reference приводит к тому, что вся ссылаемая под-библиотека целиком запаковывается в ссылающуюся библиотеку. Вы правы - это именно так работает. Круто.

Но тогда это сразу же говорит том, что все эти ваши манипуляции с lib и созданием C.lib были не нужными. Зачем тогда вы делали этот шаг с запаковкой A.lib и B.lib в C.lib? Какой в этом был смысл? Достаточно было просто указать "Link Library Dependencies" в ссылках из goal.lib на A.lib и B.lib - и готово. Все содержимое A.lib и B.lib было бы записано в ваш goal.lib, как вы и хотели. Это, кстати, вы изначально и сделали. Чем вас не устроило такое решение? Что не работало?

Ответ, как я догадываюсь, заключается в том, что линкер продолжал требовать файлы A.lib и B.lib. Однако он их требовал не потому, что они реально нужны (они больше не нужны), а просто потому, что авторы этих библиотек тупо вписали в свои заголовочные файлы директивы #pragma comment с ссылками на A.lib и B.lib. В результате линкер всегда безусловно требовал наличия этих файлов.

Криворуких умельцев, которые используют #pragma comment для "подключения библиотек", надо, конечно, лупить по рукам очень больно. Но, это, как я понял, находится, вне вашего контроля.

Однако выше вы упомянули, что вам пришлось исправить ссылки на A.lib и B.lib в заголовках этих библиотек (исправить на C.lib). То есть вам разрешается лезть руками в эти сторонние заголовки и исправлять их? Если так, то более эффективным решением было бы вообще выкосить нафиг из них все эти #pragma comment. После этого линкер перестал бы искать A.lib и B.lib. И все эти дополнительные телодвижения с созданием C.lib и "обманом" линкера стали бы вообще не нужными.
1
12 / 12 / 0
Регистрация: 29.09.2010
Сообщений: 66
21.10.2024, 19:59  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Однако выше вы упомянули, что вам пришлось исправить ссылки на A.lib и B.lib в заголовках этих библиотек (исправить на C.lib). То есть вам разрешается лезть руками в эти сторонние заголовки и исправлять их? Если так, то более эффективным решением было бы вообще выкосить нафиг из них все эти #pragma comment. После этого линкер перестал бы искать A.lib и B.lib.
Все так, однако, это требовало бы глубокого вникания в происходящее. Как я ранее писал, даже настройки Cmake для меня какое-то колдунство, мне туда пришлось лезть, т.к. исходники библиотек под этот компилятор были настроены. Поступило требование все одну статическую библиотеку все запаковать - пришлось на скорую руку разбираться. Я человек простой: вижу, что линкер требует одни файлы, с горем пополам делаю, чтобы он требовал имеющийся, а то, что может и требовать ему ничего не надо - как-то не подумал. Завтра попробую, спасибо за подсказку.
0
12 / 12 / 0
Регистрация: 29.09.2010
Сообщений: 66
22.10.2024, 11:03  [ТС]
Цитата Сообщение от Itisme Посмотреть сообщение
Если так, то более эффективным решением было бы вообще выкосить нафиг из них все эти #pragma comment. После этого линкер перестал бы искать A.lib и B.lib.
Все так. Спасибо еще раз.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.10.2024, 11:03
Помогаю со студенческими работами здесь

Вызов функции одной динамической библиотеки из другой динамической библиотеки
Добрый день! Помогите пожалуйста разобраться со следующим вопросом. Возможно ли из одной библиотеки передать параметры для...

Получение доступа из одной библиотеки к полям другой в CodeIgniter
Здравствуйте. Я пишу свой супер-мега-заковыристый велосипед, с помощю CodeIgniter. Понадобилось мне при загрузке одной библиотеки...

Линковка библиотеки
Здравствуйте, пытаюсь в первый раз прилинковать библиотеку, есть папка /home/god/Qt/chilkat-9.5.0-x86_64-linux-gcc/lib в нём...

Статические библиотеки и их линковка
Подскажите, пожалуйста, где бы почитать теорию о статических библиотеках? Сейчас вот работаю над программой и понадобилось мне работа...

Линковка библиотеки (GPL)
Здравствуйте форумчане! Тут недавно начал кодить на Qt и я ставил себе Open Source, под лицензией GPL. И вот вопрос, я хочу линковать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью в КА2. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа в КА2. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru