Получение неопределенных ссылок при связывании со статической библиотекой - PullRequest
2 голосов
/ 10 июля 2010

Я сделал статическую библиотеку с GCC.Сборка библиотеки была в порядке.

Когда я ее использую, компоновщик выдает неопределенные ошибки ссылки на некоторые функции.Но nm говорит, что функции определены и экспортированы в статическую библиотеку (помеченную T).Я знаю о порядке компоновки, который мне нужно поместить библиотеки после того модуля, который нуждается в них, так что это не может быть проблемой.

Статическая библиотека была построена из файлов 3 C.Ac Bc и Dc Модуль D зависит от A и B (включая их заголовки).

Нет проблем, когда я использую функции из A и B, но когда я пытаюсь использовать любую функцию из D, я получаю неопределенные ошибки ссылок на них.

Если переместить эти функции в A или B, это сработает.Но не в том случае, если они находятся в модуле D.

У меня совершенно нет идей, что происходит или что меня упускают.

Я использую Code :: Blocks иработа с простыми файлами C.

Ответы [ 4 ]

2 голосов
/ 10 июля 2010

Старый трюк, который много раз срабатывает: перечислите каждую статическую библиотеку дважды на этапе компоновки.

, то есть в вашем make-файле (или что бы вы ни использовали), введите:

gcc -o <outfile> <liba> <libb> <libc> <liba> <libb> <libc>

Во всяком случае, я надеюсь, что вы поняли идею.

1 голос
/ 18 мая 2012

В основном файле make, который я написал для упрощения сборки приложений / библиотеки, я использовал решение дважды выполнить шаг ссылки.Использование опции компоновщика -u для указания неопределенных символов на второй ссылке.

В моем файле make у меня есть цель, подобная этой:

undefined.txt:
    @$(generate-undefined-syms)

, которая вызывает этот макрос ... первыйпопытка связать ...

define generate-undefined-syms
    $(PRINTF) "$(this_makefile): Generating undefined symbols ... \n"
    $(CC) -o rubbish $(LDFLAGS) $(objects) $(LDLIBS) 2>&1 | $(GREP) 'undefined reference' > tmp.txt; \
    $(SED) 's/^.*`/-Wl,-u/g' < tmp.txt > undefined.txt; \
    rm -f tmp.txt rubbish
endef

Поскольку мои навыки sed / regexp не очень хороши (и я написал этот материал в спешке), я получаю undefined.txt, содержащий:

-uSomeSym'
-uSomeOtherSym'

то есть с завершающим '

Затем я использую этот синтаксис make для удаления' s 'и удаления дубликатов

undefined_references = $(filter-out follow, $(sort $(subst ',,$(shell cat undefined.txt))))

Фильтр follow следует, потому что если неопределенный символссылаясь много раз, в выходных данных появляется сообщение «больше ссылок на XXX follow», что приводит к ложному «follow» в файле undefined.txt, например,

-Wl, uXXXX' follow

Наконец я связываюсь во второй раз (примечаниезависимость от undefined.txt)

$(application): $(library_dependencies) $(objects) undefined.txt
    $(CC) -o $@ $(LDFLAGS) $(undefined_references) $(objects) $(LDLIBS)

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

Управление проектами с помощью GNU Make, третье издание Автор: Роберт Мекленбург

1 голос
/ 12 июля 2010

Я обнаружил, что добавил в свой проект файл .cpp и просто переименовал его в .c.Я выбрал язык C вместо C ++, когда создавал проект.Я не думал, что это может вызвать проблемы

Я думал, что расширение файла решает, когда IDE выбирает между gcc и g ++.Но нет.В Code :: Blocks, если вы добавите файл с расширением .cpp, он будет использовать g ++.Если вы добавите файл с расширением .c, он будет использовать gcc.Но если вы переименуете файл, он будет использовать тот же компилятор.Вы должны явно изменить это в настройках проекта.

Этот модуль D был построен с использованием g ++ вместо gcc.

Я понял это, когда установил в IDE всю командную строку, когдасборка не просто "Компиляция foo.c".

0 голосов
/ 10 июля 2010

Возможно, вам следует использовать ranlib или параметр approriate ar, чтобы указать индекс для вашего .a файла.

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