#!/usr/bin/env python # vim:fileencoding=utf-8 # License: GPLv3 Copyright: 2016, Kovid Goyal from __future__ import (unicode_literals, division, absolute_import, print_function) from itertools import count import os import shutil from bypy.constants import is64bit from bypy.utils import run 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 7' calibre_constants = globals()['calibre_constants'] CANDLE = WIXP + r'\bin\candle.exe' LIGHT = WIXP + r'\bin\light.exe' j, d, a, b = os.path.join, os.path.dirname, os.path.abspath, os.path.basename def create_installer(env): if os.path.exists(env.installer_dir): shutil.rmtree(env.installer_dir) os.makedirs(env.installer_dir) with open(j(d(__file__), 'wix-template.xml'), 'rb') as f: template = f.read().decode('utf-8') components, smap = get_components_from_files(env) wxs = template.format( app=calibre_constants['appname'], appfolder='Calibre2' if is64bit else 'Calibre', version=calibre_constants['version'], upgrade_code=UPGRADE_CODE, ProgramFilesFolder='ProgramFiles64Folder' if is64bit else 'ProgramFilesFolder', x64=' 64bit' if is64bit else '', minverhuman=MINVERHUMAN, minver='601', fix_wix='' if is64bit else '', compression='high', app_components=components, exe_map=smap, main_icon=j(env.src_root, 'icons', 'library.ico'), viewer_icon=j(env.src_root, 'icons', 'viewer.ico'), editor_icon=j(env.src_root, 'icons', 'ebook-edit.ico'), web_icon=j(env.src_root, 'icons', 'web.ico'), ) with open(j(d(__file__), 'en-us.xml'), 'rb') as f: template = f.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.encode('utf-8')) with open(enusf, 'wb') as f: 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] run(*cmd) installer = j(env.dist, '%s%s-%s.msi' % ( calibre_constants['appname'], ('-64bit' if is64bit else ''), calibre_constants['version'])) license = j(env.src_root, 'LICENSE.rtf') banner = j(env.src_root, 'icons', 'wix-banner.bmp') dialog = j(env.src_root, 'icons', 'wix-dialog.bmp') cmd = [LIGHT, '-nologo', '-ext', 'WixUIExtension', '-cultures:en-us', '-loc', enusf, wixobj, '-ext', 'WixUtilExtension', '-o', installer, '-dWixUILicenseRtf=' + license, '-dWixUIBannerBmp=' + banner, '-dWixUIDialogBmp=' + dialog] cmd.extend([ '-sice:ICE60', # No language in dlls warning '-sice:ICE61', # Allow upgrading with same version number '-sice:ICE40', # Re-install mode overriden '-sice:ICE69', # Shortcut components are part of a different feature than the files they point to ]) cmd.append('-sval') # Disable all checks since they fail when running under ssh run(*cmd) def get_components_from_files(env): file_idc = count() file_id_map = {} def process_dir(path): components = [] for x in os.listdir(path): f = os.path.join(path, x) file_id_map[f] = fid = next(file_idc) if os.path.isdir(f): components.append( '' % (file_id_map[f], f, x)) c = process_dir(f) components.extend(c) components.append('') else: checksum = 'Checksum="yes"' if x.endswith('.exe') else '' c = [ ('') % (fid,), ('') % (fid, f, x, checksum), '' ] if x.endswith('.exe') and not x.startswith('pdf'): # Add the executable to app paths so that users can # launch it from the run dialog even if it is not on # the path. See http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx c[-1:-1] = [ ('' % (x, fid)), (''.format(x)), ] components.append('\n'.join(c)) return components components = process_dir(a(env.base)) smap = {} for x in calibre_constants['basenames']['gui']: smap[x] = 'file_%d' % file_id_map[a(j(env.base, x + '.exe'))] return '\t\t\t\t' + '\n\t\t\t\t'.join(components), smap