MinGW + MSYSでVST Plug-inを作る方法とサンプル。
prefix=/opt/MinGWとします。bootstrapには、MinGWのバイナリが必要になりますが、まず binutilsをsourceからbuildします。
$ tar -zxvf binutils-2.16.91-20060119-1-src.tar.gz $ cd binutils-2.16.91-20060119-1 $ ./configure --prefix=/opt/MinGW --target=i386-mingw32 -v $ sudo make install
次に、bootstrap用のバイナリとヘッダファイルとライブラリファイルを$prefix/$targetに解凍します。 この時点ではw32apiとmingw-runtimeをsourceからbuildすることはできません。
$ sudo tar -zxvf w32api-3.8.tar.gz -C /opt/MinGW/i386-mingw32/ $ sudo tar -zxvf mingw-runtime-3.11.tar.gz -C /opt/MinGW/i386-mingw32/
次にgccをbuildします。configureでは、languagesとprefixとtarget以外は好きに選んで下さい。 make CFLAGS="-O2 -fomit-frame-pointer" CXXFLAGS="-mthreads -fno-omit-frame-pointer -O2" LDFLAGS=-s bootstrap などもできますが、エラーが出る事があります。オプションはほどほどにしましょう。
$ tar -zxvf gcc-core-3.4.2-20040916-1-src.tar.gz $ tar -zxvf gcc-g++-3.4.2-20040916-1-src.tar.gz $ mkdir gcc-work;cd gcc-work $ ../gcc-3.4.2-20040916-1/configure --enable-languages=c,c++ \ --prefix=/opt/MinGW/ --with-gcc --with-gnu-ld --with-gnu-as \ --target=i386-mingw32 --enable-threads --disable-nls \ --disable-win32-registry --disable-shared \ --enable-sjlj-exceptions --disable-libstdcxx-debug $ make $ sudo make install;cd ..
以上最低限はおわりです。正しくかかれたautotoolsでは--target=i386-mingw32とし、 /opt/MinGW/binにパスを通せば使える筈ですが、だめならCCなどをオーバーライドします。
PATH=$PATH:/opt/MinGW/bin build=i486-slackware-linux target=i386-mingw32 host=i386-mingw32 ./configure --prefix=/opt/MinGW --build=$build --host=$host --target=$target
リンクの順番は大事です。gccを直接呼び出す場合、使用するライブラリ (-lkernel32など)は最後に書きますが、automakeなどを使用していると、 libtoolが勝手に並べかえるので、gccでなくlinkerに渡すコマンド(-Wl,-lkernel32) としてかき、最後に持ってくるようにします。
# Makefile.am lib_LTLIBRARIES = Freeverb3VST.la Freeverb3VST_la_LDFLAGS = -module -avoid-version -no-undefined \ -Wl,-lkernel32 Freeverb3VST_la_LIBADD = ... Freeverb3VST_la_SOURCES = ...
リンクの順番を間違えると以下のようなエラーが出ます。
/opt/MinGW//i386-mingw32/lib/libmingwex.a(gettimeofday.o):gettimeofday.c:(.text+0x45): undefined reference to `___udivdi3' /opt/MinGW//i386-mingw32/lib/libmingwex.a(gettimeofday.o):gettimeofday.c:(.text+0x60): undefined reference to `___umoddi3' /opt/MinGW//i386-mingw32/lib/libmingwex.a(gettimeofday.o):gettimeofday.c:(.text+0x8a): undefined reference to `___udivdi3'
windresはconfigure.inで以下のようにして取得でき、Makefile.am内で$(WINDRES)として使用できます。
(
Autotools Generic Program and File Checks)
AC_CHECK_TARGET_TOOL([WINDRES], [windres], [no]) if test "x$WINDRES" = "xno"; then AC_MSG_ERROR([Cannot find windres]) fi AC_SUBST(WINDRES)
architecture-vendor-osSometimes the vender tag is left out. The following are several examples of common architecture tags used:
i386-redhat-linux ppc-yellowdog-linux ppc-apple-darwin i686-pc-cygwin i386-mingw32 i386-pc-mingw32 i686-pc-cygwin i386-linux i686-linux sparc-linux sparc64-linux arm-linuxWhen configuring, if you don't know the full vender tag, you can often just use the platform-os name.
export set PATH=/usr/i586-mingw32msvc/bin:$PATH export set build=i486-linux-gnu export set host=i586-mingw32msvc export set target=i586-mingw32msvc
cygwin,MinGW/make 3.81でときどき発生するようです。クロスコンパイル時のパスの扱いに問題があり、 パッチの情報があります。 別のバージョンを使う手もあります。UNIXなのに、PloにC:\MinGW\...などと 設定されているのが原因です。どうしてもうまくいかないときは、*.Ploや.cacheなどすべての 生成されたファイルを消去して初めからautotoolsをやり直すのもよいかもしれません。
シングルスレッドですむ場合には特に気をつける必要がないのですが、マルチスレッドプログラムを
ビルドする場合、TLS(Thread Local Storage)やEH(Exception Handling)の機構を利用するので、
いろいろと気をつける必要があります。
よくある問題が、-mthreads利用時のmingwm10.dllへの依存です。
-D_MT -mthreadsによって、多くのビルトイン関数(putとか)がthread-safe ライブラリを利用するようになりますが、
その時、マルチスレッドでtry-catchなどEHを利用する場合にMinGWライブラリの不整合から
少なくとも24bytesずつメモリリークするのを防ぐために、
DllMain()トラップを利用してリソースの開放を行うためのちょっとしたハックです。EHを使わないなら
-fno-exceptionsで明示すればよいですが、ふつうはEHを使っているのでリークの原因となります。
ちなみに、SEHは、Windowsでデバッグ情報などの例外を管理するための機構で、C++のEHとは違いますが、SEHをC++のEHで
とらえるようにできます(/EHa)。
古いOSのサポートは面倒ですね。
Makefile.amでLDFLAGS += -Wl,-lmingw32 -Wl,-lmingwex -Wl,-lmingwthrdとかするとよい。 まあ、見つからない関数をlibディレクトリでかたっぱしからgrepすればリンクすべきライブラリは みつかるんだけど。あと、リンクする順序には気をつけましょう。
rateconv.o:rateconv.cpp:(.text+0xa40): multiple definition of `_main' libmingw32.a(main.o):(.text+0x0): first defined here libmingw32.a(main.o):(.text+0x85): undefined reference to `_WinMain@16'
dllを作るときには-lmingw32をつけてもいいですが、単体exeを作る時に-lmingw32を入れるとエラーになります。
configure;make;make installでインストールしないで*.aだけをコピーしたりすると以下のような エラーを吐いてdllが生成されないことがあります。
*** Warning: linker path does not have real file for library -lfftw3f-sse. *** I have the capability to make that library automatically link in when *** you link to this library. But I can only do this if you have a *** shared version of the library, which you do not appear to have *** because I did check the linker path looking for a file starting *** with libfftw3f-sse and none of the candidates passed a file format test *** using a file magic. Last file checked: /mnt/CVS/freeverb3_vst/lib/libfftw3f-sse.a
静的ライブラリだと、基本的には、*.laと.libs/*.aでペアになるのがlibtoolの作法なので、“どうしても”手動で コピーしたい場合は、*.laと.libs/*.aをセットになるようにしましょう(.libsは自分で掘る)。ふつうはmake installが すべてやってくれるんですが。上は、libfftw3f-sse.aのみをコピーしたためにエラーとなりました。 *.laはテキストファイルなので、ほかから*.laを持ってきてold_libraryの部分「のみ」を書き換えて対処できます。 ちなみに、コメント部分を消すとうまくいきません。 (なお、libtoolが.laファイルの2行目の「libtoolのバージョン」を参照するため、.laファイルの先頭2行のコメントは削除してはならない。) -lfooとしても、そこにlibfoo.aがあるのかlibfoo.laがあるのか、 はたまたlibfoo.soがあるのか、libfoo.dll.aがあるのか、libtoolにすべて任せるほうが簡単でしょう。
MinGW w64で普通にビルドすると、いくつかのDLL依存になることがあります。 libgcc_s_sjlj-1.dll や libstdc++-6.dllはstatic linkにすることもできます。-static-libgccや-static-libstdc++は gccやg++へのオプションなので、libtoolを利用している場合には、LDFLAGSから削られてしまうことがあります。 どうしても依存をなくしたい場合は、x86_64-w64-mingw32/lib64/libstdc++.dll.aをlibstdc++.aへのリンクに、 libgcc_s.aをlib/gcc/x86_64-w64-mingw32/4.5.0/libgcc.aへのリンクにすると強制的にstatic linkとなります。 libgcc_eh.aはlibgcc.aに含まれないいくつかのexception handlingのコードを含んでいますが、 libgcc_s.soというshared libraryはすべてを含んでいます。
上で述べたように、dll依存のライブラリと静的リンクのライブラリが共存しているので、 動的・静的ライブラリ両方を指定するなど、リンクの仕方を間違えると出ます。やっていることが わかっていれば、--allow-multiple-definitionを使って強制的にリンクできますが、MinGWやcygwinでは 時々起る問題で、DLL間でexceptionを投げられるようになるなど動的ライブラリが望ましいんですが、 バイナリ配布のときにはDLLをインストールさせるのが面倒だったりするので一概には決められないのが難点です。
MPlayer cross-platform UNIX movie player, Cygwin port
Benchmarking SSE instructions - Stack Overflow
Old Nabble - MinGW - User - MinGW with SIMD (SSE, etc)
整列したメモリを静的に確保する attribute ((aligned(n)) - PS3 Linux Information Site / Cell/B.E.のパワーを体験しよう
株式会社エス・スリー・フォー ≫ Blog Archive ≫ sizeofの不思議
The Road to Hell Is Paved with Good Intentions
Yet another Unix nightmare: statically linking libstdc++ | 2005-05-31 | christopher baus.net
Among the generalists, the conventional wisdom is that the worse-is-better approach is more adaptive. Personally, I get a little tired of the argument: My worse-is-better is better than your worse-is-better because I'm better at being worser! Is it really true that the worse-is-better approach always wins? With Perl 6 we're trying to sneak one better-is-better cycle in there and hope to come out ahead before reverting to the tried and true worse-is-better approach. Whether that works, only time will tell. Larry Wall in "State of the Onion 11" http://www.perl.com/pub/a/2007/12/06/soto-11.html?page=3 -- Larry Wall -- State of the Onion 11 ( http://www.perl.com/pub/a/2007/12/06/soto-11.html?page=3 ) Suspicion always haunts the guilty mind. -- Wm. Shakespeare