試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

Mandriva Linux 2009.0のStepMania 3.9の動画背景の問題が解決

Mandriva Linux 2009.0のStepManiaのパッケージで動画背景が動作しない件について」ではシステムのFFmpegライブラリを用いる方法だとパッチを当ててもうまく動画背景が動作しなかった。ところが、「StepMania4(Subversion版)のビルドと動画背景サポートについて(2009/1/29現在)」ではソースツリーに対応するバージョンを使用することでバージョン4では動いているのを確認できたので、バージョン3.9でも同様にできないかどうかを試した結果、うまくいった。

  1. 使用するFFmpegのバージョンとそのパッチについて
  2. ビルド
    1. 準備からFFmpegのビルドまで
    2. ビルドしたFFmpegライブラリをStepManiaに組み込むための準備

使用するFFmpegのバージョンとそのパッチについて

http://web.archive.org/web/20081214194506/http://www.stepmania.com/wiki/Build_the_StepMania_Source_in_Linux
を見ると、StepManiaのバージョン3.9では、バージョン0.4.9-pre1を独自に修正したffmpeg-0.4.9-pre1-sm.tar.gz*1とGCC4向けパッチを用いればよいことが分かった。前者は上のURLからダウンロードでき、後者はサーバ上に無かったものの、Internet ArchiveのWayback Machine上に見つかった。

ビルド

FFmpegのライブラリは、システムのFFmpegライブラリとぶつからないようにする意味も含めて、本家版と同様に静的リンクする(StepManiaの実行ファイルに組み込む)ことにする。

準備からFFmpegのビルドまで

$ tar jxf [StepMania-3.9-src.tar.bz2の場所]
$ cd StepMania-3.9-src/
(ここで本体に対する他のパッチを当てる)
[StepMania-3.9-src]$ tar zxf [ffmpeg-0.4.9-pre1-sm.tar.gzの場所]
[StepMania-3.9-src]$ cd ffmpeg-0.4.9-pre1-sm/
[StepMania-3.9-src/ffmpeg-0.4.9-pre1-sm]$ patch -p1 < [ffmpeg-0.4.9-pre1-gcc4-1.patchの場所]
patching file libavcodec/ac3.h
patching file libavcodec/avcodec.h
patching file libavcodec/common.h
patching file libavcodec/i386/dsputil_mmx.c
[StepMania-3.9-src/ffmpeg-0.4.9-pre1-sm]$ ./configure --disable-ffserver --disable-ffplay
[StepMania-3.9-src/ffmpeg-0.4.9-pre1-sm]$ make

FFmpegのビルド完了後、静的リンクライブラリlibavformat/libavformat.alibavcodec/libavcodec.aが得られる。動的リンクする共有オブジェクト(.soファイル)も生成されるが、ここでは使用しない。

ビルドしたFFmpegライブラリをStepManiaに組み込むための準備
このままではStepMania本体のビルド時に検出もリンクもされないため、ビルドシステム*2の設定をいじくることにした。以下のパッチはFFmpegライブラリを「検出済み」とした上でヘッダファイルをffmpeg-0.4.9-pre1-sm/include/以下から探索し、先ほど場所を書いた2つの静的リンクライブラリを最後に組み込むようにするためのもの。
[任意]ファイル名: StepMania-3.9-ffmpeg-staticlink.patch

diff -ur StepMania-3.9-src.orig/configure.ac StepMania-3.9-src/configure.ac
--- StepMania-3.9-src.orig/configure.ac
+++ StepMania-3.9-src/configure.ac
@@ -159,38 +159,8 @@
 SM_AUDIO
 SM_TLS
 
-AC_SEARCH_LIBS(avcodec_init, [avcodec], have_libavcodec=yes,  have_libavcodec=no)
-AC_SEARCH_LIBS(guess_format, [avformat], have_libavformat=yes,  have_libavformat=no)
-
-if test "$have_libavcodec" = "yes"; then
-  AC_MSG_CHECKING([for libavcodec >= 0.4.9])
-  AC_TRY_RUN([
-      #include <ffmpeg/avcodec.h>
-      int main()
-      {
-	      return ( LIBAVCODEC_VERSION_INT < 0x000409 )? 1:0;
-      }
-      ],,have_libavcodec=no,)
-  AC_MSG_RESULT($have_libavcodec)
-fi
-
-if test "$have_libavformat" = "yes"; then
-  AC_MSG_CHECKING([for libavformat >= 0.4.9])
-  AC_TRY_RUN([
-      #include <ffmpeg/avformat.h>
-      int main()
-      {
-	      return ( LIBAVFORMAT_VERSION_INT < 0x000409 )? 1:0;
-      }
-      ],,have_libavformat=no,)
-  AC_MSG_RESULT($have_libavformat)
-fi
-
-have_ffmpeg=no
-if test "$have_libavformat" = "yes" -a "$have_libavcodec" = "yes"; then
-	have_ffmpeg=yes
-	AC_DEFINE(HAVE_FFMPEG, 1, [FMPEG support available])
-fi
+have_ffmpeg=yes
+AC_DEFINE(HAVE_FFMPEG, 1, [FMPEG support available])
 AM_CONDITIONAL(HAVE_FFMPEG, test "$have_ffmpeg" = "yes")
 
 SM_CHECK_CRASH_HANDLER
diff -ur StepMania-3.9-src.orig/src/Makefile.am StepMania-3.9-src/src/Makefile.am
--- StepMania-3.9-src.orig/src/Makefile.am
+++ StepMania-3.9-src/src/Makefile.am
@@ -301,7 +301,9 @@
 		  $(LUA_LIBS) \
 		  $(SDL_LIBS) \
 		  $(XLIBS) \
-		  $(srcdir)/libresample/libresample.a
+		  $(srcdir)/libresample/libresample.a \
+		  $(top_srcdir)/ffmpeg-0.4.9-pre1-sm/libavformat/libavformat.a \
+		  $(top_srcdir)/ffmpeg-0.4.9-pre1-sm/libavcodec/libavcodec.a
 
 stepmania_SOURCES = $(main_SOURCES)
 stepmania_LDADD = $(main_LDADD)
@@ -382,4 +384,4 @@
 		$(all_test_SOURCES) \
 		tests/test_threads.cpp
 
-INCLUDES = $(LUA_CFLAGS) $(SDL_CFLAGS)
+INCLUDES = $(LUA_CFLAGS) $(SDL_CFLAGS) -I$(top_srcdir)/ffmpeg-0.4.9-pre1-sm/include

ヘッダファイルの場所についてはソース側からffmpegディレクトリの中という指定があるため、正常に探索できるように場所を用意しておく。

[StepMania-3.9-src/ffmpeg-0.4.9-pre1-sm]$ mkdir include/ffmpeg -p
[StepMania-3.9-src/ffmpeg-0.4.9-pre1-sm]$ ln -s $(pwd)/*/*.h include/ffmpeg/

上のパッチをビルドシステムへ反映するにはautoreconfの実行が必要(本体へのパッチを反映させるためにも必要)。

[StepMania-3.9-src/ffmpeg-0.4.9-pre1-sm]$ cd ../
[StepMania-3.9-src]$ patch -p1 < [StepMania-3.9-ffmpeg-staticlink.patchの場所]
patching file configure.ac                                  
patching file src/Makefile.am
[StepMania-3.9-src]$ autoreconf

この後は普通にビルドすればOK。

[StepMania-3.9-src]$ ./configure
[StepMania-3.9-src]$ make

生成された実行ファイルで動作を確認したところ、動画背景は本家版同様、正常に動作した。
この修正を含んだMandriva Linux向けRPMパッケージを別館の配布ページに公開した。
(2014/10/12)配布ページは削除済み。
.specファイルのソースやパッチに関する部分を抜粋すると

Source0:	%{distname}-%{version}-src.tar.bz2
Source1:	ffmpeg-0.4.9-pre1-sm.tar.gz
Patch0:		StepMania-3.9-home.patch
Patch1:		StepMania-3.9-pkgdir.patch
Patch2:		StepMania-3.9-ffmpeg-staticlink.patch
Patch10:	010_all_alsa.patch
Patch30:	030_all_64bits.patch
Patch40:	040_all_alias.patch
Patch50:	050_all_gcc.patch
Patch60:	060_all_gettid.patch
Patch70:	070_all_lua.patch
Patch80:	080_all_sdl.patch
Patch90:	090_all_vorbis.patch
Patch100:	100_all_jpeg.patch
Patch110:	110_all_gcc43.patch
Patch500:	ffmpeg-0.4.9-pre1-gcc4-1.patch
(中略)
%prep
%setup -q -n %{distname}-%{version}-src -a 1
%patch0 -p1 -b .home
%patch1 -p1 -b .pkgdir
%patch2 -p1 -b .ffmpegstatic
%patch10 -p1 -b .alsa
%patch30 -p0 -b .64bits
%patch40 -p1 -b .alias
%patch50 -p0 -b .gcc
%patch60 -p1 -b .gettid
%patch70 -p1 -b .lua
%patch80 -p0 -b .sdl
%patch90 -p1 -b .vorbis
%patch100 -p1 -b .jpeg
%patch110 -p0 -b .gcc43
%{__autoreconf}
pushd ffmpeg-0.4.9-pre1-sm/
%patch500 -p1 -b .ffmpeggcc4
%{__mkdir_p} include/ffmpeg
%{__ln_s} $(pwd)/*/*.h include/ffmpeg/
popd


%build
pushd ffmpeg-0.4.9-pre1-sm/
CFLAGS="%{optflags} -O3" ./configure --disable-ffserver --disable-ffplay
%make
popd
%configure \
(以下Mandrivaのパッケージと同様)

のようになった。また、元々使用されているStepMania-3.9-pkgdir.patchについては直接configureスクリプトを編集していた部分をsrc/Makefile.amへ記述するようにした(autoreconfはどのみち実行することになるので、こちらに書いたほうが良い)。一番下の部分だけ編集してある。
[引用]ファイル名: StepMania-3.9-pkgdir.patch

--- StepMania-3.9-src/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp.pkgdir	2004-05-16 00:16:39.000000000 +0200
+++ StepMania-3.9-src/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp	2006-05-14 20:33:47.000000000 +0200
@@ -16,10 +16,17 @@
 {
 try {
 	ASSERT( Handle == NULL );
-	
+
+#ifdef PKG_LIB_DIR
+	Handle = dlopen( PKG_LIB_DIR "/" "GtkModule.so", RTLD_NOW );
+	if ( Handle == NULL ) {
+#endif	
 	Handle = dlopen( DirOfExecutable + "/" + "GtkModule.so", RTLD_NOW );
 	if( Handle == NULL )
 		RageException::ThrowNonfatal("dlopen(): %s", dlerror());
+#ifdef PKG_LIB_DIR
+	}
+#endif	
 
 	Module_Init = (INIT) dlsym(Handle, "Init");
 	if( !Module_Init )
--- StepMania-3.9-src/src/RageFileManager.cpp.pkgdir	2006-05-14 15:48:44.000000000 +0200
+++ StepMania-3.9-src/src/RageFileManager.cpp	2006-05-14 18:42:22.000000000 +0200
@@ -179,6 +179,10 @@
 		Root = DirOfExecutable;
 	if( Root == "" && !stat( InitialWorkingDirectory + "/Songs", &st ) && st.st_mode&S_IFDIR )
 		Root = InitialWorkingDirectory;
+#ifdef PKG_DATA_DIR
+	if( Root == "" && !stat( PKG_DATA_DIR "/Songs", &st ) && st.st_mode&S_IFDIR )
+		Root = PKG_DATA_DIR;
+#endif
 	if( Root == "" )
 		RageException::Throw( "Couldn't find \"Songs\"" );
 			
--- StepMania-3.9-src.orig/src/Makefile.am
+++ StepMania-3.9-src/src/Makefile.am
@@ -15,6 +15,7 @@
 
 AM_CXXFLAGS += $(XCFLAGS)
 
+DEFS=-DHAVE_CONFIG_H -DPKG_LIB_DIR=\"$(pkglibdir)\" -DPKG_DATA_DIR=\"$(pkgdatadir)\"
 LIBS += -lpthread
 
 $(srcdir)/libresample/libresample.a:

参考URL:

使用したバージョン:

*1:接尾辞「sm」は「StepMania」の略

*2:automakeやautoconfによる、広く使われているビルドシステム