A few fixes to the macOS builder, and fix up the Windows builder

This commit is contained in:
Raoul Snyman 2016-12-05 20:23:50 +02:00
parent 05dde36a9e
commit f4f7fc9cad
3 changed files with 234 additions and 283 deletions

View File

@ -103,7 +103,7 @@ from macholib.util import flipwritable, in_system_path
from builder import Builder
class MacosxBuilder(Builder):
class MacOSXBuilder(Builder):
"""
The :class:`MacosxBuilder` class encapsulates everything that is needed
to build a Mac OS X .dmg file.
@ -119,75 +119,7 @@ class MacosxBuilder(Builder):
dir_size += os.path.getsize(filename)
return dir_size
def get_sphinx_build(self):
"""
The type of build Sphinx should be doing
"""
return 'applehelp'
def setup_paths(self):
"""
Extra setup to run
"""
super().setup_paths()
if hasattr(self, 'mutool_exe'):
self.mutool_lib = os.path.abspath(
os.path.join(os.path.dirname(self.mutool_exe), '..', 'lib', 'libjbig2dec.0.dylib'))
self.dist_app_path = os.path.join(self.work_path, 'dist', 'OpenLP.app')
self.dist_path = os.path.join(self.work_path, 'dist', 'OpenLP.app', 'Contents', 'MacOS')
def copy_extra_files(self):
"""
Copy any extra files which are particular to a platform
"""
self._copy_bundle_files()
self._copy_macosx_files()
def _copy_bundle_files(self):
"""
Copy Info.plist and OpenLP.icns to app bundle.
"""
copy(self.icon_path, os.path.join(self.dist_app_path, 'Contents', 'Resources', os.path.basename(self.icon_path)))
# Add OpenLP version to Info.plist and put it to app bundle.
fr = open(self.bundle_info_path, 'r')
fw = open(os.path.join(self.dist_app_path, 'Contents', os.path.basename(self.bundle_info_path)), 'w')
text = fr.read()
text = text % {'openlp_version': self.version}
fw.write(text)
fr.close()
fw.close()
def _copy_macosx_files(self):
"""
Copy all the OSX-specific files.
"""
self._print('Copying extra files for Mac OS X...')
self._print_verbose('... LICENSE.txt')
copy(self.license_path, os.path.join(self.dist_path, 'LICENSE.txt'))
self._print_verbose('... mudraw')
if hasattr(self, 'mudraw_exe') and self.mudraw_exe and os.path.isfile(self.mudraw_exe):
copy(self.mudraw_exe, os.path.join(self.dist_path, 'mudraw'))
self.relink_mudraw()
elif hasattr(self, 'mutool_exe') and self.mutool_exe and os.path.isfile(self.mutool_exe):
copy(self.mutool_exe, os.path.join(self.dist_path, 'mutool'))
self.relink_mutool()
copy(self.mutool_lib, os.path.join(self.dist_path, 'libjbig2dec.0.dylib'))
else:
self._print('... WARNING: mudraw and mutool not found')
def relink_mudraw(self):
"""
Relink mudraw to bundled libraries
"""
self.relink_mupdf('mudraw')
def relink_mutool(self):
"""
Relink mudraw to bundled libraries
"""
self.relink_mupdf('mutool')
def relink_mupdf(self, bin_name):
def _relink_mupdf(self, bin_name):
"""
Relink mupdf to bundled libraries
"""
@ -233,6 +165,116 @@ class MacosxBuilder(Builder):
except Exception:
pass
def _relink_mudraw(self):
"""
Relink mudraw to bundled libraries
"""
self._relink_mupdf('mudraw')
def _relink_mutool(self):
"""
Relink mudraw to bundled libraries
"""
self._relink_mupdf('mutool')
def _copy_bundle_files(self):
"""
Copy Info.plist and OpenLP.icns to app bundle.
"""
copy(self.icon_path, os.path.join(self.dist_app_path, 'Contents', 'Resources', os.path.basename(self.icon_path)))
# Add OpenLP version to Info.plist and put it to app bundle.
fr = open(self.bundle_info_path, 'r')
fw = open(os.path.join(self.dist_app_path, 'Contents', os.path.basename(self.bundle_info_path)), 'w')
text = fr.read()
text = text % {'openlp_version': self.version}
fw.write(text)
fr.close()
fw.close()
def _copy_macosx_files(self):
"""
Copy all the OSX-specific files.
"""
self._print('Copying extra files for Mac OS X...')
self._print_verbose('... LICENSE.txt')
copy(self.license_path, os.path.join(self.dist_path, 'LICENSE.txt'))
self._print_verbose('... mudraw')
if hasattr(self, 'mudraw_exe') and self.mudraw_exe and os.path.isfile(self.mudraw_exe):
copy(self.mudraw_exe, os.path.join(self.dist_path, 'mudraw'))
self._relink_mudraw()
elif hasattr(self, 'mutool_exe') and self.mutool_exe and os.path.isfile(self.mutool_exe):
copy(self.mutool_exe, os.path.join(self.dist_path, 'mutool'))
self._relink_mutool()
copy(self.mutool_lib, os.path.join(self.dist_path, 'libjbig2dec.0.dylib'))
else:
self._print('... WARNING: mudraw and mutool not found')
def _code_sign(self):
certificate = self.config.get('codesigning', 'certificate')
self._print('Checking for certificate...')
self._run_command(['security', 'find-certificate', '-c', certificate],
'Could not find certificate "{certificate}" in keychain, '.format(certificate=certificate) +
'codesigning will not work without a certificate')
self._print('Codesigning app...')
self._run_command(['codesign', '--deep', '-s', certificate, self.dist_app_path], 'Error running codesign')
def _create_dmg(self):
"""
Create .dmg file.
"""
self._print('Creating dmg file...')
dmg_name = 'OpenLP-{version}.dmg'.format(version=self.version)
dmg_title = 'OpenLP {version}'.format(version=self.version)
self.dmg_file = os.path.join(self.work_path, 'dist', dmg_name)
# Remove dmg if it exists.
if os.path.exists(self.dmg_file):
os.remove(self.dmg_file)
# Get size of the directory in bytes, convert to MB, and add padding
size = self._get_directory_size(self.dist_app_path)
size = size / (1000 * 1000)
size += 10
self._print_verbose('... %s' % self.script_path)
os.chdir(os.path.dirname(self.dmg_settings_path))
self._run_command([self.dmgbuild_exe, '-s', self.dmg_settings_path, '-D', 'size={size}M'.format(size=size),
'-D', 'icon={icon_path}'.format(icon_path=self.icon_path),
'-D', 'app={dist_app_path}'.format(dist_app_path=self.dist_app_path), dmg_title, self.dmg_file],
'Unable to run dmgbuild')
# Dmg done.
self._print('Finished creating dmg file, resulting file: %s' % self.dmg_file)
def get_platform(self):
"""
Return the plaform we're building for
"""
return 'Mac OS X'
def get_sphinx_build(self):
"""
The type of build Sphinx should be doing
"""
return 'applehelp'
def setup_paths(self):
"""
Extra setup to run
"""
super().setup_paths()
if hasattr(self, 'mutool_exe'):
self.mutool_lib = os.path.abspath(
os.path.join(os.path.dirname(self.mutool_exe), '..', 'lib', 'libjbig2dec.0.dylib'))
self.dist_app_path = os.path.join(self.work_path, 'dist', 'OpenLP.app')
self.dist_path = os.path.join(self.work_path, 'dist', 'OpenLP.app', 'Contents', 'MacOS')
def copy_extra_files(self):
"""
Copy any extra files which are particular to a platform
"""
self._copy_bundle_files()
self._copy_macosx_files()
def after_run_sphinx(self):
"""
Run Sphinx to build an HTML Help project.
@ -250,45 +292,9 @@ class MacosxBuilder(Builder):
"""
Build the actual DMG
"""
self.code_sign()
self.create_dmg()
def code_sign(self):
certificate = self.config.get('codesigning', 'certificate')
self._print('Checking for certificate...')
self._run_command(['security', 'find-certificate', '-c', certificate],
'Could not find certificate "{certificate}" in keychain, '.format(certificate=certificate) +
'codesigning will not work without a certificate')
self._print('Codesigning app...')
self._run_command(['codesign', '--deep', '-s', certificate, self.dist_app_path], 'Error running codesign')
def create_dmg(self):
"""
Create .dmg file.
"""
self._print('Creating dmg file...')
dmg_name = 'OpenLP-{version}.dmg'.format(version=self.version)
dmg_title = 'OpenLP {version}'.format(version=self.version)
self.dmg_file = os.path.join(self.work_path, 'dist', dmg_name)
# Remove dmg if it exists.
if os.path.exists(self.dmg_file):
os.remove(self.dmg_file)
# Get size of the directory in bytes, convert to MB, and add padding
size = self._get_directory_size(self.dist_app_path)
size = size / (1000 * 1000)
size += 10
self._print('... %s' % self.script_path)
os.chdir(os.path.dirname(self.dmg_settings_path))
self._run_command([self.dmgbuild_exe, '-s', self.dmg_settings_path, '-D', 'size={size}M'.format(size=size),
'-D', 'icon={icon_path}'.format(icon_path=self.icon_path),
'-D', 'app={dist_app_path}'.format(dist_app_path=self.dist_app_path), dmg_title, self.dmg_file],
'Unable to run dmgbuild')
# Dmg done.
self._print('Finished creating dmg file, resulting file: %s' % self.dmg_file)
self._code_sign()
self._create_dmg()
if __name__ == '__main__':
MacosxBuilder().main()
MacOSXBuilder().main()

View File

@ -19,7 +19,6 @@
# 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
--------------------
@ -39,7 +38,7 @@ PyEnchant
installed. You can find this on the PyEnchant site.
Inno Setup 5
Inno Setup should be installed into "C:\%PROGRAMFILES%\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
@ -58,7 +57,7 @@ Bazaar
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".
structure like this: "openlp\\branch-name".
Visual C++ 2008 Express Edition
This is to build pptviewlib.dll, the library for controlling the
@ -73,14 +72,14 @@ psvince.dll
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)
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
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
@ -116,12 +115,8 @@ Portable App Builds
"""
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
from shutil import copy, move, rmtree
from builder import Builder
@ -131,6 +126,107 @@ class WindowsBuilder(Builder):
The :class:`WindowsBuilder` class encapsulates everything that is needed
to build a Windows installer.
"""
def _build_pptviewlib(self):
"""
Build the PowerPoint Viewer DLL using Visual Studio.
"""
self._print('Building PPTVIEWLIB.DLL...')
if not os.path.exists(self.vcbuild_exe):
self._print('... WARNING: vcbuild.exe was not found, skipping building pptviewlib.dll')
return
self._run_command([self.vcbuild_exe, '/rebuild', os.path.join(self.pptviewlib_path, 'pptviewlib.vcproj'),
'Release|Win32'], 'Error building pptviewlib.dll')
copy(os.path.join(self.pptviewlib_path, 'Release', 'pptviewlib.dll'), self.pptviewlib_path)
def _create_innosetup_file(self):
"""
Create an InnoSetup file pointing to the branch being built.
"""
self._print('Creating Inno Setup file...')
with open(os.path.join(self.script_path, 'OpenLP.iss.default'), 'r') as input_file, \
open(os.path.join(self.script_path, 'OpenLP.iss'), 'w') as output_file:
content = input_file.read()
content = content.replace('%(branch)s', self.branch_path)
content = content.replace('%(display_version)s', self.version)
output_file.write(content)
def _run_innosetup(self):
"""
Run InnoSetup to create an installer.
"""
self._print('Running Inno Setup...')
os.chdir(self.script_path)
self._run_command([self.innosetup_exe, os.path.join(self.script_path, 'OpenLP.iss'), '/q'],
'Error running InnoSetup')
def _create_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.replace('-', '.') + '.0' * (3 - self.version.count('.'))
with open(os.path.join(self.script_path, 'appinfo.ini.default'), 'r') as input_file, \
open(os.path.join(self.portable_path, 'App', 'Appinfo', 'appinfo.ini'), 'w') as output_file:
content = input_file.read()
content = content.replace('%(display_version)s', self.version)
content = content.replace('%(package_version)s', portable_version)
output_file.write(content)
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.
self._create_portableapp_directory()
self._create_portableapps_appinfo_file()
dir_util.copy_tree(os.path.join(self.script_path, 'OpenLPPortable'), self.portable_path)
# 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')
self_run_command([self.portablelauncher_exe, self.portable_path], 'Error creating PortableAppa Launcher')
# Build the portable installer.
self._print(' Building PortableApps Installer')
self._run_command([self.portableinstaller_exe, self.portable_path], 'Error running PortableApps Installer')
portable_app = os.path.abspath(os.path.join(self.portable_path, '..',
'OpenLPPortable_%s.paf.exe' % self.version.replace('-', '.')))
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 get_platform(self):
"""
Return the platform we're building for
@ -195,20 +291,20 @@ class WindowsBuilder(Builder):
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'))
copy(self.psvince_exe, 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('... mutool.exe')
if self.mutoolbin and os.path.isfile(self.mutoolbin):
copy(os.path.join(self.mutoolbin), os.path.join(self.dist_path, 'mutool.exe'))
if self.mutool_exe and os.path.isfile(self.mutool_exe):
copy(os.path.join(self.mutool_exe), os.path.join(self.dist_path, 'mutool.exe'))
else:
self._print('... WARNING: mutool.exe not found')
self._print_verbose('... MediaInfo.exe')
if self.mediainfo_bin and os.path.isfile(self.mediainfo_bin):
copy(os.path.join(self.mediainfo_bin), os.path.join(self.dist_path, 'MediaInfo.exe'))
if self.mediainfo_exe and os.path.isfile(self.mediainfo_exe):
copy(os.path.join(self.mediainfo_exe), os.path.join(self.dist_path, 'MediaInfo.exe'))
else:
self._print('... WARNING: MediaInfo.exe not found')
@ -218,168 +314,17 @@ class WindowsBuilder(Builder):
"""
self._print('Running HTML Help Workshop...')
os.chdir(os.path.join(self.manual_build_path, 'htmlhelp'))
self._run_command([self.htmlhelp, 'OpenLP.chm'], 'Error running HTML Help Workshop')
self._run_command([self.htmlhelp_exe, 'OpenLP.chm'], 'Error running HTML Help Workshop')
def build_package(self):
"""
Build the installer
"""
self.build_pptviewlib()
self.create_innosetup_file()
self.run_innosetup()
self._build_pptviewlib()
self._create_innosetup_file()
self._run_innosetup()
if self.portable_path and os.path.exists(self.portable_path):
self.run_portableapp_builder()
def build_pptviewlib(self):
"""
Build the PowerPoint Viewer DLL using Visual Studio.
"""
self._print('Building PPTVIEWLIB.DLL...')
if not os.path.exists(self.vcbuild_exe):
self._print('... WARNING: vcbuild.exe was not found, skipping building pptviewlib.dll')
return
self._run_command([self.vcbuild, '/rebuild', os.path.join(self.pptviewlib_path, 'pptviewlib.vcproj'),
'Release|Win32'], 'Error building pptviewlib.dll')
copy(os.path.join(self.pptviewlib_path, 'Release', 'pptviewlib.dll'), self.pptviewlib_path)
def create_innosetup_file(self):
"""
Create an InnoSetup file pointing to the branch being built.
"""
self._print('Creating Inno Setup file...')
with open(os.path.join(self.script_path, 'OpenLP.iss.default'), 'r') as input_file, \
open(os.path.join(self.script_path, 'OpenLP.iss'), 'w') as output_file:
content = input_file.read()
content = content.replace('%(branch)s', self.branch_path)
content = content.replace('%(display_version)s', self.version)
output_file.write(content)
def run_innosetup(self):
"""
Run InnoSetup to create an installer.
"""
self._print('Running Inno Setup...')
os.chdir(self.script_path)
self._run_command([self.innosetup_exe, os.path.join(self.script_path, 'OpenLP.iss'), '/q'],
'Error running InnoSetup')
def create_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.replace('-', '.') + '.0' * (3 - self.version.count('.'))
with open(os.path.join(self.script_path, 'appinfo.ini.default'), 'r') as input_file, \
open(os.path.join(self.portable_path, 'App', 'Appinfo', 'appinfo.ini'), 'w') as output_file:
content = input_file.read()
content = content.replace('%(display_version)s', self.version)
content = content.replace('%(package_version)s', portable_version)
output_file.write(content)
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')
self._run_command([self.portableinstaller, self.portable_path], 'Error running PortableApps Installer')
portable_app = os.path.abspath(os.path.join(self.portable_path, '..',
'OpenLPPortable_%s.paf.exe' % self.version.replace('-', '.')))
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 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.documentation_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('Mutool binary ............%s', self.mutoolbin)
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.')
self._run_portableapp_builder()
if __name__ == '__main__':

View File

@ -8,13 +8,13 @@ psvince = %(here)s\psvince.dll
lrelease = %(sitepackages)s\PyQt5\bin\lrelease.exe
portablelauncher = %(progfiles)s\PortableApps.comLauncher\PortableApps.comLauncherGenerator.exe
portableinstaller = %(progfiles)s\PortableApps.comInstaller\PortableApps.comInstaller.exe
mutoolbin = %(here)s\..\mupdf-1.9a-windows\mutool.exe
mediainfobin = %(here)s\..\MediaInfo\MediaInfo.exe
mutool = %(here)s\..\mupdf-1.9a-windows\mutool.exe
mediainfo = %(here)s\..\MediaInfo\MediaInfo.exe
[paths]
branch = %(projects)s\trunk
documentation = %(projects)s\documentation
win32icon = %(here)s\OpenLP.ico
icon = %(here)s\OpenLP.ico
hooks = %(here)s\..\pyinstaller-hooks
portable = %(projects)s\OpenLPPortable