ATLAS の共有ライブラリで ldconfig が失敗する

もうずいぶん前になるが,研究室のサーバーに ATLAS を入れたとき,共有ライブラリをインストールしようと ldconfig を実行すると,次のように表示されて実行が失敗した.

$ ldconfig
ldconfig: Can't link /usr/local/atlas/lib//usr/local/atlas/lib/libsatlas.so to libsatlas.so
ldconfig: Can't link /usr/local/atlas/lib//usr/local/atlas/lib/libtatlas.so to libtatlas.so

そのときはとくに致命的でもなく,しばらく放置していたのだが,OS のアップグレードに合わせて ATLAS を入れ直すことになったので,ついでにこの問題の解決方法を探ってみることにした.

原因

configure を実行したあとにビルドディレクトリ下に生成される lib/Makefile の中に,次の記述がある.

LDTRY_WIN:
	$(LD) $(LDFLAGS) -shared -soname $(LIBINSTdir)/$(outso) -o $(outso) \   
           -rpath-link $(LIBINSTdir) --output-def=$(outdef) \                   
           --whole-archive $(libas) --no-whole-archive $(LIBS)

ここで,ld がライブラリファイルを生成するときに,ファイル中に完全記述 soname(インストールディレクトリのパス + ライブラリ名)を記録している.このファイルをそのままインストールディレクトリに入れて ldconfig を実行すると,ldconfig はファイルのあるディレクトリのパス + ファイルに記録された完全記述 soname,つまりインストールディレクトリのパスが2回繰り返されたパスを探しに行ってしまい,サーチが失敗する.ld / ldconfig の知識が足りないのでこの理解でよいのか自信がないが,そうなっていると思えば納得できる.

対策

上のような状況を避けるためには,soname を記録しないでリンカを実行するのが手っ取り早いと思う.必要な static ライブラリは生成されているので,これを全部 ld に渡してやればよい.具体的な手順は次のようになる.

  1. とりあえず make を実行して ATLAS をビルドする.lib ディレクトリに生成物が出力される.
  2. 生成物のうち,共有ライブラリ(libsatlas.so,libtatlas.so)を削除しておく.
  3. 次のコマンドを実行して,soname のない共有ライブラリを新たに作成する.
    $ ld -shared -o libsatlas.so \
    --whole-archive libtstatlas.a libatlas.a liblapack.a \
    --no-whole-archive libf77blas.a libcblas.a
    $ ld -shared -o libtatlas.so \
    --whole-archive libtstatlas.a libatlas.a libptlapack.a \
    --no-whole-archive libptf77blas.a libptcblas.a
    
  4. make install して,ldconfig を実行する.

ld につけるオプションは好みだが,心配なら Makefile と同じ指定をする.$LDFLAGS はビルドディレクトリ直下の Make.inc に書いてある.

コメントを残す

メールアドレスが公開されることはありません。