2010年10月24日日曜日

SDPA の Windows バイナリのコンパイル方法

前回、一度行ったが、今日改めてやって見たところ、メモに残さないと覚えていられないほど面倒であることが分かった。

ここにメモを書いておく。

まずは、Debian or Ubuntu で Synaptic を使って
gcc-mingw32, mingw32-runtime, mingw32-binutils, wine
をインストールする。
これにより、以下のコマンドが使えるはずである。
i586-mingw32msvc-g++,i586-mingw32msvc-gfortran,i586-mingw32msvc-ar,i586-mingw32msvc-ranlib, wine

次に、lapack-3.2.2 の lapack.tgz をダウンロードしてきて、
cd lapack-3.2.2
cp INSTALL/make.inc.gfortran make.inc
でそのあと、以下の修正をする。
$ diff INSTALL/make.inc.gfortran make.inc
19c19
< FORTRAN = gfortran
> FORTRAN = i586-mingw32msvc-gfortran
23c23
< LOADER = gfortran
> LOADER = i586-mingw32msvc-gfortran
43c43
< ARCH = ar
> ARCH = i586-mingw32msvc-ar
45c45
< RANLIB = ranlib
> RANLIB = i586-mingw32msvc-ranlib
さらに、Makefile も以下のように修正する。
$ diff Makefile.org Makefile
17,18c17,18
< ( cd INSTALL; $(MAKE); ./testlsame; ./testslamch; \
< ./testdlamch; ./testsecond; ./testdsecnd; ./testversion )
---
> ( cd INSTALL; $(MAKE); wine ./testlsame; wine ./testslamch; \
> wine ./testdlamch; wine ./testsecond; wine ./testdsecnd; wine ./testversion )

これで、
make blaslib lapacklib
により、blas_LINUX.a, lapack_LINUX.a が生成される。

次に、pthread-win32 をダウンロードしてくる。
mkdir -p (どっか)/pthread-win32/include
cd (どっか)/pthread-win32/include
wget http://mirrors.kernel.org/sources.redhat.com/pthreads-win32/prebuilt-dll-2-8-0-release/include/pthread.h
wget http://mirrors.kernel.org/sources.redhat.com/pthreads-win32/prebuilt-dll-2-8-0-release/include/sched.h
wget http://mirrors.kernel.org/sources.redhat.com/pthreads-win32/prebuilt-dll-2-8-0-release/include/semaphore.h
mkdir -p (どっか)/pthread-win32/lib
cd -p (どっか)/pthread-win32/
wget http://mirrors.kernel.org/sources.redhat.com/pthreads-win32/prebuilt-dll-2-8-0-release/lib/pthreadGC2.dll
wget http://mirrors.kernel.org/sources.redhat.com/pthreads-win32/prebuilt-dll-2-8-0-release/lib/libpthreadGC2.a

次に、sdpa-7.3.2 のソースディレクトリに移動して、

./configure --prefix=${HOME}/sdpa-install --build=x86_64-unknown-linux-gnu --host=i586-mingw32msvc --target=i586-mingw32msvc --with-blas=(どっか)/blas_LINUX.a --with-lapack=(どっか)/lapack_LINUX.a

によりコンフィグを通す。
これで make をすると mumps のコンパイル中に pthread.h が見つからず止まる。

cd mumps/build で Makefile.inc に以下の修正。
$ diff Make.inc/Makefile.inc.generic.SEQ Makefile.inc
77c77
< AR = ar
> AR = i586-mingw32msvc-ar
80c80
< RANLIB = ranlib
> RANLIB = i586-mingw32msvc-ranlib
117c117
< inc = $(INCSEQ)
> INC = $(INCSEQ) -I(pthreadのディレクトリ)/include
119a120,127
> CC = i586-mingw32msvc-gcc
> FC = i586-mingw32msvc-gfortran
> FL = i586-mingw32msvc-gfortran
> OPTC = -g -O2 -O2 -funroll-all-loops
> OPTF = -g -O2 -O2 -funroll-all-loops
> OPTL = -g -O2 -O2 -funroll-all-loops
> LPORDDIR = (どっか)/sdpa-7.3.2/mumps/build/PORD/lib/
> IPORDDIR = (どっか)/sdpa-7.3.2/mumps/build/PORD/include/

これで mumps/build で
make clean; make d
を実行する。

さらに、sdpa-7.3.2のディレクトリの Makefile を以下のように修正する。
$ diff Makefile.org Makefile
104,105c104,105
< $(LDFLAGS) -o $@
< default_includes = -I.
> $(LDFLAGS) -o $@
> DEFAULT_INCLUDES = -I. -I(pthreadのどっか)/include
200c200
< FCLIBS =
> FCLIBS = -L/usr/lib/gcc/i586-mingw32msvc/4.4.4 -L/usr/lib/gcc/i586-mingw32msvc/4.4.4/../../../../i586-mingw32msvc/lib (pthreadのどっか)/lib/libpthreadGC2.a -lgfortranbegin -lgfortran -lmingw32 -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32

さらに sdpa_newton.h の 33 行目に
#include <pthread.h>
を追加し、sdpa_tool.cpp では、
#include <sys/times.h>をコメントにし、
double Time::rGetUseTime() 関数を削除する。

これで make すると sdpa.exe が完成する。
Linux 上でテストするには、pthreadGC2.dll を sdpa-7.3.2 にコピーしてきて
$ wine ./sdpa.exe example1.dat-s example1.result
である。

これを最終的に Windows に持っていくには、
$ nkf --windows param.sdpa > param.sdpa.windows
$ nkf --windows example1.dat-s > example1.dat-s.windows
として windows 用のテキストファイルにしてから、
sdpa.exe, pthreadGC2.dll, param.sdpa.windows, example1.dat-s.windows を Windows にコピーし、param.sdpa.windows を param.sdpa, example1.dat-s.windows を example1.dat-s にする。
最後にWindows のアクセサリにあるコマンドプロンプトからディレクトリを移動しておき、
sdpa.exe example1.dat-s example1.result
で実行できる。

ここまでで気がついたと思うが、この場合、 reference-blas に接続しているので、ATLAS,GotoBLAS などの性能は出ない。
ATLAS は mingw だとやはりうまくコンパイルができず、GotoBLAS はコンパイルと実行はできるがライセンスの関係で配布できない。

いずれにしても、この程度まで頑張れば、Windows 用のバイナリを生成できる。

6 件のコメント:

  1. sdpa-7.3.1を使用してコンパイルを行ったのですが,
    sdpa-7.3.1のMakefileの編集において,

    200c200
    < FCLIBS =
    > FCLIBS = -L/usr/lib/gcc/i586-mingw32msvc/4.4.4 -L/usr/lib/gcc/i586-mingw32msvc/4.4.4/../../../../i586-mingw32msvc/lib (pthreadのどっか)/lib/libpthreadGC2.a -lgfortranbegin -lgfortran -lmingw32 -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32

    の部分が見つからず,コンパイルが行えません.
    どのように読み変えればよいでしょうか?

    返信削除
  2. 匿名さん、こんにちは。
    sdpa-7.3.1 だと configure が mingw に対応しきってないので、sdpa-7.3.4 にしてください。
    まだ SDPA の Web page に載せていませんが、Debian から
    ダウンロードできます。(Web page に載せるのは、7.3.5 以降になる予定です。)
    ダウンロードは、

    http://ftp.de.debian.org/debian/pool/main/s/sdpa/sdpa_7.3.4.dfsg.orig.tar.gz

    です。
    これには、MUMPS_4.8.4.tar.gz が含まれていないので、sdpa-7.3.1 のディレクトリにある MUMPS_4.8.4.tar.gz を mumps ディレクトリにコピーしてください。

    configure については、
    export CFLAGS="-D__CLEANUP_C -O3 -finline-functions -DPTW32_BUILD_INLINED -D
    PTW32_STATIC_LIB -I. -DHAVE_CONFIG_H -Wall"
    export CXXFLAGS="${CFLAGS}"
    export FCFLAGS="${CFLAGS}"
    ./configure --prefix=${どこか}/sdpa-install \
    --build=x86_64-unknown-linux-gnu \
    --host=i586-mingw32msvc \
    --target=i586-mingw32msvc \
    --with-blas=${どこか}/lapack-current/blas_LINUX.a \
    --with-lapack=${どこか}/lapack-current/lapack_LINUX.a \
    --with-pthread-include="-I${MINGW_BASE}/pthreads-current" \
    --with-pthread-libs=${どこか}/pthreads-current/libpthreadGC2.a \
    --with-mumps-libs=NO_MUMPS
    のように指定して、あとは
    make
    make install
    でコンパイルができます。
    いちおう make install できますが、実際に使うのは sdpa.exe だと思うのでこれを使ってください。
    (できたバイナリが sdpa の時には sdpa.exe にしないと
    Windows では実行できません。)

    もし、他にもあればメールで聞いてくれてもOKです。

    返信削除
  3. 素早い返答,ありがとうございます.
    私がLinux上でのプログラミングに不慣れなため,これほど多くのヒントをいただいておきながら,いまだ解決できずにいます...
    configure の設定で

    configure: error: Pthread link failed

    とエラーがでているので,pthreadのパス設定に問題があるのだと考えられます.
    パスの設定について教えていただけませんでしょうか?

    また,メールでの質問の場合,何処宛で送ればよろしいでしょうか?
    よろしくお願いします.

    返信削除
  4. えっと、pthread がうまくリンクできていない状態ですね。
    自分の場合も試行錯誤でようやくできていたりします。

    pthread と lapack をコンパイルするためのスクリプトについては、
    http://margaret-sdpara.blogspot.com/2010/12/pthread-win32-lapack-on-mingw32.html
    に載せてあるので、参考にしてください。

    あと、メールなどでの問い合わせは、
    http://sdpa.indsys.chuo-u.ac.jp/sdpa/contact.html
    を参考にお願いします。
    開発者全体に送ってもらっても対応しますし、個別のホームページからアドレスを見つけてそちらに送ってもらっても対応します。

    よろしくお願いします。

    返信削除
  5. 試行錯誤のすえ,やっとコンパイルすることができました.
    ありがとうございます.

    返信削除
  6. 匿名さん、コンパイルできてよかったです。
    もしうまく行かないことがあったら、またコメントを書いてください。
    では。

    返信削除