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-linux
When 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
<rooneg> weird, mine and jack's come out way too fast with this
player... but the others all work fine.
<rooneg> and after hearing them all, i have two thinigs to say: first,
it must be really amusing hearing that stuff randomly
throughout the day in the office, and two, cmike spent far too
long on his ;-)
<sussman> rooneg: yours and jack's got corrupted
<sussman> cmpilato goofed when converting from mp3 to ogg
<sussman> he's gonna fix it, tho
<rooneg> cool
* rooneg considers filing a critical issue about the problem ;-)
<sussman> heh
<rooneg> obviously this will block any 1.0 release
<sussman> indeed.
-- #svn, Freenode
* rindolf tries to think what can cause the KDE 4 SNAFU on
his user.
<rindolf> And hopefully to avoid bissecting the KDE 4 config tree.
<Zuu> snafu... that wounds like a delicious cake :D
<Zuu> *sounds
<rindolf> Zuu: Situation Normal - All F****ed up.
<Zuu> :/
* Zuu gives the snafu cake to Dmage :D
<Zuu> Dmage, just eat the cake already
<Dmage> Zuu, are you hate my english? ;)
<Zuu> i hate your non-english
<Black_Phoenix> I english your hate
<Dmage> xD
<Zuu> Dmage, but i dont hate you! :D
<Black_Phoenix> and now I can do that
<Dmage> Zuu, learn russian then! :)
<Zuu> Hehe
<Zuu> Dmage, i think you'd hate my russion far more than i
would ever hate your english
<rindolf> Spasiva.
<Dmage> xD
<Dmage> learn 'Eto huinya!'
* Zuu steals the snafu cake back from Dmage and gives it
to rindolf instead
<Dmage> and apply everywhere
* rindolf eats the SNAFU cake
<Zuu> :D
* rindolf eats Zuu's Danish too.
<Zuu> Noooh!
* rindolf loves Zuu's Danish.
<rindolf> Yum yum.
<Zuu> tis mine!
<Zuu> My daaaanish :'(
<rindolf> My precioussssssssss!
<Zuu> tis gone :<
-- SNAFU Cake
-- ##programming, Freenode