3

OSX の BLAS 実装に対してリンクしようとしています (好奇心旺盛な方のために) が、netlib から独自の LAPACK ビルドを使用したいので、同じディレクトリに/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylibリンクしたくありません。libLAPACK.dylibより最近で最新のもの。

私の問題は、通常 LAPACK ライブラリに格納されている BLAS ライブラリにシンボルがあり、そのため名前の競合が発生していることです。具体的な例として、spotrf関数は次のように定義されていlibBLAS.dylibます。

$ nm /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib | grep spotrf
0000000000010c05 T $ld$hide$os10.7$_spotrf
0000000000010c05 T $ld$hide$os10.8$_spotrf
000000000000746e T _spotrf

これらの最初の 2 つの記号は少し怪しいと思ったので、再確認するために、以下も確認しlibLAPACK.dylibます。

$ nm /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib | grep spotrf
00000000000010c8 T $ld$hide$os10.4$_spotrf
00000000000010c8 T $ld$hide$os10.5$_spotrf
00000000000010c8 T $ld$hide$os10.6$_spotrf
000000000000765b T _spotrf

私が見つけた限られた情報から、このプレフィックスは、ユーザーが特定の OSX バージョンに対してコンパイルしている場合、動的リンカーにこれらのシンボルを無視するように指示しているようです。libBLAS.dylibApple がシンボルをlibLAPACK.dylib10.6 から 10.7 の間に移動した場合、これは理にかなっています。

spotrf私の質問は、内部にあるなどを非表示にする必要があることをダイナミックリンカーにどのように通知できlibBLAS.dylibますか?

4

1 に答える 1

2

まず、動的にリンクしているため、目的の動作を得るために実際に特別なことをする必要はありません。リンク コマンドの -lblas の前に netlib でビルドされた LAPACK が表示されていることを確認してください。すべての LAPACK インターフェイスが netlib LAPACK から取得されます (ldリンクされている各ライブラリに対して可能なすべての未定義シンボルを順番に一致させます)。

または、netlib LAPACK がシステム BLAS に対してリンクされていると仮定すると、BLAS シンボルをすべて再エクスポートするように LAPACK のリンクを構成できるはずです。次に、LAPACK に対してリンクするだけで、リンク コマンドから -lblas を完全に除外できます。


$show$およびシンボルは$hide$、システム BLAS とシステム LAPACK ライブラリの両方に対してリンクしている場合にのみ機能します。簡単な例は、その場合にどのように機能するかを示しています。

Kronecker:~ scanon$ cat foo.c
void dgetrf_(void);
int main(void) { dgetrf_(); return 0; }

これを 10.9 でビルドし、 でブレークすると、ビルド コマンドで最初に表示されますが、dgetrf_シンボルが から取得されたことがわかります。これは、10.9 を対象とする場合にシンボルが非表示になるためです。libLAPACK.dylib-lblaslibBLAS.dylib

Kronecker:~ scanon$ clang foo.c -lblas -llapack
Kronecker:~ scanon$ lldb a.out 
Current executable set to 'a.out' (x86_64).
(lldb) b dgetrf_
Breakpoint 1: 2 locations.
(lldb) run
...
frame #0: 0x00007fff89237b70 libLAPACK.dylib`dgetrf
libLAPACK.dylib`dgetrf:
...

指定した場合-mmacosx-version-min=10.6(10.6 Snow Leopard で実行できる実行可能ファイルを生成することをコンパイラとリンカーに伝えます)、代わりにシンボルがピックアップされていることがわかりますlibBLAS.dylib。これは、シンボルが 10.6 に存在しないためです。したがって、シンボルが使用されlibLAPACK.dylibた場合、実行可能ファイルはそのプラットフォームで実行できません。libLAPACK.dylib

Kronecker:~ scanon$ clang foo.c -lblas -llapack -mmacosx-version-min=10.6
Kronecker:~ scanon$ lldb a.out 
Current executable set to 'a.out' (x86_64).
(lldb) b dgetrf_
Breakpoint 1: 2 locations.
(lldb) run
...
frame #0: 0x00007fff8c9d6841 libBLAS.dylib`DGETRF_
libBLAS.dylib`DGETRF_:
...
于 2013-11-05T16:28:54.830 に答える