連絡先 トップに戻る 最初に戻る 前に戻る 次へ進む
$Date: 2017-05-06 22:21:48 +0900 (2017/05/06 (土)) $
$Revision: 1117 $

Python binding をコンパイルする方法 (VC6)

概要

Subversion の Python binding をWindows 上でコンパイルする方法を簡単に 説明します。

以下の手順を既に行っていることを前提としています。

  1. 最小の構成でコンパイルする (VC6)

準備

必要なファイルの入手

下準備

以下のような感じでファイルを置くとして以後の説明をする。
│
├─common
│   │
│   ├─db4-win32
│   ├─openssl-0.9.8d
│   ├─httpd-2.2.3
│   ├─neon-0.26.2
│   └─zlib-1.2.3
│
└─trunk (subversion のソースコード)
      │
      ├─INSTALL
      │  ... (中略) ...
      └─gen-make.py
c:\
 │
 └─swigwin-1.3.31

Visual C++ 6 の設定

python.exe のディレクトリパスを設定する
  1. Visual C++ のメニューから [ツール] - [オプション]を選ぶ
  2. [ディレクトリ] タブに移動する。
  3. [表示するディレクトリ] で[実行可能ファイル]を選ぶ
  4. C:\Python24 (python.exe のあるディレクトリ)を追加する
  5. [表示するディレクトリ] で[インクルードファイル]を選ぶ
  6. C:\Python24\include (python関連のヘッダファイルのあるディレクトリ)を追加する
  7. [表示するディレクトリ] で[ライブラリファイル]を選ぶ
  8. C:\Python24\libs (python関連のライブラリファイルのあるディレクトリ)を追加する

apache 2.2.x を使用する場合の準備

C:\Python25\include\pyconfig.h に以下のような定義があります。 この定義をコメントアウトします。
/* Define to `int' if <sys/types.h> doesn't define.  */
#if _MSC_VER + 0 >= 1300
/* VC.NET typedefs socklen_t in ws2tcpip.h. */
#else
#define socklen_t int
#endif
変更後
#if 0
/* Define to `int' if <sys/types.h> doesn't define.  */
#if _MSC_VER + 0 >= 1300
/* VC.NET typedefs socklen_t in ws2tcpip.h. */
#else
#define socklen_t int
#endif
#endif
上記の作業をしないと以下のコンパイルエラーになります。
-------------------構成: libsvn_swig_py - Win32 Release--------------------
コンパイル中...
swigutil_py.c
C:\Python25\include\pyconfig.h(42) : warning C4005: '_CRT_SECURE_NO_DEPRECATE' : マクロが再定義されました。
        unknown(0) : '_CRT_SECURE_NO_DEPRECATE' の前の定義を確認してください
C:\Python25\include\pyconfig.h(43) : warning C4005: '_CRT_NONSTDC_NO_DEPRECATE' : マクロが再定義されました。
        unknown(0) : '_CRT_NONSTDC_NO_DEPRECATE' の前の定義を確認してください
C:\Program Files\Microsoft SDK\include\ws2tcpip.h(593) : error C2632: 'int' と 'int' の 2 つの型指定子のあいだにコードがありません。
C:\Program Files\Microsoft SDK\include\ws2tcpip.h(593) : warning C4091: 空白の宣言が見つかりました。
cl.exe の実行エラー

__SWIG_PYTHON__ - エラー 1、警告 72
VC 6.0 では _MSC_VER の値は 1200 です。 C:\Program Files\Microsoft SDK\include\ws2tcpip.h で 以下のように定義されています。
typedef int socklen_t;
リンク

プロジェクトファイルの作成

以下のコマンドを subversion のソースコードのルートで実行する (見やすくするため改行していますが、実際には1行で入力します。)
c:\...\trunk> python gen-make.py -t dsp 
	--with-openssl=..\common\openssl-0.9.8d
	--with-swig=C:\swigwin-1.3.31 ←絶対パスで指定する
	--with-neon=..\common\neon-0.26.2 
	--with-zlib=..\common\zlib-1.2.3 
	--with-berkeley-db=..\common\db4-win32
	--with-httpd=..\common\httpd-2.2.3

Python binding のコンパイル

subversion_msvc.dsw を VC6 で開いて __SWIG_PYTHON__ の 構成を選択して、Release の構成のみをビルドする。

コマンドラインから行う場合

msdev subversion_msvc.dsw /MAKE "__SWIG_PYTHON__ - Win32 Release"

デバッグ版をコンパイルする場合、通常のバイナリ版の Python を使用した場合 python24_d.lib が存在しないので以下のエラーになります。

--------------------構成: libsvn_swig_py - Win32 Debug--------------------
リンク中...
LINK : fatal error LNK1104: ファイル "python24_d.lib" を開けません。
link.exe の実行エラー

__SWIG_PYTHON__ - エラー 1、警告 0

Python binding のインストール (for Python 2.4)

Subversion ソースツリーのルートで以下のコマンドを実行して必要なファイルをコピーする。 バッチファイルを作成しておくと便利です。 ( C:\Python24 以下に Python がインストールされている場合 )
c:\...\trunk> mkdir C:\Python24\Lib\site-packages\svn
c:\...\trunk> mkdir C:\Python24\Lib\site-packages\libsvn
c:\...\trunk> copy /Y subversion\bindings\swig\python\svn\*.py      C:\Python24\Lib\site-packages\svn
c:\...\trunk> copy /Y subversion\bindings\swig\python\*.py          C:\Python24\Lib\site-packages\libsvn
c:\...\trunk> copy /Y Release\subversion\bindings\swig\python\*.dll C:\Python24\Lib\site-packages\libsvn

libsvn_swig_py-1.dll をスクリプトと同じディレクトリに コピーするか、パスの通ったディレクトリにコピーする。 「libsvn_swig_py が見つからない」

Python binding のインストール (for Python 2.5)

Python 2.5 の Windows版 では dll の拡張子を pyd にする必要があるようです。
c:\...\trunk> mkdir C:\Python25\Lib\site-packages\svn
c:\...\trunk> mkdir C:\Python25\Lib\site-packages\libsvn
c:\...\trunk> copy /Y subversion\bindings\swig\python\svn\*.py      C:\Python25\Lib\site-packages\svn
c:\...\trunk> copy /Y subversion\bindings\swig\python\*.py          C:\Python25\Lib\site-packages\libsvn
c:\...\trunk> copy /Y Release\subversion\bindings\swig\python\*.dll C:\Python25\Lib\site-packages\libsvn

c:\...\trunk> cd C:\Python25\Lib\site-packages\libsvn
C:\Python25\Lib\site-packages\libsvn> move _client.dll _client.pyd
C:\Python25\Lib\site-packages\libsvn> move _core.dll   _core.pyd
C:\Python25\Lib\site-packages\libsvn> move _delta.dll  _delta.pyd
C:\Python25\Lib\site-packages\libsvn> move _fs.dll     _fs.pyd
C:\Python25\Lib\site-packages\libsvn> move _ra.dll     _ra.pyd
C:\Python25\Lib\site-packages\libsvn> move _repos.dll  _repos.pyd
C:\Python25\Lib\site-packages\libsvn> move _wc.dll     _wc.pyd

拡張子を dll から pyd に変更し忘れると以下のエラーになります。 ImportError: No module named _fs

libsvn_swig_py-1.dll をスクリプトと同じディレクトリに コピーするか、パスの通ったディレクトリにコピーする。 「libsvn_swig_py が見つからない」

リンク

python のインストールディレクトリの構成

カッコの中は Python 2.5 の場合
C:\Python24 (Python25)
     └─Lib
         └─site-packages
             │
             ├─libsvn
             │   │
             │   ├─__init__.py
             │   ├─__init__.pyc
             │   ├─_client.dll (_client.pyd)
             │   ├─_core.dll   (_core.pyd  )
             │   ├─_delta.dll  (_delta.pyd )
             │   ├─_fs.dll     (_fs.pyd    )
             │   ├─_ra.dll     (_ra.pyd    )
             │   ├─_repos.dll  (_repos.pyd )
             │   ├─_wc.dll     (_wc.pyd    )
             │   ├─client.py
             │   ├─core.py
             │   ├─core.pyc
             │   ├─delta.py
             │   ├─delta.pyc
             │   ├─fs.py
             │   ├─fs.pyc
             │   ├─ra.py
             │   ├─repos.py
             │   ├─repos.pyc
             │   └─wc.py
             │
             ├─svn
             │   │
             │   ├─__init__.py
             │   ├─__init__.pyc
             │   ├─client.py
             │   ├─core.py
             │   ├─core.pyc
             │   ├─delta.py
             │   ├─delta.pyc
             │   ├─fs.py
             │   ├─fs.pyc
             │   ├─ra.py
             │   ├─repos.py
             │   ├─repos.pyc
             │   └─wc.py
             │
             └─README.txt

実行確認

Subversion Book に載っているサンプルスクリプトを使用します。このファイルを test.py の名前で保存して、以下のように実行します。
svnadmin create test
test.py test
スクリプト
#!/usr/bin/python

"""Crawl a repository, printing versioned object path names."""

import sys
import os.path
import svn.fs, svn.core, svn.repos

def crawl_filesystem_dir(root, directory, pool):
    """Recursively crawl DIRECTORY under ROOT in the filesystem, and return
    a list of all the paths at or below DIRECTORY.  Use POOL for all 
    allocations."""

    # Print the name of this path.
    print directory + "/"
    
    # Get the directory entries for DIRECTORY.
    entries = svn.fs.svn_fs_dir_entries(root, directory, pool)

    # Use an iteration subpool.
    subpool = svn.core.svn_pool_create(pool)

    # Loop over the entries.
    names = entries.keys()
    for name in names:
        # Clear the iteration subpool.
        svn.core.svn_pool_clear(subpool)

        # Calculate the entry's full path.
        full_path = directory + '/' + name

        # If the entry is a directory, recurse.  The recursion will return
        # a list with the entry and all its children, which we will add to
        # our running list of paths.
        if svn.fs.svn_fs_is_dir(root, full_path, subpool):
            crawl_filesystem_dir(root, full_path, subpool)
        else:
            # Else it's a file, so print its path here.
            print full_path

    # Destroy the iteration subpool.
    svn.core.svn_pool_destroy(subpool)

def crawl_youngest(pool, repos_path):
    """Open the repository at REPOS_PATH, and recursively crawl its
    youngest revision."""
    
    # Open the repository at REPOS_PATH, and get a reference to its
    # versioning filesystem.
    repos_obj = svn.repos.svn_repos_open(repos_path, pool)
    fs_obj = svn.repos.svn_repos_fs(repos_obj)

    # Query the current youngest revision.
    youngest_rev = svn.fs.svn_fs_youngest_rev(fs_obj, pool)
    
    # Open a root object representing the youngest (HEAD) revision.
    root_obj = svn.fs.svn_fs_revision_root(fs_obj, youngest_rev, pool)

    # Do the recursive crawl.
    crawl_filesystem_dir(root_obj, "", pool)
    
if __name__ == "__main__":
    # Check for sane usage.
    if len(sys.argv) != 2:
        sys.stderr.write("Usage: %s REPOS_PATH\n"
                         % (os.path.basename(sys.argv[0])))
        sys.exit(1)

    # Call the app-wrapper, which takes care of APR initialization/shutdown
    # and the creation and cleanup of our top-level memory pool.
    svn.core.run_app(crawl_youngest, os.path.normpath(sys.argv[1]))

Trouble Shooting

実行時

『 libsvn_swig_py-1.dll が見つからなかったため、 このアプリケーションを開始できませんでした。アプリケーションをインストールし直す とこの問題は解決される場合があります。 』のエラーが出る

libsvn_swig_py-1.dll のあるディレクトリにパスを通してください。あるいは カレントディレクトリにコピーしてください。

『 ImportError: No module named _fs 』 のエラーが出る

Traceback (most recent call last):
  File "D:\svnwork\subversion\trunk\test.py", line 7, in 
    import svn.fs, svn.core, svn.repos
  File "C:\Python25\lib\site-packages\svn\fs.py", line 19, in 
    from libsvn.fs import *
  File "C:\Python25\lib\site-packages\libsvn\fs.py", line 7, in 
    import _fs
ImportError: No module named _fs
Python2.5 を使う場合 _fs.dll や _core.dll 等のファイルは _fs.pyd や _core.pyd の ように拡張子を pyd に変更する必要があります。