Подтвердить что ты не робот

Как сделать слабую связь с GCC?

Кажется, есть 3 способа сообщить GCC о слабой ссылке на символ:

  • __attribute__((weak_import))
  • __attribute__((weak))
  • #pragma weak symbol_name

Никто из них не работает для меня:

#pragma weak asdf
extern void asdf(void) __attribute__((weak_import, weak));
...
{
    if(asdf != NULL) asdf();
}

Я всегда получаю ошибку ссылки следующим образом:

Undefined symbols:
  "_asdf", referenced from:
      _asdf$non_lazy_ptr in ccFA05kN.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Я использую GCC 4.0.1 на OS X 10.5.5. Что я делаю неправильно?

4b9b3361

Ответ 1

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

Слабая связь со слабым_импорт действительно работает только с динамическими библиотеками. Вы можете заставить его работать со статическим связыванием (указав - undefined dynamic_lookup, как было предложено выше), но это не такая уж горячая идея. Это означает, что символы undefined не будут обнаружены до выполнения. Этого я бы избежал в производственном коде лично.

Вот сеанс терминала Mac OS X, показывающий, как заставить его работать:

Здесь f.c

int f(int n)
{
    return n * 7;
}

Вот whatnof.c

#include <stdio.h>
#include <stdlib.h>

extern int f (int) __attribute__((weak_import));

int main() {
    if(f == NULL)
        printf("what, no f?\n");
    else
        printf("f(8) is %d\n", f(8));
    exit(0);
}

Сделайте динамическую библиотеку из файла f.c:

$ cc -dynamiclib -o f.dylib f.c

Скомпилировать и связать динамическую библиотеку lib, список динамических библиотек.

$ cc -o whatnof whatnof.c f.dylib
$ otool -L whatnof
whatnof:
       f.dylib (compatibility version 0.0.0, current version 0.0.0)
       /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)

Запустите whatnof, чтобы узнать, что произойдет:

$ whatnof
f(8) is 56

Теперь замените f.dylib пустой библиотекой (без символов):

$ mv f.dylib f.dylib.real
$ touch null.c
$ cc -dynamiclib -o f.dylib null.c

Запустите ту же самую whatnof, чтобы узнать, что происходит:

$ whatnof
what, no f?

Основная идея (или "use case" ) для weak_import заключается в том, что она позволяет вам связываться с набором динамических (общих) библиотек, но затем запускать тот же код с более ранних версий тех же библиотек. Вы можете проверить функции на NULL, чтобы узнать, поддерживаются ли они в конкретной динамической библиотеке, с которой в данный момент работает данный код. Это, похоже, является частью базовой модели разработки, поддерживаемой Xcode. Я надеюсь, что этот пример полезен; это помогло мне успокоиться в этой части дизайна Xcode.

Ответ 2

Добавьте -Wl,-flat_namespace,-undefined,dynamic_lookup в строку компилятора gcc, которую вы используете для окончательной ссылки.

Ответ 3

Вам нужно установить переменную MACOSX_DEPLOYMENT_TARGET в 10.2 или новее. См. документация Apple и их technote на слабом сшивание.

Ответ 4

В руководстве gcc doc:

слабый

Слабый атрибут заставляет объявление выдаваться как слабый а не глобальным. Это в первую очередь полезно при определении библиотечные функции, которые могут быть переопределены в коде пользователя, хотя это также может использоваться с не-функциональными объявлениями. Слабые символы поддерживается для целей ELF, а также для целей a.out при использовании сборщик и компоновщик GNU.

что означает, что объект легитимирован, чтобы перезаписать слабый символ (определенный в другом объекте/библиотеке), не получая ошибок во время связи. Неясно, связывается ли библиотека со слабым символом или нет. Кажется, что и вы не определили символ, и библиотека неправильно связана.