Вопрос по предкомпилированным библиотекам

Дисклаймер
Сразу предупрежу, что вопрос чисто теоретический и кода НЕ БУДЕТ. Тем, кто не может обсуждать вопрос без кода, можно сразу закрыть ветку. (Или можно облить меня грязью, мне пофиг)

Для тех, кто готов продолжить.
Есть некий проект, использующий предкомпилированные библиотеки libA.a и libB.a. Функции libA ссылаются при работе на функции из libB. Исходников к libA нет, к libB есть.
Я хочу внести изменения в libB, однако при сборке измененного проекта старая библиотека libA.a перестает видеть функции в перекомпилированной libB

Собственно вопрос - это так и должно быть (я предполагаю, что линковка происходит по адресам функций в файле libB.a, а при перекомпиляции, конечно, эти адреса меняются и все рушится. Или линковка происходит по именам методов - тогда вроде бы все должно собираться и ошибка возникает из-за каких-то других проблем?

Должно собираться

1 лайк

Спасибо
Будем искать…

Если библиотека предкомпилированная, она в любом случае не будет включаться в исполняемый файл.

Она их обязана видеть, если все используемые libA функции в libB экспортированы.

Таки да. Заголовочные файлы меняли? Где-то путаница с “extern "C"” скорее всего. Функции в С так и называются, как Вы пишете, а в С++ в имена добавляются сведения о типах. Если напутать, то просто имена будут другими.

objdump -t libB.a
Читай man objdump, короче.

2 лайка

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

А скрипты сборки ты об этом проинформировал?

И да и нет.

Изначально библиотека собиралась с помощью make. Я же пытаюсь все это собрать в ардуино среде, где make нет. Но файлы сборки проекта внутри ардуино, конечно же, поправил.

ОК, спасибо за помощь.Вы мне дали наводки, по которым я попытаюсь дальше продвинутся в решении.
Я вижу что у меня очень много проблем с пониманием базовых принципов компиляции и линковки, надо подтянуть знания сначала.

согласно objdump символ нужной мне функции абсолютно одинаковый что в исходной библиотеке, что после компиляции

Значит не линкуется

А в каком году (какой версии компилятора) собирались библиотеки? Может у тебя более новая версия и в этой разнице вся «заковырка»?

нет, я написал неправильно.
Нужная мне функция находится в файле utils.c. Согласно objdump в обьектном файле utils.c.o символ функции есть и он такой же, как в исходной библиотеке.
Далее при сборке в среде ардуино все обьектные файлы собираются в один супер-архив core.a. Так вот, согласно objdump, в core.a символа функции уже нет!

При этом в логе компиляции строчка

gcc-ar ru core.a utils.c.o

присутствует.

Причем в в core.a ссылка на файл utils.c.o есть, но ни одна функция из этого обьектника не экспортирована в основной архив.
Далее я просто не понимаю, что к чему.

Что говорят:

nm -g libB.a
(-u и еще -a)

Хотя не уверен, что именно для этих библиотек подходит, но проверить же ничего не стоит?

Еще:

nm -D libname | grep " T " (это вроде бы аналог -g, линукса нет «под рукой»)

nm -g libB.a

00000000 T hex_to_digit

nm -a libB.a


00000000 T hex_to_digit
00000000 t .text.hex_to_digit

где hex_to_digit - имя функции

-u ссылок на функцию не дает, что, по-моему, ожидаемо

(исправлено - добавил строчку во втором выводе)

ладно, всем спасибо, пойду я домой. А то время почти девять у нас тут, я на работе еще

Вывод одинаков и для оригинальной и для перекомпилированной библиотек?

После компиляции библиотеки libB из исходников, по дефолту она будет лежать в папке результата компиляции( там где должен лежать .hex файл прошивки ) а не там где лежала когда линковалась как библиотека . Это тоже надо учесть при компиляции libA .

1 лайк

Это правильно. Надо перерывы делать, оно само обмозгуется еще в перерыв…