2014年02月17日

FFmpegのビルド (2014/02/17)

FFmpeg(w32threads版)のビルド手順です。

MSYSとMinGWから準備する方は、1、2番の記事からお読みください。
MSYSとMinGWの準備ができている方は、3番の記事からお読みください。

1. MSYS環境のアップデート

2. MinGW環境のアップデート

FFmpegのDirectShow(dshow)を有効にするためには、mingwrtとw32apiの代わりに、MinGW-w64が必要です。
MinGW-w64を自分でビルドしてみたい方は、こちらを参考にしてください。
MinGW-w64のビルド (v3.1.0以降)

MinGW-w64を自分でビルドするのが面倒という方は、以下の記事を参照してください。
現在は、mingw-w64-v3系がメインですが、以下の記事では、mingw-w64-v1系をインストールします。
MinGW-w64 for win32 のインストール

FFmpegのconfigureと、その他のライブラリのconfigureでもpkg-configが必要なものがありますので、インストールしておいてください。
pkg-configのインストール


3. 個別のライブラリについて
以下のライブラリは、あらかじめインストールしておいてください。
この記事を書いた時点より新しくなっているものもありますので、それぞれの記事で確認してください。

あまり使用しないライブラリもありますので、必要なライブラリだけインストールして、それをconfigureオプションでenableにすれば良いです。

2016/03/25 追記
個別のライブラリに、Kvazaar HEVC encoderと、XZ Utilsを追加しました。
rev.78199(e07e88c)以降、libvo-aacencはサポートされなくなりました。

nasm-2.11
yasm-1.2.0
zlib-1.2.8
bzip2-1.0.6
libbluray-0.5.0
libcaca-0.99.beta18
libcdio-0.92
libcdio-paranoia-10.2+0.90+1
game-music-emu-0.6.0
gsm-1.0.13
libilbc-1.1.1
kvazaar
libmodplug-0.8.8.4
lame-3.99.5
OpenH264
openjpeg-1.5.1
opus-1.1
opencore-amr-0.1.3
vid.stab-0.98
vo-aacenc-0.1.3
vo-amrwbenc-0.1.3
libogg-1.3.1
aoTuV Beta6.03 (libvorbis-1.3.4パッチ)
libtheora-1.1.1
speex-1.2rc1
twolame-0.3.13
libsoxr-0.1.1
libvpx-v1.3.0
wavpack-4.70.0
libwebp-0.4.0
x264 (make fprofiled)
x265
xvidcore-1.4
xz-5.2.2

PolarSSLを使用する場合は、以下の記事を参照してください。
当サイトでは、PolarSSLを使用しています。
polarssl-1.3.4
rtmpdump-2.4 PolarSSL版

GnuTLSを、PolarSSLの代わりに使用する場合は、以下の記事を参照してください。
当サイトでは、以前はPolarSSLを使用していましたが、2015/08/16以降、GnuTLSを使用しています。
gmp-6.1.0
gnutls-3.4.10
rtmpdump-2.4 GnuTLS版

OpenSSLを使用する場合は、以下の記事を参照してください。
OpenSSLはGPL非互換なので、GnuTLSかPolarSSLをおすすめします。
openssl-1.0.1f
rtmpdump-2.4

字幕ファイルを読み込むためのライブラリlibassを追加する場合は、以下のライブラリが必要になります。
pkg-config_0.28-1_win32
libiconv-1.14
freetype-2.5.2
expat-2.1.0
fontconfig-2.11.0
fribidi-0.19.6
libass-0.10.2

FFplayをビルドする場合は、SDLが必要になります。
デフォルトでffplayはenableになっていますので、configureオプションに「--disable-ffplay」がある場合は削除してください。
SDL-1.2.15

SDLをインストールしていると、自動でSDLがenableになります。
SDLをインストールしていてもFFmpegでdisableにしたい場合は、configureオプションに「--disable-outdev=sdl」を追加してください。
「--disable-outdev=sdl」を付けてSDLがdisableになるのはFFmpegだけで、FFplayには影響ありません。

4. FFmpegのビルド
FFmpegは、以下の場所にあります。
http://ffmpeg.org/

ソースコードはGitで管理されています。
Gitをインストールして、MSYSから、以下のコマンドでソースコードを入手してください。
$ git clone git://source.ffmpeg.org/ffmpeg.git

または、
Get FFmpeg
http://ffmpeg.org/download.html
Extra repositoriesの、一番上のSnapshotのリンクからソースコードをダウンロードできます。
ファイルは、ffmpeg-HEAD-(Gitハッシュ値).tar.gz という形式になっていますので、そのファイル名に読み替えてください。
ダウンロードしたファイルは、tarで解凍できます。
$ tar xzf ffmpeg-HEAD-9125383.tar.gz

解凍したら、ソースコードのあるディレクトリに移動します。
$ cd ffmpeg-HEAD-9125383
Gitでソースコードをダウンロードした場合は、
$ cd ffmpeg

2012/04/13 以降、makeすると以下のようなエラーが出る場合があります。
library.mak:95: *** missing separator. Stop.

ダウンロード(git clone)済みのソースコードがある場合、一旦Makefileを全部削除して、改行コードをLFにして作成し直せば、エラーが出なくなります。
$ echo 'Makefile eol=lf' >> .gitattributes
$ find ./ -name 'Makefile' -print | xargs rm
$ git checkout -f

次に、configure、その他諸々の一括パッチを適用します。

2016/09/29 追記
パッチを更新しました。(rev.81760(2134499)〜)
ffmpeg-20160929.diff

FFmpeg rev.37209以降の更新で、「-flags2」で設定していたものが独立したオプションになり、特にx264関連の設定が大幅に変わりました。
以前の「-flags2」の設定も使用できるように、Revert用のパッチを作りましたので、必要であれば適用してください。

2016/12/08 追記
「-flags2」用のパッチを更新しました。(rev.82564(7289aa2d71)〜)
ffmpeg-global_opts-20161208.diff

$ patch -p1 < ffmpeg-20160929.diff
$ patch -p1 < ffmpeg-global_opts-20161208.diff

パッチを適用したら、configureを実行します。

2016/08/12 追記
configureオプションの「--disable-dxva2」を削除しました。

$ ./configure --enable-gpl --enable-version3 --enable-avisynth --enable-fontconfig --enable-libass --enable-libbluray --enable-libcaca --enable-libcdio --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libkvazaar --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-opengl --disable-outdev=sdl --enable-w32threads --disable-debug --pkg-config-flags=--static --extra-ldflags=-static --extra-cflags="-mtune=athlon64 -mfpmath=sse -msse" --optflags="-O2 -finline-functions"

配布用に、できる限りのライブラリをenableにしていますが、自分用の場合は必要なものだけenableにすれば良いと思います。
FFplay、FFprobeはデフォルトでenableになっていますので、不要な場合は、それぞれ「--disable-ffplay」「--disable-ffprobe」を追加してください。
FFserverは、MinGW環境に実装されていないincludeファイルなどがあり、configureオプションにかかわらずビルドできません。

debug symbolsはgdbなどでデバッグする時に必要になりますが、デバッグすることはほとんどないため「--disable-debug」を付けています。


最適化レベルは、以前は、
--enable-small 有りの場合 -Os
--enable-small 無しの場合 -O3
しか選択できませんでしたが、FFmpeg Git rev.30971(4b87a08)から、
--optflags
というオプションが追加され、最適化レベルを変えられるようになりました。

--enable-small 有りだと、バイナリのサイズは小さくなるが、エンコード速度が落ちる。
--enable-small 無しだと、エンコード速度は速いが、バイナリのサイズがでかくなる。
--enable-small 無しで、--optflags="-O2 -finline-functions" だと、バイナリサイズがあまり大きくならないわりに、--enable-small 無しの場合とエンコード速度が大して変わらない。

ということで、色々試した結果、以下のようにしました。
--enable-small 無し
--optflags="-O2 -finline-functions" 追加


最適化オプションは、PCの環境により以下のようにしています。
最適化無し版のconfigureオプションのみ、「--enable-memalign-hack」を追加しています。
これにより、Windows2000でも使えるようになるらしいです。
※あくまでも一例ですので、もっと凝ってみたい方は、gccのマニュアルなどを見て研究されると良いかもしれません。

最適化無し版
--extra-cflags="-march=i686 -mtune=generic" --enable-memalign-hack

Pentium4最適化版
--extra-cflags="-mtune=pentium4 -mfpmath=sse -msse"

Core2最適化版
--extra-cflags="-mtune=core2 -mfpmath=sse -msse"

Athlon64最適化版
--extra-cflags="-mtune=athlon64 -mfpmath=sse -msse"

Phenom最適化版
--extra-cflags="-mtune=amdfam10 -mfpmath=sse -msse"

FFmpegのconfigureオプションに、
--cpu=athlon64
などど追加すると、そのCPUに特化した最適化が実行されますので、ご自分の環境でしか使用しない場合は、試してみると良いかもしれません。

その他、Core2最適化版、Athlon64最適化版、Phenom最適化版のconfigureオプションに、--cpu=i686 を追加、Pentium4のconfigureオプションに、--cpu=pentium4 を追加しています。
configureの結果に以下のような違いがあります。

・「--cpu」オプション無し
CMOV enabled=no, CMOV is fast=no, EBX available=yes, EBP available=no
・「--cpu=i686」オプション追加
CMOV enabled=yes, CMOV is fast=yes, EBX available=yes, EBP available=yes
・「--cpu=pentium4」オプション追加
CMOV enabled=yes, CMOV is fast=no, EBX available=yes, EBP available=yes


問題なければ、以下のようなメッセージが出ます。
source pathはコンパイル環境により異なります。
思ったよりも時間がかかりますので、気長に待ちましょう。

configureのメッセージを見る

(長いので中略)
License: GPL version 3 or later
Creating config.mak, config.h, and doc/config.texi...

その後、
$ make

CPUに余力がある場合は、「-j」でパラレルmakeできます。
3パラの場合は、以下のように指定します。
あまり増やしすぎてもかえって効率が悪くなりますので、CPUによって適当な数値を見つけてください。
$ make -j3

ffmpeg.exe が出来ていれば完了です。


【補足】
自分用の場合は、再配布を考えなくても良いので、libfaac入りのFFmpegをビルドすることもできます。
現在は、libfaacより音質が良いと評判のfdk-aacがありますので、fdk-aacをおすすめします。

追加で、fdk-aacをコンパイル&インストールします。
fdk-aacのコンパイル&インストール

configureオプションの適当な所に、
--enable-nonfree
--enable-libfdk-aac
を追加します。

configureメッセージの、External libraries: に
libfdk-aac
が追加されていれば、後はmakeして完了です。

FFmpegのエンコードオプションで、
-acodec libfdk_aac
が使えるようになります。

当サイトで配布しているFFmpegは配布用のため、libfaac、libfdk-aacは無効にしています。


【更新履歴】を見る
posted by あべちん at 11:37 | Comment(29) | TrackBack(0) | FFmpegビルド
この記事へのコメント
管理人様、ご無沙汰しております。

昨年に仕上げたffmpegコンパイルガイドですが、アップデートしようかと考えて訪問したところ、ビックリする位更新がありました。

さて、つかぬことをお聞きしますが、ffmpegをconfigureするときに"x265 not found"というエラーで止まってしまうことはありませんか?

こちらでは数十回トライして1回だけはconfigureが通りmakeもできたのですが、残りは全てエラーでした。

Macでffmpegをコンパイルしている人を見つけて確認したところ、その人はうまく行っていたけど、今日再現実験をしたら"x265 not found"が出たそうです。

見当違いでもいいからと考え、現在x265-develのメーリングリストに加入して、問題提起しました。

MinGW環境では、このようなエラーはないのかと思い書き込みました。
Posted by 桃源老師 at 2014年04月21日 03:14
上記コメントですが、Macでffmpegをコンパイルしている人が解決してくれました。

「ffmpegとx265をリンクするためには " -lstdc++"がコンパイラフラッグとして必要だが、ffmpegがx265のCFLAGをリクエストする際に、それはpkg-config経由で用意されていない。」

ことが原因でした。

x265.pcを次のように編集すると、問題は解決します。
--- a/x265.pc 2014-04-16 14:50:20.000000000 +0900
+++ b/x265.pc 2014-04-21 10:54:32.000000000 +0900
@@ -6,6 +6,6 @@
Name: x265
Description: H.265/HEVC video encoder
Version: 0.9
-Libs: -L${libdir} -lx265
+Libs: -L${libdir} -lx265 -lstdc++

原因から類推するにMinGW環境でも起こりえるような気がしますが、取りあえず情報までです。


P.S.
x265のパッチはMac(Unix)/MinGWどちらでも適用されるものでしょうか?
Posted by 桃源老師 at 2014年04月21日 14:10
桃源老師さん、こんにちは。管理人です。
お久しぶりです。

pkg-configについて、説明不足でした。

-lstdc++は、x265.pcのLibs.privateセクションに入っています。

Libs.privateを有効にするには、pkg-configのオプションに「--static」を付けて、
pkg-config --libs --static /mingw/lib/pkgconfig/x265.pc
などとしなければいけません。

ffmpegのconfigureの中で、デフォルトでは「--static」が付いていないので、ffmpeg-2014XXXX.diffパッチでconfigureファイルを修正しています。

configureオプションのどこかに、
--pkg-config-flags=--static
と付け加えれば、configureファイルを修正しなくても、同じことができます。

もしかして、Macだと、-lstdc++がLibs.privateにも入っていなかったりするのでしょうか。

x265の方のパッチは、いつまで経っても修正される気配がないので、修正しなくても問題ない箇所なのかもしれません。
Posted by あべちん at 2014年04月22日 23:52
なるほど、そういうことでしたか。

管理人さんはffmpegのconfigureスクリプトの方で対応されていたのですね。

x265開発チームと話し合った結果、-lstdc++をLibsに加えるのは正しくないと説明されました。
管理人さんも書かれている通り、--pkg-config-flags=--staticを付け加えろと言われ、これで問題がないことを確認しました。

Mac (llvm) の場合は-lstdc++ではなく-lc++がLibs.privateに入っています。--staticを付け加えることで、これがコンパイラフラグとして呼び出されるようです。
(実のところ、僕はこの辺が良く分かってませんが…。(^ ^;)

あ、そうだ。MacだとLibs.privateにlibclang_rt.osx.aというファイルが絶対パスで記述され、頭に-lがついてリンクされるようになっていますが、これはx265のバグと認定されました。
昨晩mecurialで落とした分から、頭に着いていた-lが削除されていました。
これは、もしかして管理人さんがx265のところでsedコマンドで処理しているリンクする必要のないファイルなのではないかと想像します。
お時間のある時に確認してみてください。

x265のパッチは、うーん。分からない人間が間に入っても何ですもんね。x265-develに参加しているので代わりに投稿してみようかと思ったんですが…。止めておいた方が良いでしょうか?
Posted by 桃源老師 at 2014年04月24日 00:48
(実のところ、僕はこの辺が良く分かってませんが…。(^ ^;)

というのは、おかしいですね。管理人さんの説明されたところまでは理解しています。

スミマセン。
Posted by 桃源老師 at 2014年04月24日 00:57
桃源老師さん

x265-develに参加してるとは、すごいですね!

バグ報告してみたいと思うこともあるのですが、英語が得意でないので、ためらってしまいます。

x265のパッチは、x264から流用しているファイル
source/common/x86/mc-a.asm
の中で、"x264_"というprefixを削除し忘れている箇所が2つあるので、そこを削除しているだけのものです。

あと、x265.pcのLibs.privateは、

Libs.private: -lstdc++ -lmingw32 -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lmoldname -lmingwex -lmsvcrt

となっており、-lstdc++以外は特に明示しなくてもffmpegのビルドには影響がなかったので、削除しています。

現在は修正されていますが、以前は、不要な-lpthreadが入っていたので、ついでに他のも削除しようと思ったのが発端だったような気がします。

今は、特に修正する必要はないかもしれません。
Posted by あべちん at 2014年04月25日 19:17
追記です。

なんで、
--pkg-config-flags=--static
を使わないでconfigureを修正したんだろうかと、自分でも記憶があいまいだったのですが、今年の3/12に新しく追加されたオプションでした。
Posted by あべちん at 2014年04月25日 19:37
全然すごくないんです。ffmpegみたいにユーザー向けのメーリングリストがないので、バカ丸出し、恥を忍んで参加しました。

"x264_"のプレフィックスは、メールしたらすぐに修正されたようです。削除ではなく"x265_"に置き換わっているようです。

x265.pcのLibs.privateはMinGWだと、随分沢山のファイルがリンクされているのですね。
MacとはCMakeの部分が異なるのかもですね。失礼しました。

--pkg-config-flags=--staticは新しいオプションなのですね。ffmpegのメーリングリストで紹介したら、pkg_config='pkg-config --static'の方が良く知られているみたいなことを言われました。
Posted by 桃源老師 at 2014年04月28日 23:42
桃源老師さん

さっそく"x265_"に修正されてると思ったら、報告してくださったんですね。
ありがとうございました。

私ももっと英語を勉強して、開発者さんたちと直接やりとりできるようになりたいです。

あと、このオプション
--pkg_config='pkg-config --static'
pkg-configのパスを指定したりするのに使うんだと思っていましたが、オプションを追加するのにも使えるとは知りませんでした。

いろいろと参考になりました。
Posted by あべちん at 2014年05月03日 12:40
こちらこそ。

いろいろ丁寧にコメントしてくださってありがとうございました。
Posted by 桃源老師 at 2014年05月06日 06:32
あべちんさん、ご無沙汰しております。

今回の自分のffmpegコンパイルガイド改訂で、libmodplugを組み込むことにしました。
その際、ffmpeg configureスクリプトであべちんさんは、-lstdc++をenabled libmodplugの行に追加されていますが、この件についてffmpegメーリングリストに投げました。
結果、configureスクリプトが修正され

enabled libmodplug && require_pkg_config libmodplug libmodplug/modplug.h ModPlug_Load

になりましたのでお知らせします。

あと、libwebpは0.4.1ではダメですね。0.4.0を使ったら、あっさりOKでした。
Posted by 桃源老師 at 2014年09月01日 18:12
桃源老師さん、こんにちは。管理人です。

情報ありがとうございます。

libmodplugの所がrequire_pkg_configに修正されたバージョンでconfigureしてみたところ、config.logに
undefined reference to _imp__...
というエラーが出てstopしてしまいました。

libmodplugの方を修正すれば良いのですが、とりあえずffmpegのconfigureを元にもどしてしみました。

逆に、libwebpは0.4.1でも問題ありませんでした。

ビルド環境によって違うのかもしれませんね。
Posted by あべちん at 2014年09月09日 02:13
管理人さん、こんばんは。桃源老師です。

libmodplugの件ですが、メーリングリストに投げてみますので、僕にメールを戴けますか? 以下の情報を含めてください。

MinGWのどんな環境か?
config.log
configureスクリプトが停止した時のエラー内容。
configureスクリプトに与えたオプションの内容。

*メーリングリストでは、編集しない、完全なコマンドの内容が要求されます。よろしくお願いします。


libwebpは分かりませんね。不思議です。使い方も分かんないのでいいかにゃ? f(^^;
Posted by 桃源老師 at 2014年09月09日 23:12
私の環境でも同じくエラーになりました。
原因は、libmodplugのデフォルトのヘッダだとDLLへのリンクとして判断され、スタティックリンクでないためエラーとなります。
libmodplugをスタティックライブラリとして利用しているために起こる現象ですね。
libmodplugのヘッダを修正すれば、configureでrequire_pkg_configとなっていてもエラーが出ないですむようにはなります。
具体的にはmodplug.hでMODPLUG_STATICを定義すればOKです。
私はこれでエラーを回避させてます。
Posted by einguste at 2014年09月10日 00:36
ffmpegでlibmodplugをshared libraryとして使うかstatic libraryとして使うかの選択の問題なのですよね。
現状、libmodplugのヘッダがshared library(DLL)として使うことをデフォルトとしていて、static libraryとして使う際にはヘッダでMODPLUG_STATICを宣言する必要があります。
なのでconfigureを変更するか、libmodplugのヘッダに修正を加えるかのどちらかを選ぶことになるかと思います。
Posted by einguste at 2014年09月10日 00:49
ffmpeg/libavformat/libmodplug.c
でも
#define MODPLUG_STATIC
を宣言しています。
これを考えると、ffmpegではスタティックライブラリとして使うことを前提にしているのかなぁと思ったのですが、ffmpeg-2.2.7ではその宣言がなくなっていたんですよね。迷走している感じ。
個人的には、libmodplugをスタティックライブラリとして使うのだから、libmodplugを修正するのが、正攻法かなぁと思ってます。
Posted by einguste at 2014年09月10日 01:19
eingusteさま、はじめまして。

僕の環境はMac OS Xなのですが、現在Windows(MinGW?)の方がエラーになっている状態のffmpegで正常にコンパイルできています。
libmodplugのconfigureオプションは、こちらのサイトと同じです。

Macで正常でWinでエラーになる理由が、ご指摘の#define MODPLUG_STATICをmodplug.hで定義することなのでしょうか?(済みません、言い方がうまくないです)

ちなみに、今あるffmpegのgitクローンでは、ffmpeg/libavformat/libmodplug.cに#define MODPLUG_STATICが宣言されています。
Posted by 桃源老師 at 2014年09月10日 06:49
桃源老師 さま、はじめまして。

>Macで正常でWinでエラーになる理由が、ご指摘の#define MODPLUG_STATICをmodplug.hで定義することなのでしょうか?

逆です。エラーにならないように定義します。
modplug.hではWindows用DLLをデフォルトで使用する設定になっています。それをスタティックライブラリとして使用するのに、ヘッダでMODPLUG_STATICを宣言します。
ffmpeg/libavformat/libmodplug.cに#define MODPLUG_STATICが宣言されていることが、スタティックに使用するということです。

WindowsのDLL関連の固有の問題というしかありません。関数名がDLLとスタティックライブラリとでは異なっていることが原因です。

require_pkg_configでは、その宣言をしないでコンパイルされるのでDLLの関数名が見つからずエラーとなるのです。
MacOSXではスタティックでもシェアードでも名前が同じなのではないでしょうか?
それで挙動が異なるのではないかと推測いたします。
Posted by einguste at 2014年09月10日 07:19
上記の問題ですが、ヘッダを修正する以外にも、
/usr/local/lib/pkgconfig/libmodplug.pc
を修正して、-DMODPLUG_STATICを追加することで、対応できることに気がつきました。具体的には、
Cflags: -I${includedir} -DMODPLUG_STATIC
とします。
どちらにせよ、libmodplug側で修正が必要なことには変わりありませんね。
どちらがスマートかは判断しかねますが、一応ご報告まで。
Posted by einguste at 2014年09月10日 10:16
eingusteさま、こんばんは。

ご指摘の内容をmodplugのメンテナーにメールしようとして、はたと詰まりました。
繰り返しになって申し訳ありませんが、もう一度確認させてください。(理解が遅くてすみません)

modplug.hでのMODPLUG_STATICの宣言追加は、modplugをSharedライブラリで使うケースには影響はないのでしょうか?

あるいは、libmodplug.pcに-DMODPLUG_STATICを追加するのも、同じようにSharedライブラリで使うケースには影響はないのでしょうか?

そんなのはメンテナーに考えて貰えば良いのかも知れませんが、ちょっと気になりました。

個人的には、modplugのconfigureスクリプトのオプションで使い分けができれば良いように思います。

現行のmodplugのconfigureオプションである「./configure --prefix=/mingw --disable-shared --enable-static」では、ffmpegのconfigureスクリプトのエラーが避けられないのですよね?

そうそう、このエラーがlibmodplug not foundなのか、他のエラーなのかどうかも伺っていませんでした。
Posted by 桃源老師 at 2014年09月11日 00:25
static宣言すれば、sharedとしての利用には影響は出ます。staticオンリーとしての使い方になるからです。

エラーは、次のような感じです。

check_pkg_config libmodplug libmodplug/modplug.h ModPlug_Load
pkg-config --exists --print-errors libmodplug
check_func_headers libmodplug/modplug.h ModPlug_Load -ID:/MinGW6/msys/1.0/local/include -LD:/MinGW6/msys/1.0/local/lib -lmodplug -lstdc++ -lm
check_ld cc -ID:/MinGW6/msys/1.0/local/include -LD:/MinGW6/msys/1.0/local/lib -lmodplug -lstdc++ -lm
check_cc -ID:/MinGW6/msys/1.0/local/include -LD:/MinGW6/msys/1.0/local/lib
BEGIN /tmp/ffconf.MDykmaQK.c
1 #include <libmodplug/modplug.h>
2 long check_ModPlug_Load(void) { return (long) ModPlug_Load; }
3 int main(void) { return 0; }
END /tmp/ffconf.MDykmaQK.c
gcc -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1 -D__printf__=__gnu_printf__ -std=c99 -fomit-frame-pointer -ID:/MinGW6/msys/1.0/local/include -LD:/MinGW6/msys/1.0/local/lib -c -o /tmp/ffconf.VYCDiWPi.o /tmp/ffconf.MDykmaQK.c
gcc -static -Wl,--nxcompat -Wl,--dynamicbase -Wl,--as-needed -ID:/MinGW6/msys/1.0/local/include -LD:/MinGW6/msys/1.0/local/lib -o /tmp/ffconf.JwUOdPmk.exe /tmp/ffconf.VYCDiWPi.o -lmodplug -lstdc++ -lm -lm -lz -lpsapi -ladvapi32 -lshell32
C:/Users/augus/AppData/Local/Temp/ffconf.VYCDiWPi.o:ffconf.MDykmaQK.c:(.text+0x1): undefined reference to `_imp__ModPlug_Load'
collect2.exe: error: ld returned 1 exit status
ERROR: libmodplug not found
Posted by einguste at 2014年09月11日 01:42
eingusteさん、桃源老師さん
いろいろとありがとうございます。
横入り失礼します。

とりあえず分かっていることは、

DLL作成時、__declspec(dllexport)を関数の前に付ける。
DLLから呼び出す時、__declspec(dllimport)を関数の前に付ける。
スタティックライブラリの時は、どちらも付けない。
ということを、modplug.hのMODPLUG_EXPORTマクロで切り替えています。

MODPLUG_STATICマクロを定義していないと、__declspec(dllimport)が付けられる条件になっており、`_imp__関数名'という形で呼び出されるため、undefined referenceになってしまいます。

要は、スタティックライブラリをリンクする場合、__declspec(dllimport)が付かないようにすればよいので、解決策は何通りか考えられると思います。

ffmpegのconfigureオプションで、
--extra-cflags=-DMODPLUG_STATIC
を追加してもOKでした。

libcaca、twolame、openjpegでも同じような問題があるのですが、私の場合は、各ライブラリのヘッダファイルを修正して、MinGW環境の時は__declspec(dllimport)が付かないようにしています。

これが正解かどうかは分かりませんが、ffmpegをビルドすることが目的なので、とりあえず良しとしています。

あと、エラーメッセージやログなどはコメント欄が長くなってしまいますので、pastebinなどを利用していただけると助かります。
Posted by あべちん at 2014年09月11日 03:38
eingusteさま、こんばんは。

エラーの内容を拝見しました。概ね、僕が最初にffmpegにlibmodplugを組み込もうとした時に出たエラーに似ています。

それで思い出したのですが、ffmpegを修正してもらった時、configureオプションに「--pkg-config-flags=--static」をつけてね!! と言われていたのを忘れていました。

なので、
「./configure --enable-libmodplug --pkg-config-flags=--static」
または
「./configure --pkg_config='pkg-config --static' --enable-libmodplug」
というオプションでffmpegをconfigureしても「ERROR: libmodplug not found」が発生するかどうかを確認して戴けますでしょうか?
Posted by 桃源老師 at 2014年09月11日 03:59
staticオプションをつけて実行した結果です。なのでエラーは同じです。関数名の最初に_imp__というのがつくのがDLLで呼び出す際の関数名なのです。
管理人さんが、

ffmpegのconfigureオプションで、
--extra-cflags=-DMODPLUG_STATIC
を追加してもOKでした。

とのことでしたので、Windows環境での解決策としては、出揃った感じがあります。管理人さま、ffmpeg側のconfigureオプションでも解決できるんですね^^

どの解決法がスマートなのかは判断しかねますが、libmodplugをスタティックライブラリしか作成しない選択をしているので、私はmodplag.hヘッダを修正してエラー回避したいと思います。
Posted by einguste at 2014年09月11日 06:13
一応、
./configure --pkg_config='pkg-config --static' --enable-libmodplug
でのエラーはこんな感じです。
http://pastebin.com/Dy3Gu1Fj

同じエラーで止まっているのがお分かりいただけるでしょうか?
Posted by einguste at 2014年09月11日 08:26
eingusteさま、管理人さま、おはようございます。

やっとですが、Windows側で何らかの対策が必要なことは理解しました。

libmodplugのメンテナーに連絡を取るのは止めようと思います。理由は他にも対応が必要なライブラリがある様子だからです。

ffmpegメーリングリストでrequire_pkg_configに変更される際にWindowsの方から異論が出なかったのですが、新たに必要になった対策はどうやって伝えれば良いのか悩んでいます。
あるいは、ffmpegの変更をキャンセルして貰った方が皆さんにとって幸せなのでしょうか?
Posted by 桃源老師 at 2014年09月11日 08:46
require_pkg_configへの変更は他のPlatformで有効、汎用的な変更だと思うので、変更されたままで構わないと思いますよ。
Windowsだけの問題でしょうから。
それに変更前のrequireが問題なかったのは、ヘッダの存在確認と関数の確認が別個に分かれていて、たまたま関数名がスタティックリンクの関数名と同じになってたからです。それにどちらにせよライブラリの追加修正が必要になりますよね。
個人的には今のまま(require_pkg_config)でよろしいかと思います。
問題あっても、メーリングリストやconfig.logからも解決はできますしね。
Posted by einguste at 2014年09月11日 09:13
みなさま、こんにちは。

ffmpegメーリングリストのlibmodplugに関する部分が変更されたスレッドにWindowsでの暫定対策を書き込みました。
今のところ、文句、クレームはありません。
libmodplugに関する変更もそのまま維持されるようです。(多分…もし動きがあれば再度報告します)

eingusteさん、メーリングリストでの援護射撃ありがとうございました。
Posted by 桃源老師 at 2014年09月13日 15:56
桃源老師さま

>eingusteさん、メーリングリストでの援護射撃ありがとうございました。

いえいえ、どうしたしまして。
援護射撃になってるか分かりませんが^^;;
Posted by einguste at 2014年09月14日 00:37
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/87476810
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック