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

Слабая символьная ссылка на Mac OS X

В настоящее время я столкнулся с проблемой слабого соединения в Mac OS X 10.6.7 с Xcode 4.0.2.

[email protected]:/tmp/o$ gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)

Как говорится в документе http://developer.apple.com/library/mac/#technotes/tn2064/_index.html, мы можем использовать gcc атрибут ((слабый_импорт)) для слабой ссылки символ. Однако следующий примерный код всегда выдает ошибку компиляции. Как показано ниже:

weak.c

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

extern int SayHello() __attribute__((weak));

int main()
{
    int result;

    if (SayHello!=NULL)
    {
        printf("SayHello is present!\n");
        result=SayHello();
    }
    else
        printf("SayHello is not present!\n");
}

Сообщение об ошибке следующее:

[email protected]:/tmp/o$ gcc weak.c 
Undefined symbols for architecture x86_64:
  "_f", referenced from:
      _main in cceOf2wN.o
     (maybe you meant: __dyld_func_lookup)
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

Даже если используется опция -undefined dynamic_lookup, она все равно выдает ошибку во время выполнения:

[email protected]:/tmp/o$ gcc -undefined dynamic_lookup weak.c 
[email protected]:/tmp/o$ ./a.out 
dyld: Symbol not found: _SayHello
  Referenced from: /private/tmp/o/./a.out
  Expected in: dynamic lookup

Trace/BPT trap

Сообщение nm -m "a.out" следующее:

[email protected]:/tmp/o$ nm -m a.out  | grep Hello

(undefined) external _SayHello (dynamically looked up)

Ожидалось, что следующее:

(undefined) weak external _SayHello (dynamically looked up)

Однако, когда я компилирую Ubuntu с gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5, он работает как ожидалось:

weak.c

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

extern int SayHello() __attribute__((weak));

int main()
{
    int result;

    if (SayHello!=NULL)
    {
        printf("SayHello is present!\n");
        result=SayHello();
    }
    else
        printf("SayHello is not present!\n");
}

    robin @robinz:/tmp/o $gcc weak.c   robin @robinz:/tmp/o $./a.out   SayHello нет!

Символ SayHello в двоичном формате:

[email protected]:/tmp/o$ nm a.out | grep Hello
w SayHello

"w" Символ является слабым символом, который не был специально помечен как символ слабого объекта.

И я тестирую старый xcode 3.2, он работает как ожидалось.

Может ли кто-нибудь помочь мне в этом? Это была ошибка ld?

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

dummy.c

int SayHello() {
    return;
}

 

[email protected]:/tmp/o$ gcc -dynamiclib -o libdummy.dylib dummy.c 
[email protected]:/tmp/o$ gcc weak.c libdummy.dylib 
[email protected]:/tmp/o$ ./a.out 
SayHello is present!

Если "libdummy.dylib" не существует:

[email protected]:/tmp/o$ rm libdummy.dylib 
[email protected]:/tmp/o$ ./a.out 
SayHello is not present!

Работает как ожидалось! Слабый символ теперь в сообщении nm, как и ожидалось:

[email protected]:/tmp/o$ nm -m a.out | grep Hello

                 (undefined) weak external _SayHello (from libdummy)
4b9b3361