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
Q: What's the difference between the 1950's and the 1980's?
A: In the 80's, a man walks into a drugstore and states loudly, "I'd
like some condoms," and then, leaning over the counter, whispers,
"and some cigarettes."
2. Journaling filesystems:
Imagine writing stuff on a lot of different notes and pieces of papers, etc.,
and then suddenly getting hit in the head and forgetting everything (call this
rebooting). You suddenly don't know which was the note you were in the middle
of writing, and you may end up finding a note saying "kill <name>" not knowing
you really meant to write "kill <name>'s jobs on the department's workstation,
because they are hogging all resources" before you got hit on the head. That's
why you should have a journal. Write everything that you do in there, one
entry after another, and only when you complete a whole note, cut it out of
the journal and keep it.
Also, when you go to the bathroom, don't forget to write down in the journal
about whether you're already done with #1, #2, or #3 (don't ask what #3
is...). That way, if you suddenly get hit on the head (say, the nice fake
plant over the toilet falls on you) you won't get embaraced, asking yourself
questions like "Oops, I don't remember if I did #2 or not, so should I reach
for some toilet paper or not?" If you had a journal, everything would have
been much simpler. Just look in there, and see what you've been up to.
-- Nadav Har'El
-- Hackers-IL Message No. 1,408 ( http://tech.groups.yahoo.com/group/hackers-il/message/1408 )