Use python 2.6 and Visual Studio 2008 in the windows build

This commit is contained in:
Kovid Goyal 2008-12-09 03:25:31 -08:00
parent e90cb0954b
commit 463b406312
7 changed files with 85 additions and 33 deletions

View File

@ -6,13 +6,13 @@ __docformat__ = 'restructuredtext en'
''' '''
Freeze app into executable using py2exe. Freeze app into executable using py2exe.
''' '''
QT_DIR = 'C:\\Qt\\4.4.1' QT_DIR = 'C:\\Qt\\4.4.3'
LIBUSB_DIR = 'C:\\libusb' LIBUSB_DIR = 'C:\\libusb'
LIBUNRAR = 'C:\\Program Files\\UnrarDLL\\unrar.dll' LIBUNRAR = 'C:\\Program Files\\UnrarDLL\\unrar.dll'
PDFTOHTML = 'C:\\pdftohtml\\pdftohtml.exe' PDFTOHTML = 'C:\\pdftohtml\\pdftohtml.exe'
IMAGEMAGICK_DIR = 'C:\\ImageMagick' IMAGEMAGICK_DIR = 'C:\\ImageMagick'
FONTCONFIG_DIR = 'C:\\fontconfig' FONTCONFIG_DIR = 'C:\\fontconfig'
VC90 = r'C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT'
import sys, os, py2exe, shutil, zipfile, glob, subprocess, re import sys, os, py2exe, shutil, zipfile, glob, subprocess, re
from distutils.core import setup from distutils.core import setup
@ -65,6 +65,8 @@ class BuildEXE(py2exe.build_exe.py2exe):
shutil.copyfile(f, os.path.join(self.dist_dir, os.path.basename(f))) shutil.copyfile(f, os.path.join(self.dist_dir, os.path.basename(f)))
for f in glob.glob(os.path.join(BASE_DIR, 'src', 'calibre', 'plugins', '*.pyd')): for f in glob.glob(os.path.join(BASE_DIR, 'src', 'calibre', 'plugins', '*.pyd')):
shutil.copyfile(f, os.path.join(tgt, os.path.basename(f))) shutil.copyfile(f, os.path.join(tgt, os.path.basename(f)))
for f in glob.glob(os.path.join(BASE_DIR, 'src', 'calibre', 'plugins', '*.manifest')):
shutil.copyfile(f, os.path.join(tgt, os.path.basename(f)))
shutil.copyfile('LICENSE', os.path.join(self.dist_dir, 'LICENSE')) shutil.copyfile('LICENSE', os.path.join(self.dist_dir, 'LICENSE'))
print print
print 'Adding QtXml4.dll' print 'Adding QtXml4.dll'
@ -115,12 +117,17 @@ class BuildEXE(py2exe.build_exe.py2exe):
shutil.copytree(f, tgt) shutil.copytree(f, tgt)
else: else:
shutil.copyfile(f, tgt) shutil.copyfile(f, tgt)
print print
print 'Doing DLL redirection' # See http://msdn.microsoft.com/en-us/library/ms682600(VS.85).aspx print 'Doing DLL redirection' # See http://msdn.microsoft.com/en-us/library/ms682600(VS.85).aspx
for f in glob.glob(os.path.join(PY2EXE_DIR, '*.exe')): for f in glob.glob(os.path.join(PY2EXE_DIR, '*.exe')):
open(f + '.local', 'w').write('\n') open(f + '.local', 'w').write('\n')
print
print 'Adding Windows runtime dependencies...'
for f in glob.glob(os.path.join(VC90, '*')):
shutil.copyfile(f, os.path.join(PY2EXE_DIR, os.path.basename(f)))
@classmethod @classmethod
def manifest(cls, prog): def manifest(cls, prog):
@ -142,17 +149,17 @@ def main(args=sys.argv):
{'script' : scripts['gui'][0], {'script' : scripts['gui'][0],
'dest_base' : APPNAME, 'dest_base' : APPNAME,
'icon_resources' : [(1, ICONS[0])], 'icon_resources' : [(1, ICONS[0])],
'other_resources' : [BuildEXE.manifest(APPNAME)], #'other_resources' : [BuildEXE.manifest(APPNAME)],
}, },
{'script' : scripts['gui'][1], {'script' : scripts['gui'][1],
'dest_base' : 'lrfviewer', 'dest_base' : 'lrfviewer',
'icon_resources' : [(1, ICONS[1])], 'icon_resources' : [(1, ICONS[1])],
'other_resources' : [BuildEXE.manifest('lrfviewer')], #'other_resources' : [BuildEXE.manifest('lrfviewer')],
}, },
{'script' : scripts['gui'][2], {'script' : scripts['gui'][2],
'dest_base' : 'ebook-viewer', 'dest_base' : 'ebook-viewer',
'icon_resources' : [(1, ICONS[1])], 'icon_resources' : [(1, ICONS[1])],
'other_resources' : [BuildEXE.manifest('ebook-viewer')], #'other_resources' : [BuildEXE.manifest('ebook-viewer')],
}, },
], ],
console = console, console = console,
@ -162,12 +169,12 @@ def main(args=sys.argv):
'includes' : [ 'includes' : [
'sip', 'pkg_resources', 'PyQt4.QtSvg', 'sip', 'pkg_resources', 'PyQt4.QtSvg',
'mechanize', 'ClientForm', 'wmi', 'mechanize', 'ClientForm', 'wmi',
'win32file', 'pythoncom', 'rtf2xml', 'win32file', 'pythoncom',
'win32process', 'win32api', 'msvcrt', 'win32process', 'win32api', 'msvcrt',
'win32event', 'calibre.ebooks.lrf.any.*', 'win32event', 'calibre.ebooks.lrf.any.*',
'calibre.ebooks.lrf.feeds.*', 'calibre.ebooks.lrf.feeds.*',
'genshi', 'BeautifulSoup', 'BeautifulSoup', 'pyreadline',
'path', 'pydoc', 'IPython.Extensions.*', 'pydoc', 'IPython.Extensions.*',
'calibre.web.feeds.recipes.*', 'calibre.web.feeds.recipes.*',
'PyQt4.QtWebKit', 'PyQt4.QtNetwork', 'PyQt4.QtWebKit', 'PyQt4.QtNetwork',
], ],

View File

@ -6,7 +6,7 @@ __docformat__ = 'restructuredtext en'
''' '''
Build PyQt extensions. Integrates with distutils (but uses the PyQt build system). Build PyQt extensions. Integrates with distutils (but uses the PyQt build system).
''' '''
from distutils.core import Extension from distutils.core import Extension as _Extension
from distutils.command.build_ext import build_ext as _build_ext from distutils.command.build_ext import build_ext as _build_ext
from distutils.dep_util import newer_group from distutils.dep_util import newer_group
from distutils import log from distutils import log
@ -15,12 +15,23 @@ import sipconfig, os, sys, string, glob, shutil
from PyQt4 import pyqtconfig from PyQt4 import pyqtconfig
iswindows = 'win32' in sys.platform iswindows = 'win32' in sys.platform
QMAKE = os.path.expanduser('~/qt/bin/qmake') if 'darwin' in sys.platform else'qmake' QMAKE = os.path.expanduser('~/qt/bin/qmake') if 'darwin' in sys.platform else'qmake'
WINDOWS_PYTHON = ['C:/Python25/libs'] WINDOWS_PYTHON = ['C:/Python26/libs']
OSX_SDK = '/Developer/SDKs/MacOSX10.4u.sdk' OSX_SDK = '/Developer/SDKs/MacOSX10.4u.sdk'
def replace_suffix(path, new_suffix): def replace_suffix(path, new_suffix):
return os.path.splitext(path)[0] + new_suffix return os.path.splitext(path)[0] + new_suffix
class Extension(_Extension):
pass
if iswindows:
from distutils import msvc9compiler
msvc = msvc9compiler.MSVCCompiler()
msvc.initialize()
nmake = msvc.find_exe('nmake.exe')
rc = msvc.find_exe('rc.exe')
class PyQtExtension(Extension): class PyQtExtension(Extension):
def __init__(self, name, sources, sip_sources, **kw): def __init__(self, name, sources, sip_sources, **kw):
@ -37,9 +48,7 @@ class PyQtExtension(Extension):
class build_ext(_build_ext): class build_ext(_build_ext):
def make(self, makefile): def make(self, makefile):
make = 'make' make = nmake if iswindows else 'make'
if iswindows:
make = 'mingw32-make'
self.spawn([make, '-f', makefile]) self.spawn([make, '-f', makefile])
def build_qt_objects(self, ext, bdir): def build_qt_objects(self, ext, bdir):
@ -65,12 +74,13 @@ CONFIG += x86 ppc
open(name+'.pro', 'wb').write(pro) open(name+'.pro', 'wb').write(pro)
self.spawn([QMAKE, '-o', 'Makefile.qt', name+'.pro']) self.spawn([QMAKE, '-o', 'Makefile.qt', name+'.pro'])
self.make('Makefile.qt') self.make('Makefile.qt')
pat = 'release\\*.o' if iswindows else '*.o' pat = 'release\\*.obj' if iswindows else '*.o'
return map(os.path.abspath, glob.glob(pat)) return map(os.path.abspath, glob.glob(pat))
finally: finally:
os.chdir(cwd) os.chdir(cwd)
def build_sbf(self, sip, sbf, bdir): def build_sbf(self, sip, sbf, bdir):
print '\tBuilding spf...'
sip_bin = self.sipcfg.sip_bin sip_bin = self.sipcfg.sip_bin
self.spawn([sip_bin, self.spawn([sip_bin,
"-c", bdir, "-c", bdir,
@ -100,9 +110,7 @@ CONFIG += x86 ppc
def build_extension(self, ext): def build_extension(self, ext):
self.inplace = True # Causes extensions to be built in the source tree self.inplace = True # Causes extensions to be built in the source tree
if not isinstance(ext, PyQtExtension):
return _build_ext.build_extension(self, ext)
fullname = self.get_ext_fullname(ext.name) fullname = self.get_ext_fullname(ext.name)
if self.inplace: if self.inplace:
# ignore build-lib -- put the compiled extension into # ignore build-lib -- put the compiled extension into
@ -119,7 +127,38 @@ CONFIG += x86 ppc
else: else:
ext_filename = os.path.join(self.build_lib, ext_filename = os.path.join(self.build_lib,
self.get_ext_filename(fullname)) self.get_ext_filename(fullname))
bdir = os.path.abspath(os.path.join(self.build_temp, fullname)) bdir = os.path.abspath(os.path.join(self.build_temp, fullname))
if not os.path.exists(bdir):
os.makedirs(bdir)
if not isinstance(ext, PyQtExtension):
if not iswindows:
return _build_ext.build_extension(self, ext)
c_sources = [f for f in ext.sources if os.path.splitext(f)[1].lower() in ('.c', '.cpp', '.cxx')]
compile_args = '/c /nologo /Ox /MD /W3 /GX /DNDEBUG'.split()
compile_args += ext.extra_compile_args
self.swig_opts = ''
inc_dirs = self.include_dirs + [x.replace('/', '\\') for x in ext.include_dirs]
cc = [msvc.cc] + compile_args + ['-I%s'%x for x in list(set(inc_dirs))]
objects = []
for f in c_sources:
o = os.path.join(bdir, os.path.basename(f)+'.obj')
objects.append(o)
compiler = cc + ['/Tc'+f, '/Fo'+o]
self.spawn(compiler)
out = os.path.join(bdir, base+'.pyd')
linker = [msvc.linker] + '/DLL /nologo /INCREMENTAL:NO'.split()
linker += ['/LIBPATH:'+x for x in self.library_dirs]
linker += [x+'.lib' for x in ext.libraries]
linker += ['/EXPORT:init'+base] + objects + ['/OUT:'+out]
self.spawn(linker)
for src in (out, out+'.manifest'):
shutil.copyfile(src, os.path.join('src', 'calibre', 'plugins', os.path.basename(src)))
return
if not os.path.exists(bdir): if not os.path.exists(bdir):
os.makedirs(bdir) os.makedirs(bdir)
ext.sources2 = map(os.path.abspath, ext.sources) ext.sources2 = map(os.path.abspath, ext.sources)

View File

@ -46,10 +46,10 @@ main_functions = {
} }
if __name__ == '__main__': if __name__ == '__main__':
from setuptools import setup, find_packages, Extension from setuptools import setup, find_packages
from distutils.command.build import build as _build from distutils.command.build import build as _build
from distutils.core import Command as _Command from distutils.core import Command as _Command
from pyqtdistutils import PyQtExtension, build_ext from pyqtdistutils import PyQtExtension, build_ext, Extension
import subprocess, glob import subprocess, glob
def newer(targets, sources): def newer(targets, sources):
@ -391,8 +391,10 @@ if __name__ == '__main__':
ext_modules.append(Extension('calibre.plugins.winutil', ext_modules.append(Extension('calibre.plugins.winutil',
sources=['src/calibre/utils/windows/winutil.c'], sources=['src/calibre/utils/windows/winutil.c'],
libraries=['shell32', 'setupapi'], libraries=['shell32', 'setupapi'],
include_dirs=['C:/WinDDK/6001.18001/inc/api/']) include_dirs=['C:/WinDDK/6001.18001/inc/api/',
) 'C:/WinDDK/6001.18001/inc/crt/'],
extra_compile_args=['/X']
))
if isosx: if isosx:
ext_modules.append(Extension('calibre.plugins.usbobserver', ext_modules.append(Extension('calibre.plugins.usbobserver',
sources=['src/calibre/devices/usbobserver/usbobserver.c']) sources=['src/calibre/devices/usbobserver/usbobserver.c'])

View File

@ -4,17 +4,20 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
This module provides a thin ctypes based wrapper around libusb. This module provides a thin ctypes based wrapper around libusb.
""" """
from ctypes import cdll, POINTER, byref, pointer, Structure, \ from ctypes import cdll, POINTER, byref, pointer, Structure as _Structure, \
c_ubyte, c_ushort, c_int, c_char, c_void_p, c_byte, c_uint c_ubyte, c_ushort, c_int, c_char, c_void_p, c_byte, c_uint
from errno import EBUSY, ENOMEM from errno import EBUSY, ENOMEM
from calibre import iswindows, isosx, load_library, isfrozen from calibre import iswindows, isosx, load_library
_libusb_name = 'libusb' _libusb_name = 'libusb'
PATH_MAX = 511 if iswindows else 1024 if isosx else 4096 PATH_MAX = 511 if iswindows else 1024 if isosx else 4096
if iswindows: if iswindows:
Structure._pack_ = 1 class Structure(_Structure):
_pack_ = 1
_libusb_name = 'libusb0' _libusb_name = 'libusb0'
else:
Structure = _Structure
try: try:
try: try:

View File

@ -715,7 +715,7 @@ void PictureFlowPrivate::render()
painter.setPen(Qt::white); painter.setPen(Qt::white);
//painter.setPen(QColor(255,255,255,127)); //painter.setPen(QColor(255,255,255,127));
if (centerIndex < slideCount() and centerIndex > -1) if (centerIndex < slideCount() && centerIndex > -1)
painter.drawText( QRect(0,0, buffer.width(), (buffer.height() - slideSize().height())/2), painter.drawText( QRect(0,0, buffer.width(), (buffer.height() - slideSize().height())/2),
Qt::AlignCenter, slideImages->caption(centerIndex)); Qt::AlignCenter, slideImages->caption(centerIndex));
@ -767,12 +767,12 @@ void PictureFlowPrivate::render()
int sc = slideCount(); int sc = slideCount();
painter.setPen(QColor(255,255,255, (255-fade) )); painter.setPen(QColor(255,255,255, (255-fade) ));
if (leftTextIndex < sc and leftTextIndex > -1) if (leftTextIndex < sc && leftTextIndex > -1)
painter.drawText( QRect(0,0, buffer.width(), (buffer.height() - slideSize().height())/2), painter.drawText( QRect(0,0, buffer.width(), (buffer.height() - slideSize().height())/2),
Qt::AlignCenter, slideImages->caption(leftTextIndex)); Qt::AlignCenter, slideImages->caption(leftTextIndex));
painter.setPen(QColor(255,255,255, fade)); painter.setPen(QColor(255,255,255, fade));
if (leftTextIndex+1 < sc and leftTextIndex > -2) if (leftTextIndex+1 < sc && leftTextIndex > -2)
painter.drawText( QRect(0,0, buffer.width(), (buffer.height() - slideSize().height())/2), painter.drawText( QRect(0,0, buffer.width(), (buffer.height() - slideSize().height())/2),
Qt::AlignCenter, slideImages->caption(leftTextIndex+1)); Qt::AlignCenter, slideImages->caption(leftTextIndex+1));

View File

@ -7,7 +7,7 @@ This module provides a thin ctypes based wrapper around libunrar.
See ftp://ftp.rarlabs.com/rar/unrarsrc-3.7.5.tar.gz See ftp://ftp.rarlabs.com/rar/unrarsrc-3.7.5.tar.gz
""" """
import os, ctypes, sys, re import os, ctypes, sys, re
from ctypes import Structure, c_char_p, c_uint, c_void_p, POINTER, \ from ctypes import Structure as _Structure, c_char_p, c_uint, c_void_p, POINTER, \
byref, c_wchar_p, c_int, c_char, c_wchar byref, c_wchar_p, c_int, c_char, c_wchar
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
from StringIO import StringIO from StringIO import StringIO
@ -18,9 +18,12 @@ from calibre.ptempfile import TemporaryDirectory
_librar_name = 'libunrar' _librar_name = 'libunrar'
cdll = ctypes.cdll cdll = ctypes.cdll
if iswindows: if iswindows:
Structure._pack_ = 1 class Structure(_Structure):
_pack_ = 1
_librar_name = 'unrar' _librar_name = 'unrar'
cdll = ctypes.windll cdll = ctypes.windll
else:
Structure = _Structure
if hasattr(sys, 'frozen') and iswindows: if hasattr(sys, 'frozen') and iswindows:
_libunrar = cdll.LoadLibrary(os.path.join(os.path.dirname(sys.executable), 'unrar.dll')) _libunrar = cdll.LoadLibrary(os.path.join(os.path.dirname(sys.executable), 'unrar.dll'))
_libunrar = load_library(_librar_name, cdll) _libunrar = load_library(_librar_name, cdll)

View File

@ -5,5 +5,3 @@
* Use multiprocessing for cpu_count instead of QThread * Use multiprocessing for cpu_count instead of QThread
* Windows build:
* Compile all dependencies with MSVC 2008 since this is what python now uses