最近需要使用 BitTorrent 來實驗點對點資料傳輸功能,所以想說來玩玩 libtorrent 這個程式庫(C++),為了方便實驗,也需要它的 Python 綁定。經過三天的爬文與奮戰,終於在 Windows, OSX 以及 Ubuntu 上成功編譯或安裝,本文山姆鍋就來分享在 Windows 64 位元電腦上編譯的方法之一。

會特別選擇 Windows 環境來說明,主要也是因為在這個平台上編譯是其中最麻煩的,加上又是要給 64 位元架構的電腦執行,更是雪上加霜。雖然說條條道路通羅馬, 但本文所說明的是山姆鍋目前唯一成功的方法,如果您有其它更簡潔的作法,請分享。

編譯環境

從程式碼編譯成功與否跟實際編譯時的環境有很大的關聯,底下是山姆鍋使用的環境(實際上是虛擬機):

  • 作業系統:Windows X86 64 Bit
    本文使用的是正體中文環境,不過應該沒有差別。
  • C/C++ 編譯器: VC for Python
    可以在這裡下載:http://www.microsoft.com/en-us/download/details.aspx?id=44266 ,本文假設您使用預設路徑自行安裝完成。
  • Python 執行環境
    本文使用 2.7.10 64 位元版本,可到此下載並安裝:https://www.python.org/ftp/python/2.7.10/python-2.7.10.amd64.msi , 本文假設安裝路徑為:‘C:\Python’。
  • Dependency Walker
    這個工具是為了找出動態連結檔相依性問題,可以在此下載: http://www.dependencywalker.com/ ,不一定需要,但在 Python 發生無法 import 的問題時可以幫助找出問題。

準備作業

在正式編譯前,編譯環境需要做些修改: 找到這個檔案,

%USERPROFILE%\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\vcvarsall.bat\ , 其中 %USERFILE% 是 Windows 使用者個人目錄,如:C:\\Users\\Sam Kuo

將此檔案中的 if "%1" == "" goto x86 改為 if "%1" == "" goto amd64 , 這個目的是讓編譯器預設使用 64 位元模式,如果您之後需要改編譯 32 位元,請自行改回去。

開啟「命令提示字元(Command Prompt)」視窗,並執行下列指令設定編譯器的環境變數:

1
"%USERPROFILE%\AppData\Local\Programs\Common\Microsoft\Visual C++ for Python\9.0\vcvarsall.bat"

底下小節皆假設在同一個命令視窗執行。

編譯與安裝 Boost

下載

libtorrent 使用到 Boost 這個程式庫, 本文使用的版本是 1.59.0,可到這裡下載: http://sourceforge.net/projects/boost/files/boost/1.59.0/ ,下載到 C 槽並解壓縮後,原始檔的路徑為: ‘c:\boost_1_59_0’ 。

將目前目錄更換到 ‘c:\boost_1_59_0’ ,執行下列指令編譯 Boost 需要的建構工具 b2.exe。

1
bootstrap.bat

編譯並安裝 Boost

1
b2 --with-system --with-date_time --with-python address-model=64 install

上述指令會將需要的檔案複製到 C:\\Boost 這個目錄,其中會有 includelib 這兩個子目錄。

lib 子目錄中有兩個檔案需要改名,將:

  1. boost_python-vc90-mt-1_59.lib 複製並改名為 boost_python.lib
  2. boost_system-vc90-mt-1_59.lib 複製並改名為 boost_system.lib

沒有改名,在編譯 libtorrent 時會出現找不到程式庫錯誤。

編譯 libtorrent

本文使用的版本是 1.0.7,可到此下載:https://github.com/arvidn/libtorrent/releases , 假設下載後解壓縮到目錄: C:\\libtorrent-1_0_7

設定 BOOST_ROOT 環境變數:

1
set BOOST_ROOT=c:\boost_1_59_0

更換目前路徑到 ‘C:\libtorrent-1_0_7\bindings\python’ ,執行:

1
c:\boost_1_59_0\b2.exe boost=source boost-link=static link=static  release optimization=space address-model=64  "include=c:\Boost\include\boost-1_59" "library-path=c:\Boost\lib"

請注意,上述指令並沒有換行。

經過不少時間的編譯,如果沒有出問題,會產生所需的 Python 模組以及 libtorrent 本身的動態連結檔, 分別在:

  • Python 模組
    ‘C:\libtorrent-1_0_7\bindings\python\bin\msvc-9.0\release\address-model-64\boost-source\link-static\optimization-space\libtorrent.pyd’
  • libtorrent 程式庫
    ‘C:\libtorrent-1_0_7\bin\msvc-9.0\release\address-model-64\boost-link-shared\boost-source\optimization-space\threading-multi\torrent.dll’

是的,我知道,路徑就是這麼長!

設定 libtorrent-python 模組

  1. 將 libtorrent 程式庫的 DLL 檔複製到 ‘C:\Python’
  2. 將 Python 模組, libtorrent.pyd 複製到 ’C:\Python\Lib\site-packages\’

如果您在這個階段使用 Python 試圖 import libtorrent,會出現無法 import 的錯誤資訊, 這是因為 libtorrent.pyd 還相依於 Boost 的 system 模組。要解決這個問題,可以將 ‘C:\Boost\lib\boost_system-vc90-mt-1_59.dll’ 複製到 Windows 系統目錄, 或者像山姆鍋一樣複製到 ‘C:\Python\’ 目錄中。

驗證模組安裝完成

啟動 Python 進入互動模式,輸入:

1
2
import libtorrent
libtorrent.version

如果正常 import 並顯示版本號碼,模組應該有安裝成功。如果沒有,請使用 Dependency Walker 查看 libtorrent.pyd 的相依連結是否完整?例如缺少 msvcr90.dllmsvcp90.dll 這兩個檔案,則需要安裝 Visual Studio Redistributable 2008 套件。

OS X 跟 Ubuntu?

這兩個平台按照 Storjtorrent 提供的步驟便能運作,本文就不重複。

小技巧

在過程中,山姆鍋學到一些有用的小技巧或知識,在這裏順便提供:

  • 如何觀看動態連結檔 (DLL) 或共享物件檔 (.so) 的相依性?
    熟悉 Linux 系統的會知道有個 ldd 程式可以方便檢視 .so 相依於哪些其它 .so 檔; 在 OSX 系統,使用 otool -L 可以達到類似功能;Windows 系統則可以用 Dependency Walker 來查看。
  • 在 Windows 上如何分辨執行檔 (.exe) 或動態連結檔 (.dll) 是 32 還是 64 位元?

    Visual Studio 有個 dumpbin.exe 工具程式可以用來分辨,指令用法:

    1
    dumpbin /headers < 檔案名稱 & gt;

    從顯示的訊息,如果有看到 x64 表示是 64 位元, x86 則是 32 位元,如下面片段:

    1
    2
    FILE HEADER VALUES
    8664 machine (x64)

結語

雖說山姆鍋最終希望只需要一個 libtorrent.pyd 檔案便能夠使用, 也就是說:libtorrent 跟 Boost 都以靜態連結的方式到那個模組檔中,只可惜還沒有試出來。現階段只做到編譯跟安裝, 編譯出來的程式庫是否功能完全正常,這點還沒有進一步驗證;另外,很明顯 libtorrent 的一些選用的功能是不支援的,例如:OpenSSL encryption。不管怎樣,希望對於也想透過 Python 玩玩 libtorrent 的人有所幫助。