2016-05-23 8 views
0

Я пытаюсь скомпилировать двоичный файл, связывающий его со статической библиотекой libfoo.a:Неопределенная ссылка на символ на статическую библиотеке

gcc -L. -o myapp myapp.o -lfoo 

Но я получаю следующее сообщение об ошибке от линкера:

libfoo.c:101: undefined reference to `_TRACE' 

Проблема в том, что у меня нет исходного кода для библиотеки libfoo.a. Я пытался получить ссылку на _TRACE символ в библиотеке, и я получил это:

nm libfoo.a | grep TRACE 
    U _TRACE 

Предполагая, что _TRACE не будет влиять на внутреннюю работу в libfoo.a, можно получить компоновщик определить некоторое значение заполнителя для этот символ, чтобы я мог скомпилировать свой код?

ответ

2

Предполагая, что _TRACE не будет влиять на внутреннюю работу в libfoo.a

Это кажется неоправданно обнадеживающее предположение.

Возможно ли, чтобы линкер определял какое-либо значение-заполнитель для этого символа, чтобы я мог скомпилировать свой код?

Первое, что нужно сделать, это проверить документацию libfoo. Для статической библиотеки необычно полагаться на символ, который должен определить пользователь; на самом деле такая договоренность не работает чисто с традиционными линкерами. Я вижу несколько правдоподобных объяснений:

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

  2. Ожидается, что код, который использует libfoo, соответствует ассоциированному заголовку, и этот заголовок содержит предварительное определение _TRACE.

  3. Программы, которые используют libfoo, должны быть построены с помощью специальной инструментальной цепочки и, возможно, конкретных опций.

  4. Это просто сломан.

Только в случае (4) является целесообразным, чтобы попытаться вручную обеспечить определение символа в вопросе, и в этом случае вам лучше действовать более или менее, как и в случае (1), по создавая объект, который предоставляет определение и связывает его после библиотеки. Конечно, это заставляет вас пытаться угадать, каково должно быть определение.

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

+1

Если 'intmax_t _TRACE = 0;' не работает, 'int _TRACE() {return (0); } 'как' _TRACE' может быть макросом, который не получил должным образом определённого значения, поэтому ему по умолчанию была указана неявно определенная функция, возвращающая 'int'. Я сомневаюсь, что когда-либо доверял бы такой библиотеке что-нибудь важное, однако, если такие махинации - это то, что нужно, чтобы заставить ее даже привязать. –

+0

Моя первоначальная идея была чем-то похожей на '#define _TRACE' только для компиляции. Мое предположение заключается в том, что _TRACE - это функция, которая печатает отладочную информацию, поэтому местозаполнитель будет просто отлично. Я хотел бы знать, возможно ли это. –

+0

@Gustavo - Вы компилируете 'libfoo.a', или у вас есть только статическая библиотека? –

0

Как я и предполагал, функция _TRACE является своего рода функцией отладки. И я был прав, полагая, что это не повлияет на внутреннюю работу libfoo.a.

Я решил проблему определения функции _TRACE как:

int _TRACE(char*, ...) { return 0; } 

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