【原創】Tribler開發--BG Process的編譯

遵守 http://www.tribler.org/trac/wiki/BrowserPlugin 中對SwarmPlugin的說明,首先須要編譯出BG Process這個東東。 node

下載源碼 svn co http://svn.tribler.org/abc/branches/mainbranch/,將源碼放到你本身指定路徑後執行
C:\Python27>python.exe Tribler\Plugin\Build\Win32\setupBGexe.py py2exe
Traceback (most recent call last):
  File "Tribler\Plugin\Build\Win32\setupBGexe.py", line 8, in <module>
    import py2exe # Not a superfluous import!
ImportError: No module named py2exe
提示缺乏py2exe模塊,從SourceForge上下載py2exe-0.6.9.win32-py2.7.exe並安裝到默認路徑C:\Python27\Lib\site-packages\
=======================================     
This package is a distutils extension to build
standalone Windows executable programs from
Python scripts.

    Author: Thomas Heller
    Author_email: theller@python.net
    Description: Build standalone executables for Windows
    Maintainer: Jimmy Retzlaff
    Maintainer_email: jimmy@retzlaff.com
    Name: py2exe
    Url: http://www.py2exe.org/
    Version: 0.6.9
=======================================    
從新執行獲得 
C:\Python27>python.exe Tribler\Plugin\Build\Win32\setupBGexe.py py2exe
running py2exe
creating C:\Python27\build
creating C:\Python27\build\bdist.win32
creating C:\Python27\build\bdist.win32\winexe
creating C:\Python27\build\bdist.win32\winexe\collect-2.7
creating C:\Python27\build\bdist.win32\winexe\bundle-2.7
creating C:\Python27\build\bdist.win32\winexe\temp
creating C:\Python27\dist
*** searching for required modules ***
C:\Python27\Tribler\Player\swarmplayer.py:451: SyntaxWarning: name 'START_TIME' is assigned to before global declaration
  global START_TIME
*** parsing results ***
creating python loader for extension 'vlc' (C:\Python27\vlc.pyd -> vlc.pyd)
creating python loader for extension 'unicodedata' (C:\Python27\DLLs\unicodedata.pyd -> unicodedata.pyd)
creating python loader for extension 'win32pdh' (C:\Python27\lib\site-packages\win32\win32pdh.pyd -> win32pdh.pyd)
creating python loader for extension '_ctypes' (C:\Python27\DLLs\_ctypes.pyd -> _ctypes.pyd)
creating python loader for extension 'select' (C:\Python27\DLLs\select.pyd -> select.pyd)
creating python loader for extension 'win32event' (C:\Python27\lib\site-packages\win32\win32event.pyd -> win32event.pyd)
creating python loader for extension 'wx._controls_' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_controls_.pyd -> wx._co
ntrols_.pyd)
creating python loader for extension 'apsw' (C:\Python27\lib\site-packages\apsw.pyd -> apsw.pyd)
creating python loader for extension 'win32evtlog' (C:\Python27\lib\site-packages\win32\win32evtlog.pyd -> win32evtlog.pyd)
creating python loader for extension 'win32file' (C:\Python27\lib\site-packages\win32\win32file.pyd -> win32file.pyd)
creating python loader for extension 'wx._windows_' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_windows_.pyd -> wx._wind
ows_.pyd)
creating python loader for extension '_hashlib' (C:\Python27\DLLs\_hashlib.pyd -> _hashlib.pyd)
creating python loader for extension 'bz2' (C:\Python27\DLLs\bz2.pyd -> bz2.pyd)
creating python loader for extension '_ssl' (C:\Python27\DLLs\_ssl.pyd -> _ssl.pyd)
creating python loader for extension '_sqlite3' (C:\Python27\DLLs\_sqlite3.pyd -> _sqlite3.pyd)
creating python loader for extension 'wx._core_' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_core_.pyd -> wx._core_.pyd)

creating python loader for extension 'wx._misc_' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_misc_.pyd -> wx._misc_.pyd)

creating python loader for extension 'wx._xrc' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_xrc.pyd -> wx._xrc.pyd)
creating python loader for extension 'M2Crypto.__m2crypto' (C:\Python27\lib\site-packages\M2Crypto\__m2crypto.pyd -> M2Crypto.__m2
crypto.pyd)
creating python loader for extension '_win32sysloader' (C:\Python27\lib\site-packages\win32\_win32sysloader.pyd -> _win32sysloader
.pyd)
creating python loader for extension 'wx._gdi_' (C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_gdi_.pyd -> wx._gdi_.pyd)
creating python loader for extension 'pyexpat' (C:\Python27\DLLs\pyexpat.pyd -> pyexpat.pyd)
creating python loader for extension 'win32ui' (C:\Python27\lib\site-packages\Pythonwin\win32ui.pyd -> win32ui.pyd)
creating python loader for extension 'win32api' (C:\Python27\lib\site-packages\win32\win32api.pyd -> win32api.pyd)
creating python loader for extension '_socket' (C:\Python27\DLLs\_socket.pyd -> _socket.pyd)
*** finding dlls needed ***
error: python25.dll: No such file or directory
本人裝的python版本爲2.7.3,這裏報沒有找到python25.dll,奇怪,沒辦法,只好分析源碼。
先查看setupBGexe.py,沒有發現特別的東西
import os

from distutils.core import setup
import py2exe # Not a superfluous import!

from Tribler.__init__ import LIBRARYNAME
mainfile = os.path.join(LIBRARYNAME,'Plugin','SwarmEngine.py')

# Arno: 2009-06-09: changed from console= to make sure py2exe writes
# a BackgroundProcess.exe.log
#
setup(windows=[mainfile])
再查看py2exe包的__init__.py文件 
# py2exe/__init__.py

# 'import py2exe' imports this package, and two magic things happen:
#
# - the 'py2exe.build_exe' submodule is imported and installed as
#   'distutils.commands.py2exe' command
#
# - the default distutils Distribution class is replaced by the
# special one contained in this module.
#
__version__ = "0.6.9"
import distutils.dist, distutils.core, distutils.command, build_exe, sys

class Distribution(distutils.dist.Distribution):
    def __init__(self, attrs):
        self.ctypes_com_server = attrs.pop("ctypes_com_server", [])
        self.com_server = attrs.pop("com_server", [])
        self.service = attrs.pop("service", [])
        self.windows = attrs.pop("windows", [])
        self.console = attrs.pop("console", [])
        self.isapi = attrs.pop("isapi", [])
        self.zipfile = attrs.pop("zipfile", "library.zip")
        distutils.dist.Distribution.__init__(self, attrs)

distutils.core.Distribution = Distribution
distutils.command.__all__.append('py2exe')

sys.modules['distutils.command.py2exe'] = build_exe
由註釋能夠看出,該文件幹了兩件事,其中導入build_exe做爲py2exe是和我相關的,因而查看build_exe文件。在該文件中可以找到上面出錯的最後一行打印的對應代碼 print "*** finding dlls needed ***"。

由經驗知道 error: python25.dll: No such file or directory 意思是打開文件的時候出錯,要麼是文件路徑不對,要麼是文件名不對,總之未找到對應文件,搜索python27.dll,發現其位於C:\WINDOWS\system32下面,確實沒有python25.dll的影子(其實不搜索也應該猜獲得,畢竟我沒裝過python2.5嘛)

兩種解決辦法:
a) 下載python25.dll,放置到和python27.dll相同的目錄下
b) 對build_exe.py進行修改

下載python25.dll的方法能夠參考百度百科說明 http://baike.baidu.com/view/6590620.htm
這裏說明下如何對build_exe.py進行修改,和這個問題有關的代碼以下 
......
def bin_depends(path, images, excluded_dlls):
    import py2exe_util
    warnings = FileSet()
    images = FileSet(images)
    dependents = FileSet()
    others = FileSet()
    while images:
        for image in images.copy():
            images.remove(image)
            if not image in dependents:
                dependents.add(image)
                abs_image = os.path.abspath(image)
                loadpath = os.path.dirname(abs_image) + ';' + path
                for result in py2exe_util.depends(image, loadpath).items():
                    dll, uses_import_module = result
                    if os.path.basename(dll).lower() not in excluded_dlls:
                        if isSystemDLL(dll):
                            others.add(dll)
                            continue
                        if dll not in images and dll not in dependents:
                            images.add(dll)
                            if uses_import_module:
                                warnings.add(dll)
    return dependents, warnings, others


# DLLs to be excluded
# XXX This list is NOT complete (it cannot be)
# Note: ALL ENTRIES MUST BE IN LOWER CASE!
EXCLUDED_DLLS = (
    "advapi32.dll",
    "comctl32.dll",
    "comdlg32.dll",
    "crtdll.dll",
    "gdi32.dll",
    "glu32.dll",
    "opengl32.dll",
    "imm32.dll",
    "kernel32.dll",
    "mfc42.dll",
    "msvcirt.dll",
    "msvcrt.dll",
    "msvcrtd.dll",
    "ntdll.dll",
    "odbc32.dll",
    "ole32.dll",
    "oleaut32.dll",
    "rpcrt4.dll",
    "shell32.dll",
    "shlwapi.dll",
    "user32.dll",
    "version.dll",
    "winmm.dll",
    "winspool.drv",
    "ws2_32.dll",
    "ws2help.dll",
    "wsock32.dll",
    "netapi32.dll",

    "gdiplus.dll",
    )


# XXX Perhaps it would be better to assume dlls from the systemdir are system dlls,
# and make some exceptions for known dlls, like msvcr71, pythonXY.dll, and so on?
def isSystemDLL(pathname):
    if os.path.basename(pathname).lower() in ("msvcr71.dll", "msvcr71d.dll"):
        return 0
    if os.path.basename(pathname).lower() in EXCLUDED_DLLS:
        return 1
    # How can we determine whether a dll is a 'SYSTEM DLL'?
    # Is it sufficient to use the Image Load Address?
    import struct
    file = open(pathname, "rb")
    if file.read(2) != "MZ":
        raise Exception, "Seems not to be an exe-file"
    file.seek(0x3C)
    pe_ofs = struct.unpack("i", file.read(4))[0]
    file.seek(pe_ofs)
    if file.read(4) != "PE\000\000":
        raise Exception, ("Seems not to be an exe-file", pathname)
    file.read(20 + 28) # COFF File Header, offset of ImageBase in Optional Header
    imagebase = struct.unpack("I", file.read(4))[0]
    return not (imagebase < 0x70000000)

......
      分析後可知,錯誤打印 error: python25.dll: No such file or directory 應該是代碼 file = open(pathname, "rb") 產生的,從函數isSystemDLL()的註釋能夠看出,應該對一些特別版本的dll進行排除,那麼能夠作以下修改: 
if os.path.basename(pathname).lower() in ("msvcr71.dll", "msvcr71d.dll"):
改成
if os.path.basename(pathname).lower() in ("msvcr71.dll", "msvcr71d.dll", "python25.dll"):
此時執行結果爲
C:\Python27>python.exe Tribler\Plugin\Build\Win32\setupBGexe.py py2exe
running py2exe
*** searching for required modules ***
C:\Python27\Tribler\Player\swarmplayer.py:451: SyntaxWarning: name 'START_TIME' is assigned to before global declaration
  global START_TIME
*** parsing results ***
......
......
*** finding dlls needed ***
Traceback (most recent call last):
  File "Tribler\Plugin\Build\Win32\setupBGexe.py", line 16, in <module>
    setup(windows=[mainfile])
  File "C:\Python27\lib\distutils\core.py", line 152, in setup
    dist.run_commands()
  File "C:\Python27\lib\distutils\dist.py", line 953, in run_commands
    self.run_command(cmd)
  File "C:\Python27\lib\distutils\dist.py", line 972, in run_command
    cmd_obj.run()
  File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 243, in run
    self._run()
  File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 305, in _run
    dlls = self.find_dlls(extensions)
  File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 389, in find_dlls
    self.dll_excludes)
  File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 1064, in find_dependend_dlls
    bin_depends(loadpath, images + [sys.executable], excludes_use)
  File "C:\Python27\lib\site-packages\py2exe\build_exe.py", line 1438, in bin_depends
    for result in py2exe_util.depends(image, loadpath).items():
py2exe_util.bind_error: (2, '', 'python25.dll')
呵呵,貌似不行,而且只有py2exe_util.pyd文件,沒有源文件,沒法進一步知道不行的緣由,故換另一種方法:在EXCLUDED_DLLS增長"python25.dll",執行結果以下
C:\Python27>python.exe Tribler\Plugin\Build\Win32\setupBGexe.py py2exe
running py2exe
*** searching for required modules ***
C:\Python27\Tribler\Player\swarmplayer.py:451: SyntaxWarning: name 'START_TIME' is assigned to before global declaration
  global START_TIME
*** parsing results ***
......
*** finding dlls needed ***
error: MSVCP90.dll: No such file or directory
解說說明錯誤說明找不到 python25.dll的問題已經沒有了,可是 須要庫MSVCP90.dll。該庫是Microsoft C++ Runtime Library,是使用Microsoft Visual Studio 2008編譯出的程序默認依賴的庫文件。按道理我電腦已經安裝了VS2008,該庫應該是存在的,可是如今的狀況是其確實不在C:\WINDOWS\system32目錄下面(和其餘系統路徑下),故搜索出我電腦上該文件並拷貝到C:\WINDOWS\system32下面,執行程序,終於獲得了正確的結果,以下
C:\Python27>python.exe Tribler\Plugin\Build\Win32\setupBGexe.py py2exe
running py2exe
*** searching for required modules ***
C:\Python27\Tribler\Player\swarmplayer.py:451: SyntaxWarning: name 'START_TIME' is assigned to before global declaration
  global START_TIME
*** parsing results ***
......
*** finding dlls needed ***
*** create binaries ***
*** byte compile python files ***
......
skipping byte-compilation of ......
skipping byte-compilation of C:\Python27\Tribler\vlc.py to Tribler\vlc.pyc
byte-compiling C:\Python27\build\bdist.win32\winexe\temp\M2Crypto.__m2crypto.py to M2Crypto\__m2crypto.pyc
byte-compiling ......
......
skipping byte-compilation of C:\Python27\lib\zipfile.py to zipfile.pyc
*** copy extensions ***
*** copy dlls ***
copying C:\Python27\lib\site-packages\py2exe\run_w.exe -> C:\Python27\dist\SwarmEngine.exe
The following modules appear to be missing
['ElementC14N', 'Tribler.Core.BuddyCast.buddycast', '_curses', '_scproxy', 'core.bootstrap', 'core.identifier', 'core.message', 'c
ore.node', 'core.ptime', 'core.routing_table', 'meliae', 'netifaces', 'prctl', 'psyco', 'simplejson', 'test_const', 'vlc.lib.vlc',
 'win32com.shell']

*** binary dependencies ***
Your executable(s) also depend on these dlls which are not included,
you may or may not need to distribute them.

Make sure you have the license if you distribute any of them, and
make sure you don't distribute files belonging to the operating system.

   ole32.dll - C:\WINDOWS\system32\ole32.dll
   OLEAUT32.dll - C:\WINDOWS\system32\OLEAUT32.dll
   USER32.dll - C:\WINDOWS\system32\USER32.dll
   python25.dll - python25.dll
   SHELL32.dll - C:\WINDOWS\system32\SHELL32.dll
   MSWSOCK.dll - C:\WINDOWS\system32\MSWSOCK.dll
   WINMM.dll - C:\WINDOWS\system32\WINMM.dll
   WSOCK32.dll - C:\WINDOWS\system32\WSOCK32.dll
   COMDLG32.dll - C:\WINDOWS\system32\COMDLG32.dll
   ADVAPI32.dll - C:\WINDOWS\system32\ADVAPI32.dll
   mfc90.dll - C:\Python27\lib\site-packages\Pythonwin\mfc90.dll
   msvcrt.dll - C:\WINDOWS\system32\msvcrt.dll
   WS2_32.dll - C:\WINDOWS\system32\WS2_32.dll
   WINSPOOL.DRV - C:\WINDOWS\system32\WINSPOOL.DRV
   GDI32.dll - C:\WINDOWS\system32\GDI32.dll
   gdiplus.dll - C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\gdiplus.dll
   VERSION.dll - C:\WINDOWS\system32\VERSION.dll
   KERNEL32.dll - C:\WINDOWS\system32\KERNEL32.dll
   COMCTL32.dll - C:\WINDOWS\system32\COMCTL32.dll
   RPCRT4.dll - C:\WINDOWS\system32\RPCRT4.dll
   MSVCP90.dll - C:\WINDOWS\system32\MSVCP90.dll
此時已經編譯出了SwarmEngine.exe位於C:\Python27\dist目錄下,可是雙擊執行時,仍舊不能正常安裝,錯誤日誌查看SwarmEngine.exe.log解決,本文再也不說明。
相關文章
相關標籤/搜索