現在、Mac OS X 10.6.7 と Xcode 4.0.2 で弱いリンクの問題に遭遇しました。
robin@chameleon:/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_import)) を使用できます。ただし、次のサンプル コードは常にコンパイル エラーをスローします。次のように:
弱い.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@chameleon:/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
を使用しても、実行時にエラーがスローされます。
robin@chameleon:/tmp/o$ gcc -undefined dynamic_lookup weak.c
robin@chameleon:/tmp/o$ ./a.out
dyld: Symbol not found: _SayHello
Referenced from: /private/tmp/o/./a.out
Expected in: dynamic lookup
Trace/BPT trap
「a.out」のnm -m
メッセージは次のとおりです。
robin@chameleon:/tmp/o$ nm -m a.out | grep Hello
(undefined) external _SayHello (dynamically looked up)
これは次のように予想されました:
(undefined) weak external _SayHello (dynamically looked up)
ただし、gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 を使用して Ubuntu でコンパイルすると、期待どおりに動作します。
弱い.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 のシンボルは次のとおりです。
robin@robinz:/tmp/o$ nm a.out | grep Hello
w SayHello
"w" シンボルは、特に弱いオブジェクト シンボルとしてタグ付けされていない弱いシンボルです。
古い xcode 3.2 をテストすると、期待どおりに動作します。
誰かがこれについて私を助けることができますか? ldのバグでしたか?
そして、さらに興味深いものを見つけました。動的ライブラリで SayHello シンボルをエクスポートするダミー ライブラリを作成すると、期待どおりに動作します。
ダミー.c :
int SayHello() {
return;
}
robin@chameleon:/tmp/o$ gcc -dynamiclib -o libdummy.dylib dummy.c
robin@chameleon:/tmp/o$ gcc weak.c libdummy.dylib
robin@chameleon:/tmp/o$ ./a.out
SayHello is present!
「libdummy.dylib」が存在しない場合:
robin@chameleon:/tmp/o$ rm libdummy.dylib
robin@chameleon:/tmp/o$ ./a.out
SayHello is not present!
期待どおりに動作します!予想どおり、nm メッセージにウィーク シンボルが表示されるようになりました。
robin@chameleon:/tmp/o$ nm -m a.out | grep Hello
(undefined) weak external _SayHello (from libdummy)