mirror of
https://gitlab.com/openlp/packaging.git
synced 2024-12-22 13:02:50 +00:00
3bd987ffcf
Use debug bootloader when building devel version. Add ssl hook and runtime hook to include certificates for Mac OS X(OS X). Fix release app version(OS X). Fix converting bytes to megabytes(OS X). Fix argument to cp command(OS X).
655 lines
29 KiB
Python
655 lines
29 KiB
Python
# -*- coding: utf-8 -*-
|
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
|
|
|
###############################################################################
|
|
# OpenLP - Open Source Lyrics Projection #
|
|
# --------------------------------------------------------------------------- #
|
|
# Copyright (c) 2008-2015 OpenLP Developers #
|
|
# --------------------------------------------------------------------------- #
|
|
# This program is free software; you can redistribute it and/or modify it #
|
|
# under the terms of the GNU General Public License as published by the Free #
|
|
# Software Foundation; version 2 of the License. #
|
|
# #
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
|
# more details. #
|
|
# #
|
|
# You should have received a copy of the GNU General Public License along #
|
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
|
###############################################################################
|
|
|
|
"""
|
|
Windows Build Script
|
|
--------------------
|
|
|
|
This script is used to build the Windows binary and the accompanying installer.
|
|
For this script to work out of the box, it depends on a number of things:
|
|
|
|
Python 3.3/3.4
|
|
|
|
PyQt4
|
|
You should already have this installed, OpenLP doesn't work without it. The
|
|
version the script expects is the packaged one available from River Bank
|
|
Computing.
|
|
|
|
PyEnchant
|
|
This script expects the precompiled, installable version of PyEnchant to be
|
|
installed. You can find this on the PyEnchant site.
|
|
|
|
Inno Setup 5
|
|
Inno Setup should be installed into "C:\%PROGRAMFILES%\Inno Setup 5"
|
|
|
|
Sphinx
|
|
This is used to build the documentation. The documentation trunk must be at
|
|
the same directory level as OpenLP trunk and named "documentation".
|
|
|
|
HTML Help Workshop
|
|
This is used to create the help file.
|
|
|
|
PyInstaller
|
|
PyInstaller should be a git clone of either
|
|
https://github.com/matysek/pyinstaller branch python3 or
|
|
https://github.com/pyinstaller/pyinstaller branch python3
|
|
|
|
Bazaar
|
|
You need the command line "bzr" client installed.
|
|
|
|
OpenLP
|
|
A checkout of the latest code, in a branch directory, which is in a Bazaar
|
|
shared repository directory. This means your code should be in a directory
|
|
structure like this: "openlp\branch-name".
|
|
|
|
Visual C++ 2008 Express Edition
|
|
This is to build pptviewlib.dll, the library for controlling the
|
|
PowerPointViewer.
|
|
|
|
windows-builder.py
|
|
This script, of course. It should be in the "windows-installer" directory
|
|
at the same level as OpenLP trunk.
|
|
|
|
psvince.dll
|
|
This dll is used during the actual install of OpenLP to check if OpenLP is
|
|
running on the users machine prior to the setup. If OpenLP is running,
|
|
the install will fail. The dll can be obtained from here:
|
|
|
|
http://www.vincenzo.net/isxkb/index.php?title=PSVince)
|
|
|
|
The dll is presently included with this script.
|
|
|
|
Mako
|
|
Mako Templates for Python. This package is required for building the
|
|
remote plugin. It can be installed by going to your
|
|
python_directory\scripts\.. and running "easy_install Mako". If you do not
|
|
have easy_install, the Mako package can be obtained here:
|
|
|
|
http://www.makotemplates.org/download.html
|
|
|
|
SQLAlchemy Migrate
|
|
Required for the databases used in OpenLP. The package can be
|
|
obtained here:
|
|
|
|
http://code.google.com/p/sqlalchemy-migrate/
|
|
|
|
MuPDF
|
|
Required for PDF support in OpenLP. Download the windows build from
|
|
mupdf.com, extract it, and set the mudrawbin option in the config file to
|
|
point to mudraw.exe
|
|
|
|
Portable App Builds
|
|
The following are required if you are planning to make a portable build of
|
|
OpenLP. The portable build conforms to the standards published by
|
|
PortableApps.com:
|
|
|
|
http://portableapps.com/development/portableapps.com_format
|
|
|
|
PortableApps.com Installer:
|
|
|
|
http://portableapps.com/apps/development/portableapps.com_installer
|
|
|
|
PortableApps.com Launcher:
|
|
|
|
http://portableapps.com/apps/development/portableapps.com_launcher
|
|
|
|
NSIS Portable (Unicode version):
|
|
|
|
http://portableapps.com/apps/development/nsis_portable
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
from shutil import copy, rmtree, move
|
|
from distutils import dir_util
|
|
from subprocess import Popen, PIPE
|
|
from configparser import ConfigParser
|
|
from argparse import ArgumentParser
|
|
|
|
|
|
class WindowsBuilder(object):
|
|
"""
|
|
The :class:`WindowsBuilder` class encapsulates everything that is needed
|
|
to build a Windows installer.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.setup_args()
|
|
self.setup_system_paths()
|
|
self.read_config()
|
|
self.setup_executables()
|
|
self.setup_paths()
|
|
self.version = ''
|
|
|
|
def _print(self, text, *args):
|
|
"""
|
|
Print stuff out. Later we might want to use a log file.
|
|
"""
|
|
if len(args) > 0:
|
|
text = text % tuple(args)
|
|
print(text)
|
|
|
|
def _print_verbose(self, text, *args):
|
|
"""
|
|
Print output, obeying "verbose" mode.
|
|
"""
|
|
if self.args.verbose:
|
|
self._print(text, *args)
|
|
|
|
def setup_args(self):
|
|
"""
|
|
Set up an argument parser and parse the command line arguments.
|
|
"""
|
|
parser = ArgumentParser()
|
|
parser.add_argument('-b', '--branch', metavar='BRANCH', dest='branch',
|
|
help='Specify the path to the branch you wish to build.', default=None)
|
|
parser.add_argument('-d', '--documentation', metavar='DOCS', dest='docs', default=None,
|
|
help='Specify the path to the documentation branch.')
|
|
parser.add_argument('-c', '--config', metavar='CONFIG', dest='config',
|
|
help='Specify the path to the configuration file.',
|
|
default=os.path.abspath(os.path.join('.', 'config.ini')))
|
|
parser.add_argument('-u', '--skip-update', dest='skip_update', action='store_true', default=False,
|
|
help='Do NOT update the branch before building.')
|
|
parser.add_argument('-p', '--portable', metavar='PORTABLE', dest='portable', default=None,
|
|
help='Specify the path to build the portable installation.')
|
|
parser.add_argument('-t', '--skip-translations', dest='skip_translations', action='store_true', default=False,
|
|
help='Do NOT update the language translation files.')
|
|
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', default=False,
|
|
help='Print out additional information.')
|
|
self.args = parser.parse_args()
|
|
|
|
def read_config(self):
|
|
"""
|
|
Read the configuration from the configuration file.
|
|
"""
|
|
self.config = ConfigParser(defaults={
|
|
'pyroot': self.python_root,
|
|
'progfiles': self.program_files,
|
|
'sitepackages': self.site_packages,
|
|
'here': self.script_path,
|
|
'projects': os.path.abspath(os.path.join(self.script_path, '..', '..')),
|
|
})
|
|
self.config.read(os.path.abspath(self.args.config))
|
|
|
|
def setup_system_paths(self):
|
|
"""
|
|
Set up some system paths.
|
|
"""
|
|
self.script_path = os.path.dirname(os.path.abspath(__file__))
|
|
self.python = sys.executable
|
|
self.python_root = os.path.dirname(self.python)
|
|
self.site_packages = os.path.join(self.python_root, 'Lib', 'site-packages')
|
|
self.program_files = os.getenv('PROGRAMFILES')
|
|
|
|
def setup_executables(self):
|
|
"""
|
|
Set up the paths to the executables we use.
|
|
"""
|
|
self.innosetup = os.path.abspath(self.config.get('executables', 'innosetup'))
|
|
self.sphinx = os.path.abspath(self.config.get('executables', 'sphinx'))
|
|
self.pyinstaller = os.path.abspath(self.config.get('executables', 'pyinstaller'))
|
|
self.vcbuild = os.path.abspath(self.config.get('executables', 'vcbuild'))
|
|
self.hhc = os.path.abspath(self.config.get('executables', 'htmlhelp'))
|
|
self.psvince = os.path.abspath(self.config.get('executables', 'psvince'))
|
|
self.portableinstaller = os.path.abspath(self.config.get('executables', 'portableinstaller'))
|
|
self.portablelauncher = os.path.abspath(self.config.get('executables', 'portablelauncher'))
|
|
self.mudraw_bin = os.path.abspath(self.config.get('executables', 'mudrawbin'))
|
|
if os.path.exists(os.path.join(self.site_packages, 'PyQt4', 'bin')):
|
|
# Older versions of the PyQt4 Windows installer put their binaries
|
|
# in the "bin" directory
|
|
self.lrelease = os.path.join(self.site_packages, 'PyQt4', 'bin', 'lrelease.exe')
|
|
else:
|
|
# Newer versions of the PyQt4 Windows installer put their binaries
|
|
# in the base directory of the installation
|
|
self.lrelease = os.path.join(self.site_packages, 'PyQt4', 'lrelease.exe')
|
|
|
|
def setup_paths(self):
|
|
"""
|
|
Set up a variety of paths that we use throughout the build process.
|
|
"""
|
|
if self.args.branch:
|
|
branch_path = self.args.branch
|
|
else:
|
|
branch_path = self.config.get('paths', 'branch')
|
|
self.branch_path = os.path.abspath(branch_path)
|
|
if self.args.docs:
|
|
docs_path = self.args.docs
|
|
else:
|
|
docs_path = self.config.get('paths', 'documentation')
|
|
self.docs_path = os.path.abspath(docs_path)
|
|
if self.args.portable:
|
|
portable_path = self.args.portable
|
|
else:
|
|
try:
|
|
portable_path = self.config.get('paths', 'portable')
|
|
except:
|
|
portable_path = ''
|
|
if portable_path:
|
|
self.portable_path = os.path.abspath(portable_path)
|
|
self.args.portable = self.portable_path
|
|
else:
|
|
self.portable_path = ''
|
|
self.openlp_script = os.path.abspath(os.path.join(branch_path, 'openlp.py'))
|
|
self.hooks_path = os.path.abspath(self.config.get('paths', 'hooks'))
|
|
self.win32_icon = os.path.abspath(self.config.get('paths', 'win32icon'))
|
|
self.i18n_utils = os.path.join(self.branch_path, 'scripts', 'translation_utils.py')
|
|
self.source_path = os.path.join(self.branch_path, 'openlp')
|
|
self.manual_path = os.path.join(self.docs_path, 'manual')
|
|
self.manual_build_path = os.path.join(self.manual_path, 'build')
|
|
self.helpfile_path = os.path.join(self.manual_build_path, 'htmlhelp')
|
|
self.i18n_path = os.path.join(self.branch_path, 'resources', 'i18n')
|
|
self.winres_path = os.path.join(self.branch_path, 'resources', 'windows')
|
|
self.build_path = os.path.join(self.branch_path, 'build')
|
|
self.dist_path = os.path.join(self.branch_path, 'dist', 'OpenLP')
|
|
self.dist_path_pyinst_arg = os.path.join(self.branch_path, 'dist')
|
|
self.pptviewlib_path = os.path.join(self.source_path, 'plugins', 'presentations', 'lib', 'pptviewlib')
|
|
|
|
def update_code(self):
|
|
"""
|
|
Update the code in the branch.
|
|
"""
|
|
os.chdir(self.branch_path)
|
|
self._print('Reverting any changes to the code...')
|
|
bzr = Popen(('bzr', 'revert'), stdout=PIPE)
|
|
output = bzr.communicate()[0]
|
|
code = bzr.wait()
|
|
if code != 0:
|
|
self._print(output)
|
|
raise Exception('Error reverting the code')
|
|
self._print('Updating the code...')
|
|
bzr = Popen(('bzr', 'update'), stdout=PIPE)
|
|
output = bzr.communicate()[0]
|
|
code = bzr.wait()
|
|
if code != 0:
|
|
self._print(output)
|
|
raise Exception('Error updating the code')
|
|
|
|
def run_pyinstaller(self):
|
|
"""
|
|
Run PyInstaller on the branch to build an executable.
|
|
"""
|
|
self._print('Running PyInstaller...')
|
|
os.chdir(self.branch_path)
|
|
cmd = [self.python,
|
|
self.pyinstaller,
|
|
'--clean',
|
|
'--noconfirm',
|
|
'--windowed',
|
|
'--noupx',
|
|
'--additional-hooks-dir', self.hooks_path,
|
|
'--runtime-hook', os.path.join(self.hooks_path, 'rthook_openlp_pyqt4.py'),
|
|
'--distpath', self.dist_path_pyinst_arg,
|
|
'-i', self.win32_icon,
|
|
'-p', self.branch_path,
|
|
'-n', 'OpenLP',
|
|
self.openlp_script]
|
|
if not self.args.verbose:
|
|
cmd.append('--log-level=ERROR')
|
|
else:
|
|
cmd.append('--log-level=DEBUG')
|
|
if self.args.devel:
|
|
cmd.append('-d')
|
|
pyinstaller = Popen(cmd, stdout=PIPE)
|
|
output = pyinstaller.communicate()[0]
|
|
code = pyinstaller.wait()
|
|
if code != 0:
|
|
self._print(output)
|
|
raise Exception('Error running PyInstaller')
|
|
|
|
def write_version_file(self):
|
|
"""
|
|
Write the version number to a file for reading once installed.
|
|
"""
|
|
self._print('Writing version file...')
|
|
os.chdir(self.branch_path)
|
|
bzr = Popen(('bzr', 'tags'), stdout=PIPE)
|
|
output = bzr.communicate()[0]
|
|
code = bzr.wait()
|
|
if code != 0:
|
|
raise Exception('Error running bzr tags')
|
|
lines = output.splitlines()
|
|
if len(lines) == 0:
|
|
tag = '0.0.0'
|
|
revision = '0'
|
|
else:
|
|
tag, revision = lines[-1].decode('utf-8').split()
|
|
bzr = Popen(('bzr', 'log', '--line', '-r', '-1'), stdout=PIPE)
|
|
output, error = bzr.communicate()
|
|
code = bzr.wait()
|
|
if code != 0:
|
|
raise Exception('Error running bzr log')
|
|
latest = output.decode('utf-8').split(':')[0]
|
|
version_string = latest == revision and tag or '%s-bzr%s' % (tag, latest)
|
|
# Save decimal version in case we need to do a portable build.
|
|
self.version = latest == revision and tag or '%s.%s' % (tag, latest)
|
|
version_file = open(os.path.join(self.dist_path, '.version'), 'w')
|
|
version_file.write(str(version_string))
|
|
version_file.close()
|
|
|
|
def copy_default_theme(self):
|
|
"""
|
|
Copy the default theme to the correct directory for OpenLP.
|
|
"""
|
|
self._print('Copying default theme...')
|
|
source = os.path.join(self.source_path, 'core', 'lib', 'json')
|
|
dest = os.path.join(self.dist_path, 'core', 'lib', 'json')
|
|
for root, dirs, files in os.walk(source):
|
|
for filename in files:
|
|
if filename.endswith('.json'):
|
|
dest_path = os.path.join(dest, root[len(source) + 1:])
|
|
if not os.path.exists(dest_path):
|
|
os.makedirs(dest_path)
|
|
self._print_verbose('... %s', filename)
|
|
copy(os.path.join(root, filename), os.path.join(dest_path, filename))
|
|
|
|
def copy_plugins(self):
|
|
"""
|
|
Copy all the plugins to the correct directory so that OpenLP sees that
|
|
it has plugins.
|
|
"""
|
|
self._print('Copying plugins...')
|
|
source = os.path.join(self.source_path, 'plugins')
|
|
dest = os.path.join(self.dist_path, 'plugins')
|
|
for root, dirs, files in os.walk(source):
|
|
for filename in files:
|
|
if not filename.endswith('.pyc'):
|
|
dest_path = os.path.join(dest, root[len(source) + 1:])
|
|
if not os.path.exists(dest_path):
|
|
os.makedirs(dest_path)
|
|
self._print_verbose('... %s', filename)
|
|
copy(os.path.join(root, filename), os.path.join(dest_path, filename))
|
|
|
|
def copy_media_player(self):
|
|
"""
|
|
Copy the media players to the correct directory for OpenLP.
|
|
"""
|
|
self._print('Copying media player...')
|
|
source = os.path.join(self.source_path, 'core', 'ui', 'media')
|
|
dest = os.path.join(self.dist_path, 'core', 'ui', 'media')
|
|
for root, dirs, files in os.walk(source):
|
|
for filename in files:
|
|
if not filename.endswith('.pyc'):
|
|
dest_path = os.path.join(dest, root[len(source) + 1:])
|
|
if not os.path.exists(dest_path):
|
|
os.makedirs(dest_path)
|
|
self._print_verbose('... %s', filename)
|
|
copy(os.path.join(root, filename), os.path.join(dest_path, filename))
|
|
|
|
def copy_windows_files(self):
|
|
"""
|
|
Copy all the Windows-specific files.
|
|
"""
|
|
self._print('Copying extra files for Windows...')
|
|
self._print_verbose('... OpenLP.ico')
|
|
copy(os.path.join(self.script_path, 'OpenLP.ico'), os.path.join(self.dist_path, 'OpenLP.ico'))
|
|
self._print_verbose('... LICENSE.txt')
|
|
copy(os.path.join(self.script_path, 'LICENSE.txt'), os.path.join(self.dist_path, 'LICENSE.txt'))
|
|
self._print_verbose('... psvince.dll')
|
|
copy(self.psvince, os.path.join(self.dist_path, 'psvince.dll'))
|
|
if os.path.isfile(os.path.join(self.helpfile_path, 'OpenLP.chm')):
|
|
self._print_verbose('... OpenLP.chm')
|
|
copy(os.path.join(self.helpfile_path, 'OpenLP.chm'), os.path.join(self.dist_path, 'OpenLP.chm'))
|
|
else:
|
|
self._print('... WARNING: Windows help file not found')
|
|
self._print_verbose('... mudraw.exe')
|
|
if self.mudraw_bin and os.path.isfile(self.mudraw_bin):
|
|
copy(os.path.join(self.mudraw_bin), os.path.join(self.dist_path, 'mudraw.exe'))
|
|
else:
|
|
self._print('... WARNING: mudraw.exe not found')
|
|
|
|
def update_translations(self):
|
|
"""
|
|
Update the translations.
|
|
"""
|
|
self._print('Updating translations...')
|
|
if not self.config.has_section('transifex'):
|
|
raise Exception('No section named "transifex" found.')
|
|
if not self.config.has_option('transifex', 'username'):
|
|
raise Exception('No option named "username" found.')
|
|
if not self.config.has_option('transifex', 'password'):
|
|
raise Exception('No option named "password" found.')
|
|
username = self.config.get('transifex', 'username')
|
|
password = self.config.get('transifex', 'password')
|
|
os.chdir(os.path.dirname(self.i18n_utils))
|
|
translation_utils = Popen([self.python, self.i18n_utils, '-qdpu', '-U', username, '-P', password])
|
|
code = translation_utils.wait()
|
|
if code != 0:
|
|
raise Exception('Error running translation_utils.py')
|
|
|
|
def compile_translations(self):
|
|
"""
|
|
Compile the translations for Qt.
|
|
"""
|
|
self._print('Compiling translations...')
|
|
files = os.listdir(self.i18n_path)
|
|
if not os.path.exists(os.path.join(self.dist_path, 'i18n')):
|
|
os.makedirs(os.path.join(self.dist_path, 'i18n'))
|
|
for file in files:
|
|
if file.endswith('.ts'):
|
|
self._print_verbose('... %s', file)
|
|
source_path = os.path.join(self.i18n_path, file)
|
|
dest_path = os.path.join(self.dist_path, 'i18n', file.replace('.ts', '.qm'))
|
|
lconvert = Popen((self.lrelease, '-compress', '-silent', source_path, '-qm', dest_path))
|
|
code = lconvert.wait()
|
|
if code != 0:
|
|
raise Exception('Error running lconvert on %s' % source_path)
|
|
self._print('Copying qm files...')
|
|
source = os.path.join(self.site_packages, 'PyQt4', 'translations')
|
|
files = os.listdir(source)
|
|
for filename in files:
|
|
if filename.startswith('qt_') and filename.endswith('.qm') and len(filename) == 8:
|
|
self._print_verbose('... %s', filename)
|
|
copy(os.path.join(source, filename), os.path.join(self.dist_path, 'i18n', filename))
|
|
|
|
def run_sphinx(self):
|
|
"""
|
|
Run Sphinx to build an HTML Help project.
|
|
"""
|
|
self._print('Deleting previous help manual build... %s', self.manual_build_path)
|
|
if os.path.exists(self.manual_build_path):
|
|
rmtree(self.manual_build_path)
|
|
self._print('Running Sphinx...')
|
|
os.chdir(self.manual_path)
|
|
sphinx = Popen((self.sphinx, '-b', 'htmlhelp', '-d', 'build/doctrees', 'source', 'build/htmlhelp'), stdout=PIPE)
|
|
output, error = sphinx.communicate()
|
|
code = sphinx.wait()
|
|
if code != 0:
|
|
self._print(output)
|
|
raise Exception('Error running Sphinx')
|
|
|
|
def run_htmlhelp(self):
|
|
"""
|
|
Run HTML Help Workshop to convert the Sphinx output into a manual.
|
|
"""
|
|
self._print('Running HTML Help Workshop...')
|
|
os.chdir(os.path.join(self.manual_build_path, 'htmlhelp'))
|
|
hhc = Popen((self.hhc, 'OpenLP.chm'), stdout=PIPE)
|
|
output, error = hhc.communicate()
|
|
code = hhc.wait()
|
|
if code != 1:
|
|
self._print('Exit code:', code)
|
|
self._print(output)
|
|
raise Exception('Error running HTML Help Workshop')
|
|
|
|
def create_innosetup_file(self):
|
|
"""
|
|
Create an InnoSetup file pointing to the branch being built.
|
|
"""
|
|
self._print('Creating Inno Setup file...')
|
|
input = open(os.path.join(self.script_path, 'OpenLP-2.0.iss.default'), 'r').read()
|
|
output = input.replace('%(branch)s', self.branch_path)
|
|
output = output.replace('%(display_version)s', self.version)
|
|
outfile = open(os.path.join(self.script_path, 'OpenLP-2.0.iss'), 'w')
|
|
outfile.write(output)
|
|
outfile.close()
|
|
|
|
def check_portableapp_directory(self):
|
|
"""
|
|
Checks the PortableApp directory structure amd creates
|
|
missing subdirs
|
|
"""
|
|
self._print(' Checking PortableApps directory structure...')
|
|
launcher_path = os.path.join(self.portable_path, 'App', 'Appinfo', 'Launcher')
|
|
if not os.path.exists(launcher_path):
|
|
os.makedirs(launcher_path)
|
|
settings_path = os.path.join(self.portable_path, 'Data', 'Settings')
|
|
if not os.path.exists(settings_path):
|
|
os.makedirs(settings_path)
|
|
|
|
def create_portableapps_appinfo_file(self):
|
|
"""
|
|
Create a Portabbleapps appinfo.ini file.
|
|
"""
|
|
self._print(' Creating PortableApps appinfo file ...')
|
|
portable_version = self.version + '.0' * (3 - self.version.count('.'))
|
|
input = open(os.path.join(self.script_path, 'appinfo.ini.default'), 'r').read()
|
|
output = input.replace('%(display_version)s', self.version)
|
|
output = output.replace('%(package_version)s', portable_version)
|
|
outfile = open(os.path.join(self.portable_path, 'App', 'Appinfo', 'appinfo.ini'), 'w')
|
|
outfile.write(output)
|
|
outfile.close()
|
|
|
|
def run_innosetup(self):
|
|
"""
|
|
Run InnoSetup to create an installer.
|
|
"""
|
|
self._print('Running Inno Setup...')
|
|
os.chdir(self.script_path)
|
|
innosetup = Popen((self.innosetup, os.path.join(self.script_path, 'OpenLP-2.0.iss'), '/q'))
|
|
code = innosetup.wait()
|
|
if code != 0:
|
|
raise Exception('Error running Inno Setup')
|
|
|
|
def run_portableapp_builder(self):
|
|
"""
|
|
Creates a portable installer.
|
|
1 Copies the distribution to the portable apps directory
|
|
2 Builds the PortableApps Launcher
|
|
3 Builds the PortableApps Install
|
|
"""
|
|
self._print('Running PortableApps Builder...')
|
|
self._print(' Clearing old files')
|
|
# Remove previous contents of portableapp build directory.
|
|
if os.path.exists(self.portable_path):
|
|
rmtree(self.portable_path)
|
|
self._print(' Creating PortableApps build directory')
|
|
# Copy the contents of the OpenLPPortable directory to the portable
|
|
# build directory.
|
|
dir_util.copy_tree(os.path.join(self.script_path, 'OpenLPPortable'), self.portable_path)
|
|
self.check_portableapp_directory()
|
|
self.create_portableapps_appinfo_file()
|
|
# Copy distribution files to portableapp build directory.
|
|
self._print(' Copying distribution files')
|
|
portable_app_path = os.path.join(self.portable_path, 'App', 'OpenLP')
|
|
dir_util.copy_tree(self.dist_path, portable_app_path)
|
|
# Copy help files to portableapp build directory.
|
|
if os.path.isfile(os.path.join(self.helpfile_path, 'OpenLP.chm')):
|
|
self._print(' Copying help files')
|
|
dir_util.copy_tree(self.helpfile_path, os.path.join(portable_app_path, 'help'))
|
|
else:
|
|
self._print('... WARNING: Windows help file not found')
|
|
# Build the launcher.
|
|
self._print(' Building PortableApps Launcher')
|
|
portableapps = Popen((self.portablelauncher, self.portable_path), stdout=PIPE)
|
|
code = portableapps.wait()
|
|
if code != 0:
|
|
raise Exception('Error creating PortableAppa Launcher')
|
|
# Build the portable installer.
|
|
self._print(' Building PortableApps Installer')
|
|
portableapps = Popen((self.portableinstaller, self.portable_path), stdout=PIPE)
|
|
code = portableapps.wait()
|
|
if code != 0:
|
|
raise Exception('Error running PortableApps Installer')
|
|
portable_app = os.path.abspath(os.path.join(self.portable_path, '..',
|
|
'OpenLPPortable_%s.paf.exe' % self.version))
|
|
if os.path.exists(portable_app):
|
|
move(portable_app, os.path.abspath(os.path.join(self.dist_path, '..')))
|
|
self._print(' PortableApp build complete')
|
|
else:
|
|
raise Exception('PortableApp failed to build')
|
|
|
|
def build_pptviewlib(self):
|
|
"""
|
|
Build the PowerPoint Viewer DLL using Visual Studio.
|
|
"""
|
|
self._print('Building PPTVIEWLIB.DLL...')
|
|
if not os.path.exists(self.vcbuild):
|
|
self._print('... WARNING: vcbuild.exe was not found, skipping building pptviewlib.dll')
|
|
return
|
|
vcbuild = Popen((self.vcbuild, '/rebuild', os.path.join(self.pptviewlib_path, 'pptviewlib.vcproj'),
|
|
'Release|Win32'))
|
|
code = vcbuild.wait()
|
|
if code != 0:
|
|
raise Exception('Error building pptviewlib.dll')
|
|
copy(os.path.join(self.pptviewlib_path, 'Release', 'pptviewlib.dll'), self.pptviewlib_path)
|
|
|
|
def main(self):
|
|
"""
|
|
The main function to run the Windows builder.
|
|
"""
|
|
self._print_verbose('OpenLP main script: ......%s', self.openlp_script)
|
|
self._print_verbose('Script path: .............%s', os.path.dirname(os.path.abspath(__file__)))
|
|
self._print_verbose('Branch path: .............%s', self.branch_path)
|
|
self._print_verbose('Source path: .............%s', self.source_path)
|
|
self._print_verbose('Dist path: ...............%s', self.dist_path)
|
|
self._print_verbose('Portable path: ...........%s', self.portable_path)
|
|
self._print_verbose('PyInstaller: .............%s', self.pyinstaller)
|
|
self._print_verbose('Documentation branch path:%s', self.docs_path)
|
|
self._print_verbose('Help file build path: ....%s', self.helpfile_path)
|
|
self._print_verbose('Inno Setup path: .........%s', self.innosetup)
|
|
self._print_verbose('PortableApp Launcher......%s', self.portablelauncher)
|
|
self._print_verbose('PortableApp Installer.....%s', self.portableinstaller)
|
|
self._print_verbose('Windows resources: .......%s', self.winres_path)
|
|
self._print_verbose('VCBuild path: ............%s', self.vcbuild)
|
|
self._print_verbose('PPTVIEWLIB path: .........%s', self.pptviewlib_path)
|
|
self._print_verbose('Mudraw binary ............%s', self.mudraw_bin)
|
|
self._print_verbose('')
|
|
if not self.args.skip_update:
|
|
self.update_code()
|
|
self.build_pptviewlib()
|
|
self.run_pyinstaller()
|
|
self.write_version_file()
|
|
self.copy_default_theme()
|
|
self.copy_plugins()
|
|
self.copy_media_player()
|
|
if os.path.exists(self.manual_path):
|
|
self.run_sphinx()
|
|
self.run_htmlhelp()
|
|
else:
|
|
self._print('')
|
|
self._print('WARNING: Documentation trunk not found. Windows')
|
|
self._print(' Help file will not be included in build')
|
|
self._print('')
|
|
self.copy_windows_files()
|
|
if not self.args.skip_translations:
|
|
self.update_translations()
|
|
self.compile_translations()
|
|
self.create_innosetup_file()
|
|
self.run_innosetup()
|
|
if self.args.portable:
|
|
self.run_portableapp_builder()
|
|
self._print('Done.')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
WindowsBuilder().main()
|