FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PyFFmpeg を MinGW64 でビルドする

PyFFmpeg は win32 向けに Python 2.6 用のバイナリが配布されてますが,64bit で利用したければ自前でモジュールをビルドする必要があります.本記事では MinGW64 を用いて,PyFFmpeg を Python 2.6 64bit 用にビルドする方法を説明します.

Keywords: python,pyffmpeg,MinGW64


PyFFmpeg は MSVC コンパイラではビルドできません.Windows でビルドするためには MinGW が必要です.MinGW64 をインストールされていない方は,当サイトの記事を参考にインストールを済ませてください.PyFFmpeg は Cython と numpy に依存しています.64bit用のライブラリパッケージはこちらで配布されているので,必要な方はインストールしてください.scipy との関係も考えると,numpy は MKL 版をインストールするのが良いと思います.

作業環境
Python 2.6.6 x64
Cython-0.14.1
numpy-1.6.0

1.ソースコード類の準備

(i) git でウェブからリポジトリを入手します.本記事では C:\temp 内に pyffmpeg という名前でリポジトリをクローンします.コマンドプロンプトで C:\temp に移動し,以下のコマンドを実行します.

git clone https://github.com/tranx/pyffmpeg.git pyffmpeg

(ii) FFmpeg の64bit用ライブラリを入手します.以下のものをダウンロードしてください.本記事で用いたバージョンがなくなった場合でも,
・avcodec-52
・avformat-52
・avutil-50
・swscale-0
が含まれていればビルド可能であると思います(検証はしてません).

http://ffmpeg.zeranoe.com/builds/win64/shared/ >> ffmpeg-git-1aeb88b-win64-shared.7z
http://ffmpeg.zeranoe.com/builds/win64/dev/ >> ffmpeg-git-1aeb88b-win64-dev.7z

(iii) コピーしてきたリポジトリ(今回の例では C:\temp\pyffmpeg)の中に,ffmpeg というディレクトリを作成します.
(iv) ダウンロードしたアーカイブを展開し,中身(bin や include など)を作成した ffmpeg 内に移動します.

2.pyffmpeg.pyx の修正

Cython 0.14 では __new__ の代わりに __cinit__ を使うようになりました.pyffmpeg.pyx の807,1841行目の __new__ を __cinit__ に書き換えてください.

807: def __cinit__(self):
808: pass

1841: def __cinit__(self,with_readahead=True,seek_before=4000):
1842: self.filename = None
1843: self.tracks=[]

3.ビルド

(i) setup.py を修正します.修正部分が多いので,私がビルドする際に用いた setup.py を付録に示します.コピーして上書きするなどして利用してください.

(ii) libmsvcr90.a を pyffmpeg ディレクトリ内に置きます.( ※ libmsvcr90.a の作成方法はこちらの記事で説明してあります)

(iii) python setup.py build --compiler=mingw32 を実行します.

以上でビルドは完了です.作成されたモジュールの利用には avcodec-52.dll や avutil-50.dll などが必要になるので気をつけてください.

付録 setup.py
import os
import numpy.distutils.misc_util as nd
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext


ffmpegpath = 'ffmpeg'

libs = ['avformat.dll', 'avcodec.dll', 'avutil.dll', 'swscale.dll']

incdir = [ os.path.join(ffmpegpath, 'include')] + nd.get_numpy_include_dirs()
libdir = [ os.path.join(ffmpegpath, 'lib') , '.']

with_numpy=True

ext_modules = [
Extension('pyffmpeg', ['pyffmpeg.pyx'],
include_dirs=incdir,
library_dirs=libdir,
libraries=libs),
Extension('audioqueue', ['audioqueue.pyx'],
include_dirs=incdir,
library_dirs=libdir,
libraries=libs),
Extension('pyffmpeg_numpybindings', ['pyffmpeg_numpybindings.pyx'],
include_dirs=incdir,
library_dirs=libdir,
libraries=libs)
]

setup(
name = 'pyffmpeg',
cmdclass = {'build_ext': build_ext},
version = "1.9.1",
ext_modules = ext_modules
)

スポンサーサイト

MinGW64でPython拡張モジュールを64bit向けにビルドする

Windowsでは,Python拡張モジュールは基本的にVC2008でビルドできるようになっていますが,まれにMinGWでないとビルドできないことがあります.本記事では64bit用のMinGW (Minimalist GNU for Windows) を導入し,PythonのC拡張モジュールをビルドする方法を説明します.

Keywords: python, mingw64, 拡張モジュール


作業環境
・Windows 7 Professional 64bit
・Python 2.6.6 x64 (公式インストーラを利用)

読者の環境にも Python 2.6 がインストールされていることを前提とします.

1.MinGWパッケージのインストール

(i) http://www.mingw.org/ の左サイドバーにある Downloads をクリックします.そして Automated MinGW Installer > mingw-get-inst > mingw-get-inst-20110802 と進み, mingw-get-inst-20110802.exe をクリックしてダウンロードします.
(ii) 以下に示すことに注意して MinGW をインストールします.
・Repository Catalogue で Use pre-packaged repository catalogue を選択
・インストール先はデフォルトの C:\MinGW
・Select Components で C++ CompilerMSYS Basic System を忘れずにチェック

(iii) Path に C:\MinGW\bin と C:\MinGW\msys\1.0\bin を追加します.
(iv) コマンドプロンプトを開いて,gcc --version を実行して gcc のバージョンが表示されれば成功です.

2.pexports のインストール

(i) コマンドプロンプトで mingw-get show pexports を実行すると pexports に関する情報が表示されるか確認します.インターネットにつながっていることが必要です.
(ii) (i)ができていれば,mingw-get install pexports を実行すると自動的に pexports がインストールされます.

3.MinGW64 のインストール

(i) http://sourceforge.net/projects/mingw-w64/files/ から Toolchains targetting Win64 > Personal Builds > sezero_20110510 と進み,mingw-w64-bin_x86_64_mingw_20110510_sezero.zipを選んでダウンロード.
(ii) 適当な場所に展開すると mingw64 というディレクトリができるので,これを C:\ に移動します.
(iii) Path に C:\mingw64\bin を追加します.必ず C:\MinGW\bin よりも前に追加してください.
(iv) 環境変数を以下のように設定します.
C_INCLUDE_PATH=C:\mingw64\include;C:\mingw64\x86_64-w64-mingw32\include;C:\mingw64\lib\gcc\x86_64-w64-mingw32\4.4.7\include
CPLUS_INCLUDE_PATH=C:\mingw64\include;C:\mingw64\include\c++\4.4.7;C:\mingw64\x86_64-w64-mingw32\include;C:\mingw64\lib\gcc\x86_64-w64-mingw32\4.4.7\include
LIBRARY_PATH=C:\mingw64\lib;C:\mingw64\lib64;C:\mingw64\x86_64-w64-mingw32\lib


4.Python拡張モジュールのビルド

作業ディレクトリを準備します.この記事では C:\temp\pysample とします.

4.1 ライブラリの準備

Python 2.6 の distutils は python26.dll と msvcr90.dll を必要とするので,これらの MinGW インポートライブラリを作成しなければなりません.

(i) C:\Windows\System32 内の python26.dll を作業ディレクトリにコピーします.
(ii) コマンドプロンプトを開いて作業ディレクトリに移動し,以下のコマンドを実行します.成功すれば libpython26.a が作成されます.
pexports python26.dll > python26.def
dlltool --dllname python26.dll --def python26.def --output-lib libpython26.a

(iii) 作成した libpython26.a を C:\Python26\libs にコピーします.
(iv) C:\Windows\winsxs\amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.21022.8_none_750b37ff97f4f68b 内の msvcr90.dll を作業ディレクトリにコピーします.
(v) defファイルを作成します.
pexports msvcr90.dll > msvcr90.def

(vi) 作成された msvcr90.def の304行目の _decode_pointer と,314行目の _encode_pointer の前にセミコロンを入れてコメントアウトします.
303: _daylight DATA
304: ;_decode_pointer
305: _difftime32
...
313: _ecvt_s
314: ;_encode_pointer
315: _encode_null

(vii) インポートライブラリを作成します.成功すれば libmsvcr90.a が作成されます.
dlltool --dllname msvcr90.dll --def msvcr90.def --output-lib libmsvcr90.a


4.2 modsupport.h の修正

C:\Python26\include の modsupport.h を開き,青字で示すように書き加えます.

099: #if SIZEOF_SIZE_T != SIZEOF_INT || defined(WIN64)
100: /* On a 64-bit system, rename the Py_InitModule4 so that 2.4
101: modules cannot get loaded into a 2.5 interpreter */
102: #define Py_InitModule4 Py_InitModule4_64
103: #endif


4.3 拡張モジュールのビルド

付録に添付する pysample.c,setup.py,test.py を作業ディレクトリにコピーし,コマンドプロンプトで
python setup.py build_ext --inplace --compiler=mingw32
を実行します.成功すれば pysample.pyd が作業ディレクトリに作成されます.test.py を実行し,"ECHO: hoge"と表示されれば完了です.

参考
Python v2.6 documentation - Python インタプリタの拡張と埋め込み
python - Issue 11722
64-bit Windows Biopython

付録 A pysample.c
#include <Python.h>

#include <stdio.h>
#include <stdlib.h>

static PyObject* pysample_echo(PyObject *self, PyObject *args)
{
const char *msg;

if(!PyArg_ParseTuple(args, "s", &msg)) return NULL;
fprintf(stdout, "ECHO: %s\n", msg);

Py_RETURN_NONE;
}

static PyMethodDef pysample_methods[] = {
{
"echo",
pysample_echo,
METH_VARARGS,
"echo given string."
},
{NULL, NULL, 0, NULL}
};

#ifdef __cplusplus
extern "C" {
#endif

PyMODINIT_FUNC initpysample(void)
{
(void)Py_InitModule("pysample", pysample_methods);
}

#ifdef __cplusplus
}
#endif


付録 B setup.py
from distutils.core import setup, Extension

setup(ext_modules=[
Extension('pysample',
sources=['pysample.c'],
include_dirs=[],
library_dirs=['.'],
libraries=[],
extra_compile_args=[],
extra_link_args=[])
]
)


付録 C test.py
import pysample
pysample.echo("hoge")

テーマ : プログラミング
ジャンル : コンピュータ

プロフィール

Ishida Akihiko

Author:Ishida Akihiko
FC2ブログへようこそ!

免責事項
当サイトに掲載する記事内容は,必ずしも正確性,信頼性,妥当性,有用性,完成度などを保証しません.記事の利用はすべて自己責任でお願いします.当サイトに掲載された内容によって発生したいかなる損害に対しても,管理人は一切の責任を負いかねます.
最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
アクセスカウンター
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。