mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
More work on building calibre on windows
This commit is contained in:
parent
e804e48747
commit
947fb029d8
@ -31,8 +31,6 @@ dlls = [
|
||||
'Sensors',
|
||||
'Sql',
|
||||
'Svg',
|
||||
'WebKit',
|
||||
'WebKitWidgets',
|
||||
'WebEngineCore',
|
||||
'WebEngine',
|
||||
'WebEngineWidgets',
|
||||
@ -49,7 +47,7 @@ if islinux:
|
||||
elif ismacos:
|
||||
dlls += ['MacExtras', 'DBus']
|
||||
elif iswindows:
|
||||
dlls += ['WinExtras', 'Angle']
|
||||
dlls += ['WinExtras']
|
||||
|
||||
QT_DLLS = frozenset(
|
||||
'Qt5' + x for x in dlls
|
||||
@ -68,7 +66,7 @@ QT_PLUGINS = [
|
||||
# 'audio', 'printsupport', 'bearer', 'position',
|
||||
]
|
||||
|
||||
if not ismacos:
|
||||
if not ismacos and not iswindows:
|
||||
QT_PLUGINS.append('platforminputcontexts')
|
||||
|
||||
if islinux:
|
||||
@ -88,8 +86,6 @@ PYQT_MODULES = (
|
||||
'QtPrintSupport',
|
||||
'QtSensors',
|
||||
'QtSvg',
|
||||
'QtWebKit',
|
||||
'QtWebKitWidgets',
|
||||
'QtWidgets',
|
||||
'QtWebEngine',
|
||||
'QtWebEngineCore',
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Requires installation of Visual Studio 2017 Community Edition, Git, Ruby, Python 3.7 and Perl
|
||||
# Requires installation of Visual Studio 2017 Community Edition, WiX Toolset, Git, Ruby, Python 3.7 and Perl
|
||||
# git.exe must be in PATH. Must have ~100GB available disk space and 8GB RAM
|
||||
# Install certifi in python 3 with:
|
||||
# py.exe -m pip install certifi
|
||||
|
@ -8,6 +8,7 @@ import errno
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import runpy
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
@ -15,12 +16,11 @@ import sys
|
||||
import zipfile
|
||||
|
||||
from bypy.constants import (
|
||||
PREFIX, SRC as CALIBRE_DIR, SW, is64bit, build_dir, python_major_minor_version
|
||||
CL, LINK, PREFIX, RC, SRC as CALIBRE_DIR, SW, build_dir, is64bit,
|
||||
python_major_minor_version
|
||||
)
|
||||
from bypy.utils import py_compile, run, walk
|
||||
|
||||
from .wix import create_installer
|
||||
|
||||
iv = globals()['init_env']
|
||||
calibre_constants = iv['calibre_constants']
|
||||
QT_PREFIX = os.path.join(PREFIX, 'qt')
|
||||
@ -30,6 +30,9 @@ APPNAME, VERSION = calibre_constants['appname'], calibre_constants['version']
|
||||
WINVER = VERSION + '.0'
|
||||
machine = 'X64' if is64bit else 'X86'
|
||||
j, d, a, b = os.path.join, os.path.dirname, os.path.abspath, os.path.basename
|
||||
create_installer = runpy.run_path(
|
||||
j(d(a(__file__)), 'wix.py'), {'calibre_constants': calibre_constants}
|
||||
)['create_installer']
|
||||
|
||||
DESCRIPTIONS = {
|
||||
'calibre': 'The main calibre program',
|
||||
@ -51,7 +54,6 @@ DESCRIPTIONS = {
|
||||
|
||||
# https://msdn.microsoft.com/en-us/library/windows/desktop/dn481241(v=vs.85).aspx
|
||||
SUPPORTED_OS = {
|
||||
'vista': '{e2011457-1546-43c5-a5fe-008deee3d3f0}',
|
||||
'w7': '{35138b9a-5d96-4fbd-8e2d-a2440225f93a}',
|
||||
'w8': '{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}',
|
||||
'w81': '{1f676c76-80e1-4239-95bb-83d0f6d0da78}',
|
||||
@ -70,7 +72,6 @@ EXE_MANIFEST = '''\
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<supportedOS Id="{vista}"/>
|
||||
<supportedOS Id="{w7}"/>
|
||||
<supportedOS Id="{w8}"/>
|
||||
<supportedOS Id="{w81}"/>
|
||||
@ -86,6 +87,10 @@ def printf(*args, **kw):
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def run_compiler(env, *cmd):
|
||||
run(*cmd, cwd=env.obj_dir)
|
||||
|
||||
|
||||
class Env(object):
|
||||
|
||||
def __init__(self, build_dir):
|
||||
@ -160,6 +165,8 @@ def freeze(env, ext_dir):
|
||||
printf('Adding Qt...')
|
||||
for x in QT_DLLS:
|
||||
copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll'))
|
||||
for x in 'libGLESv2 libEGL'.split():
|
||||
copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll'))
|
||||
plugdir = j(QT_PREFIX, 'plugins')
|
||||
tdir = j(env.app_base, 'qt_plugins')
|
||||
for d in QT_PLUGINS:
|
||||
@ -253,7 +260,7 @@ def extract_pyd_modules(env, site_packages_dir):
|
||||
bpy = dest[:-1]
|
||||
if os.path.exists(bpy):
|
||||
with open(bpy, 'rb') as f:
|
||||
raw = f.read().strip()
|
||||
raw = f.read().strip().decode('utf-8')
|
||||
if (not raw.startswith('def __bootstrap__') or not raw.endswith('__bootstrap__()')):
|
||||
raise ValueError('The file %r has non bootstrap code' % bpy)
|
||||
for ext in ('', 'c', 'o'):
|
||||
@ -298,7 +305,7 @@ def embed_resources(env, module, desc=None, extra_data=None, product_description
|
||||
icon_map = {'calibre': 'library', 'ebook-viewer': 'viewer', 'ebook-edit': 'ebook-edit',
|
||||
'lrfviewer': 'viewer', 'calibre-portable': 'library'}
|
||||
file_type = 'DLL' if module.endswith('.dll') else 'APP'
|
||||
template = open(env.rc_template, 'rb').read()
|
||||
template = open(env.rc_template, 'rb').read().decode('utf-8')
|
||||
bname = b(module)
|
||||
internal_name = os.path.splitext(bname)[0]
|
||||
icon = icon_map.get(internal_name, 'command-prompt')
|
||||
@ -316,7 +323,7 @@ def embed_resources(env, module, desc=None, extra_data=None, product_description
|
||||
if product_description is None:
|
||||
product_description = APPNAME + ' - E-book management'
|
||||
rc = template.format(
|
||||
icon=icon,
|
||||
icon=icon.replace('\\', '/'),
|
||||
file_type=e(file_type),
|
||||
file_version=e(WINVER.replace('.', ',')),
|
||||
file_version_str=e(WINVER),
|
||||
@ -334,10 +341,10 @@ def embed_resources(env, module, desc=None, extra_data=None, product_description
|
||||
rc += '\nextra extra "%s"' % extra_data
|
||||
tdir = env.obj_dir
|
||||
rcf = j(tdir, bname + '.rc')
|
||||
with open(rcf, 'wb') as f:
|
||||
with open(rcf, 'w') as f:
|
||||
f.write(rc)
|
||||
res = j(tdir, bname + '.res')
|
||||
run('rc', '/n', '/fo' + res, rcf)
|
||||
run(RC, '/n', '/fo' + res, rcf)
|
||||
return res
|
||||
|
||||
|
||||
@ -356,8 +363,8 @@ def build_portable_installer(env):
|
||||
cflags.append(r'/I%s\include' % PREFIX)
|
||||
cflags.append('/DUNCOMPRESSED_SIZE=%d' % usz)
|
||||
printf('Compiling', obj)
|
||||
cmd = ['cl.exe'] + cflags + ['/Fo' + obj, src]
|
||||
run(*cmd)
|
||||
cmd = [CL] + cflags + ['/Fo' + obj, src]
|
||||
run_compiler(env, *cmd)
|
||||
|
||||
base = d(a(__file__))
|
||||
src = j(base, 'portable-installer.cpp')
|
||||
@ -371,8 +378,8 @@ def build_portable_installer(env):
|
||||
printf('Linking', exe)
|
||||
manifest = exe + '.manifest'
|
||||
with open(manifest, 'wb') as f:
|
||||
f.write(EXE_MANIFEST)
|
||||
cmd = ['link.exe'] + [
|
||||
f.write(EXE_MANIFEST.encode('utf-8'))
|
||||
cmd = [LINK] + [
|
||||
'/INCREMENTAL:NO', '/MACHINE:' + machine,
|
||||
'/LIBPATH:' + env.obj_dir, '/SUBSYSTEM:WINDOWS',
|
||||
'/LIBPATH:' + (PREFIX + r'\lib'),
|
||||
@ -397,12 +404,12 @@ def build_portable(env):
|
||||
cflags = '/c /EHsc /MT /W3 /Ox /nologo /D_UNICODE /DUNICODE'.split()
|
||||
|
||||
printf('Compiling', obj)
|
||||
cmd = ['cl.exe'] + cflags + ['/Fo' + obj, '/Tc' + src]
|
||||
run(*cmd)
|
||||
cmd = [CL] + cflags + ['/Fo' + obj, '/Tc' + src]
|
||||
run_compiler(env, *cmd)
|
||||
|
||||
exe = j(base, 'calibre-portable.exe')
|
||||
printf('Linking', exe)
|
||||
cmd = ['link.exe'] + [
|
||||
cmd = [LINK] + [
|
||||
'/INCREMENTAL:NO', '/MACHINE:' + machine,
|
||||
'/LIBPATH:' + env.obj_dir, '/SUBSYSTEM:WINDOWS',
|
||||
'/RELEASE',
|
||||
@ -482,16 +489,16 @@ def build_utils(env):
|
||||
|
||||
def build(src, name, subsys='CONSOLE', libs='setupapi.lib'.split()):
|
||||
printf('Building ' + name)
|
||||
obj = j(env.obj_dir, (src) + '.obj')
|
||||
obj = j(env.obj_dir, os.path.basename(src) + '.obj')
|
||||
cflags = '/c /EHsc /MD /W3 /Ox /nologo /D_UNICODE'.split()
|
||||
ftype = '/T' + ('c' if src.endswith('.c') else 'p')
|
||||
cmd = ['cl.exe'] + cflags + ['/Fo' + obj, ftype + src]
|
||||
run(*cmd)
|
||||
cmd = [CL] + cflags + ['/Fo' + obj, ftype + src]
|
||||
run_compiler(env, *cmd)
|
||||
exe = j(env.dll_dir, name)
|
||||
mf = exe + '.manifest'
|
||||
with open(mf, 'wb') as f:
|
||||
f.write(EXE_MANIFEST)
|
||||
cmd = ['link.exe'] + [
|
||||
f.write(EXE_MANIFEST.encode('utf-8'))
|
||||
cmd = [LINK] + [
|
||||
'/MACHINE:' + machine,
|
||||
'/SUBSYSTEM:' + subsys, '/RELEASE', '/MANIFEST:EMBED', '/MANIFESTINPUT:' + mf,
|
||||
'/OUT:' + exe] + [embed_resources(env, exe), obj] + libs
|
||||
@ -512,12 +519,12 @@ def build_launchers(env, debug=False):
|
||||
cflags = '/c /EHsc /W3 /Ox /nologo /D_UNICODE'.split()
|
||||
cflags += ['/DPYDLL="python%s.dll"' % env.py_ver.replace('.', ''), '/I%s/include' % env.python_base]
|
||||
for src, obj in zip(sources, objects):
|
||||
cmd = ['cl.exe'] + cflags + dflags + ['/MD', '/Fo' + obj, '/Tc' + src]
|
||||
run(*cmd)
|
||||
cmd = [CL] + cflags + dflags + ['/MD', '/Fo' + obj, '/Tc' + src]
|
||||
run_compiler(env, *cmd)
|
||||
|
||||
dll = j(env.obj_dir, 'calibre-launcher.dll')
|
||||
ver = '.'.join(VERSION.split('.')[:2])
|
||||
cmd = ['link.exe', '/DLL', '/VERSION:' + ver, '/LTCG', '/OUT:' + dll,
|
||||
cmd = [LINK, '/DLL', '/VERSION:' + ver, '/LTCG', '/OUT:' + dll,
|
||||
'/nologo', '/MACHINE:' + machine] + dlflags + objects + \
|
||||
[embed_resources(env, dll),
|
||||
'/LIBPATH:%s/libs' % env.python_base,
|
||||
@ -542,16 +549,16 @@ def build_launchers(env, debug=False):
|
||||
'/DFUNCTION="%s"' % func]
|
||||
dest = j(env.obj_dir, bname + '.obj')
|
||||
printf('Compiling', bname)
|
||||
cmd = ['cl.exe'] + cflags + dflags + ['/Tc' + src, '/Fo' + dest]
|
||||
run(*cmd)
|
||||
cmd = [CL] + cflags + dflags + ['/Tc' + src, '/Fo' + dest]
|
||||
run_compiler(env, *cmd)
|
||||
exe = j(env.base, bname + '.exe')
|
||||
lib = dll.replace('.dll', '.lib')
|
||||
u32 = ['user32.lib']
|
||||
printf('Linking', bname)
|
||||
mf = dest + '.manifest'
|
||||
with open(mf, 'wb') as f:
|
||||
f.write(EXE_MANIFEST)
|
||||
cmd = ['link.exe'] + [
|
||||
f.write(EXE_MANIFEST.encode('utf-8'))
|
||||
cmd = [LINK] + [
|
||||
'/MACHINE:' + machine, '/NODEFAULTLIB', '/ENTRY:start_here',
|
||||
'/LIBPATH:' + env.obj_dir, '/SUBSYSTEM:' + subsys,
|
||||
'/LIBPATH:%s/libs' % env.python_base, '/RELEASE',
|
||||
@ -689,3 +696,7 @@ def main():
|
||||
build_portable_installer(env)
|
||||
if args.sign_installers:
|
||||
sign_installers(env)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
@ -8,16 +8,16 @@ from itertools import count
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from pkgs.constants import is64bit
|
||||
from pkgs.utils import run
|
||||
from .. import calibre_constants
|
||||
from bypy.constants import is64bit
|
||||
from bypy.utils import run
|
||||
|
||||
WIXP = r'C:\Program Files (x86)\WiX Toolset v3.10'
|
||||
WIXP = r'C:\Program Files (x86)\WiX Toolset v3.11'
|
||||
if is64bit:
|
||||
UPGRADE_CODE = '5DD881FF-756B-4097-9D82-8C0F11D521EA'
|
||||
else:
|
||||
UPGRADE_CODE = 'BEB2A80D-E902-4DAD-ADF9-8BD2DA42CFE1'
|
||||
MINVERHUMAN = 'Windows Vista SP2'
|
||||
MINVERHUMAN = 'Windows 7'
|
||||
calibre_constants = globals()['calibre_constants']
|
||||
|
||||
CANDLE = WIXP + r'\bin\candle.exe'
|
||||
LIGHT = WIXP + r'\bin\light.exe'
|
||||
@ -29,7 +29,7 @@ def create_installer(env):
|
||||
shutil.rmtree(env.installer_dir)
|
||||
os.makedirs(env.installer_dir)
|
||||
|
||||
template = open(j(d(__file__), 'wix-template.xml'), 'rb').read()
|
||||
template = open(j(d(__file__), 'wix-template.xml'), 'rb').read().decode('utf-8')
|
||||
|
||||
components, smap = get_components_from_files(env)
|
||||
wxs = template.format(
|
||||
@ -40,7 +40,7 @@ def create_installer(env):
|
||||
ProgramFilesFolder='ProgramFiles64Folder' if is64bit else 'ProgramFilesFolder',
|
||||
x64=' 64bit' if is64bit else '',
|
||||
minverhuman=MINVERHUMAN,
|
||||
minver='600',
|
||||
minver='601',
|
||||
fix_wix='<Custom Action="OverwriteWixSetDefaultPerMachineFolder" After="WixSetDefaultPerMachineFolder" />' if is64bit else '',
|
||||
compression='high',
|
||||
app_components=components,
|
||||
@ -50,15 +50,15 @@ def create_installer(env):
|
||||
editor_icon=j(env.src_root, 'icons', 'ebook-edit.ico'),
|
||||
web_icon=j(env.src_root, 'icons', 'web.ico'),
|
||||
)
|
||||
template = open(j(d(__file__), 'en-us.xml'), 'rb').read()
|
||||
template = open(j(d(__file__), 'en-us.xml'), 'rb').read().decode('utf-8')
|
||||
enus = template.format(app=calibre_constants['appname'])
|
||||
|
||||
enusf = j(env.installer_dir, 'en-us.wxl')
|
||||
wxsf = j(env.installer_dir, calibre_constants['appname'] + '.wxs')
|
||||
with open(wxsf, 'wb') as f:
|
||||
f.write(wxs)
|
||||
f.write(wxs.encode('utf-8'))
|
||||
with open(enusf, 'wb') as f:
|
||||
f.write(enus)
|
||||
f.write(enus.encode('utf-8'))
|
||||
wixobj = j(env.installer_dir, calibre_constants['appname'] + '.wixobj')
|
||||
arch = 'x64' if is64bit else 'x86'
|
||||
cmd = [CANDLE, '-nologo', '-arch', arch, '-ext', 'WiXUtilExtension', '-o', wixobj, wxsf]
|
||||
|
Loading…
x
Reference in New Issue
Block a user