From 1bf15a053d6fe20a29cf6b047e51411df80eae45 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 26 Mar 2016 19:54:07 +0100 Subject: [PATCH 01/15] tox: Add a pyinstaller env --- tox.ini | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tox.ini b/tox.ini index 45306446f..1131141f0 100644 --- a/tox.ini +++ b/tox.ini @@ -208,6 +208,16 @@ commands = {envpython} scripts/link_pyqt.py --tox {envdir} {envpython} scripts/dev/freeze.py {posargs} +[testenv:pyinstaller] +basepython = python3 +-skip_install = true +deps = + -r{toxinidir}/requirements.txt + PyInstaller==3.1.1 +commands = + {envpython} scripts/link_pyqt.py --tox {envdir} + {envbindir}/pyinstaller --noconfirm misc/qutebrowser.spec + [testenv:eslint] skip_install = True deps = From b505c658731af23c766e1b17abeea067f976ac33 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 26 Mar 2016 19:54:19 +0100 Subject: [PATCH 02/15] pyinstaller: Add basic qutebrowser.spec --- misc/qutebrowser.spec | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 misc/qutebrowser.spec diff --git a/misc/qutebrowser.spec b/misc/qutebrowser.spec new file mode 100644 index 000000000..05a058624 --- /dev/null +++ b/misc/qutebrowser.spec @@ -0,0 +1,33 @@ +# -*- mode: python -*- + +block_cipher = None + + +a = Analysis(['../qutebrowser.py'], + pathex=['misc'], + binaries=None, + datas=None, + hiddenimports=[], + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher) +pyz = PYZ(a.pure, a.zipped_data, + cipher=block_cipher) +exe = EXE(pyz, + a.scripts, + exclude_binaries=True, + name='qutebrowser', + debug=False, + strip=False, + upx=True, + console=False ) +coll = COLLECT(exe, + a.binaries, + a.zipfiles, + a.datas, + strip=False, + upx=True, + name='qutebrowser') From f24a721e55bd98fdc62c6ba977ab3f91d1dfe259 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 26 Mar 2016 20:27:23 +0100 Subject: [PATCH 03/15] pyinstaller: Include data files This makes the following things work: - Error pages - Caret mode - pdfjs - :help --- misc/qutebrowser.spec | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/misc/qutebrowser.spec b/misc/qutebrowser.spec index 05a058624..cef325c6d 100644 --- a/misc/qutebrowser.spec +++ b/misc/qutebrowser.spec @@ -3,10 +3,26 @@ block_cipher = None +def get_data_files(): + data_files = [ + ('../qutebrowser/html', 'html'), + ('../qutebrowser/img', 'img'), + ('../qutebrowser/javascript', 'javascript'), + ('../qutebrowser/html/doc', 'html/doc'), + ] + + if os.path.exists(os.path.join('qutebrowser', '3rdparty', 'pdfjs')): + data_files.append(('../qutebrowser/3rdparty/pdfjs', '3rdparty/pdfjs')) + else: + print("Warning: excluding pdfjs as it's not present!") + + return data_files + + a = Analysis(['../qutebrowser.py'], pathex=['misc'], binaries=None, - datas=None, + datas=get_data_files(), hiddenimports=[], hookspath=[], runtime_hooks=[], From 2f8ce31e1a4cf45de58b57252a4b6dd5041f865e Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 26 Mar 2016 21:48:21 +0100 Subject: [PATCH 04/15] pyinstaller: Add git-commit-id file --- misc/qutebrowser.spec | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/misc/qutebrowser.spec b/misc/qutebrowser.spec index cef325c6d..a9179a69e 100644 --- a/misc/qutebrowser.spec +++ b/misc/qutebrowser.spec @@ -1,5 +1,11 @@ # -*- mode: python -*- +import sys +import os + +sys.path.insert(0, os.getcwd()) +from scripts import setupcommon + block_cipher = None @@ -9,6 +15,7 @@ def get_data_files(): ('../qutebrowser/img', 'img'), ('../qutebrowser/javascript', 'javascript'), ('../qutebrowser/html/doc', 'html/doc'), + ('../qutebrowser/git-commit-id', '') ] if os.path.exists(os.path.join('qutebrowser', '3rdparty', 'pdfjs')): @@ -19,6 +26,9 @@ def get_data_files(): return data_files +setupcommon.write_git_file() + + a = Analysis(['../qutebrowser.py'], pathex=['misc'], binaries=None, From 460f613fecbd78f22ecb4671a9fd612a4ca1fffc Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 26 Mar 2016 21:55:47 +0100 Subject: [PATCH 05/15] pyinstaller: Set icon --- misc/qutebrowser.spec | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/misc/qutebrowser.spec b/misc/qutebrowser.spec index a9179a69e..288b50b6a 100644 --- a/misc/qutebrowser.spec +++ b/misc/qutebrowser.spec @@ -29,6 +29,14 @@ def get_data_files(): setupcommon.write_git_file() +if os.name == 'nt': + icon = 'icons/qutebrowser.ico' +elif sys.platform == 'darwin': + icon = 'icons/qutebrowser.icns' +else: + icon = None + + a = Analysis(['../qutebrowser.py'], pathex=['misc'], binaries=None, @@ -46,6 +54,7 @@ exe = EXE(pyz, a.scripts, exclude_binaries=True, name='qutebrowser', + icon=icon, debug=False, strip=False, upx=True, From bfb4f20510573564bb394b5f7489a6eff64a4a3b Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 30 Mar 2016 23:28:44 +0200 Subject: [PATCH 06/15] pyinstaller: Build a single-executable app --- misc/qutebrowser.spec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/misc/qutebrowser.spec b/misc/qutebrowser.spec index 288b50b6a..d9e53e13c 100644 --- a/misc/qutebrowser.spec +++ b/misc/qutebrowser.spec @@ -66,3 +66,8 @@ coll = COLLECT(exe, strip=False, upx=True, name='qutebrowser') + +app = BUNDLE(coll, + name='qutebrowser.app', + icon=icon, + bundle_identifier=None) From ae41a074e8c7e0c9e4808a440722f41d9fe090c8 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 6 Apr 2016 20:34:09 +0200 Subject: [PATCH 07/15] build_release: Add basic OS X build --- scripts/dev/build_release.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/scripts/dev/build_release.py b/scripts/dev/build_release.py index 57fa1d724..3a8f8305b 100755 --- a/scripts/dev/build_release.py +++ b/scripts/dev/build_release.py @@ -50,17 +50,18 @@ def call_script(name, *args, python=sys.executable): subprocess.check_call([python, path] + list(args)) -def call_freeze(*args, python=sys.executable): - """Call freeze.py via tox. +def call_tox(toxenv, *args, python=sys.executable): + """Call tox. Args: + toxenv: Which tox environment to use *args: The arguments to pass. python: The python interpreter to use. """ env = os.environ.copy() env['PYTHON'] = python subprocess.check_call( - [sys.executable, '-m', 'tox', '-e', 'cxfreeze-windows'] + list(args), + [sys.executable, '-m', 'tox', '-e', toxenv] + list(args), env=env) @@ -88,6 +89,12 @@ def smoke_test(executable): '--temp-basedir', 'about:blank', ':later 500 quit']) +def build_osx(): + """Build OS X .dmg/.app.""" + utils.print_title("Building .app via pyinstaller") + call_tox('pyinstaller') + + def build_windows(): """Build windows executables/setups.""" utils.print_title("Updating 3rdparty content") @@ -101,13 +108,13 @@ def build_windows(): python_x64 = r'C:\Python{}'.format(ver) utils.print_title("Running 32bit freeze.py build_exe") - call_freeze('build_exe', python=python_x86) + call_tox('cxfreeze-windows', 'build_exe', python=python_x86) utils.print_title("Running 32bit freeze.py bdist_msi") - call_freeze('bdist_msi', python=python_x86) + call_tox('cxfreeze-windows', 'bdist_msi', python=python_x86) utils.print_title("Running 64bit freeze.py build_exe") - call_freeze('build_exe', python=python_x64) + call_tox('cxfreeze-windows', 'build_exe', python=python_x64) utils.print_title("Running 64bit freeze.py bdist_msi") - call_freeze('bdist_msi', python=python_x64) + call_tox('cxfreeze-windows', 'bdist_msi', python=python_x64) utils.print_title("Running 32bit smoke test") smoke_test('build/exe.win32-{}/qutebrowser.exe'.format(dotver)) @@ -201,6 +208,8 @@ def main(): sys.exit(1) run_asciidoc2html(args) build_windows() + elif sys.platform == 'darwin': + build_osx() else: build_sdist() From 362837e98c9bb5e39b6efed1872d4ecb4145f7be Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 6 Apr 2016 20:39:24 +0200 Subject: [PATCH 08/15] update_3rdparty: Add fancy-dmg Makefile --- scripts/dev/update_3rdparty.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/scripts/dev/update_3rdparty.py b/scripts/dev/update_3rdparty.py index f53135a99..eeadd14a4 100755 --- a/scripts/dev/update_3rdparty.py +++ b/scripts/dev/update_3rdparty.py @@ -81,6 +81,18 @@ def update_pdfjs(target_version=None): urllib.request.urlcleanup() +def update_dmg_makefile(): + """Update fancy-dmg Makefile + + See https://el-tramo.be/blog/fancy-dmg/ + """ + print("Updating fancy-dmg Makefile...") + url = 'https://raw.githubusercontent.com/remko/fancy-dmg/master/Makefile' + target_path = os.path.join('scripts', 'dev', 'Makefile-dmg') + urllib.request.urlretrieve(url, target_path) + urllib.request.urlcleanup() + + def main(): parser = argparse.ArgumentParser() parser.add_argument( @@ -88,9 +100,14 @@ def main(): help='Specify pdfjs version. If not given, ' 'the latest version is used.', required=False, metavar='VERSION') + parser.add_argument('--fancy-dmg', help="Update fancy-dmg Makefile", + action='store_true') args = parser.parse_args() update_pdfjs(args.pdfjs) + if args.fancy_dmg: + update_dmg_makefile() + if __name__ == '__main__': main() From 533b9d22e7d4339115077416d78587bfd722f8a0 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 6 Apr 2016 20:39:37 +0200 Subject: [PATCH 09/15] Add fancy-dmg Makefile --- scripts/dev/Makefile-dmg | 76 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 scripts/dev/Makefile-dmg diff --git a/scripts/dev/Makefile-dmg b/scripts/dev/Makefile-dmg new file mode 100644 index 000000000..1e5b7b3ce --- /dev/null +++ b/scripts/dev/Makefile-dmg @@ -0,0 +1,76 @@ +# +# Build file for creating DMG files. +# +# The DMG packager looks for a template.dmg.bz2 for using as its +# DMG template. If it doesn't find one, it generates a clean one. +# +# If you create a DMG template, you should make one containing all +# the files listed in $(SOURCE_FILES) below, and arrange everything to suit +# your style. The contents of the files themselves does not matter, so +# they can be empty (they will be overwritten later). +# +# Remko Tronçon +# https://el-tramo.be +# Licensed under the MIT License. See COPYING for details. + + +################################################################################ +# Customizable variables +################################################################################ + +NAME ?= MyApp +VERSION ?= 0.1 + +SOURCE_DIR ?= src +SOURCE_FILES ?= MyApp.app README COPYING + +TEMPLATE_DMG ?= template.dmg +TEMPLATE_SIZE ?= 40m + +################################################################################ +# DMG building. No editing should be needed beyond this point. +################################################################################ + +MASTER_DMG=$(NAME)-$(VERSION).dmg +WC_DMG=wc.dmg +WC_DIR=wc + +.PHONY: all +all: $(MASTER_DMG) + +$(TEMPLATE_DMG): $(TEMPLATE_DMG).bz2 + bunzip2 -k $< + +$(TEMPLATE_DMG).bz2: + @echo + @echo --------------------- Generating empty template -------------------- + mkdir template + hdiutil create -fs HFSX -layout SPUD -size $(TEMPLATE_SIZE) "$(TEMPLATE_DMG)" -srcfolder template -format UDRW -volname "$(NAME)" -quiet + rmdir template + bzip2 "$(TEMPLATE_DMG)" + @echo + +$(WC_DMG): $(TEMPLATE_DMG) + cp $< $@ + +$(MASTER_DMG): $(WC_DMG) $(addprefix $(SOURCE_DIR)/,$(SOURCE_FILES)) + @echo + @echo --------------------- Creating Disk Image -------------------- + mkdir -p $(WC_DIR) + hdiutil attach "$(WC_DMG)" -noautoopen -quiet -mountpoint "$(WC_DIR)" + for i in $(SOURCE_FILES); do \ + rm -rf "$(WC_DIR)/$$i"; \ + ditto -rsrc "$(SOURCE_DIR)/$$i" "$(WC_DIR)/$$i"; \ + done + #rm -f "$@" + #hdiutil create -srcfolder "$(WC_DIR)" -format UDZO -imagekey zlib-level=9 "$@" -volname "$(NAME) $(VERSION)" -scrub -quiet + WC_DEV=`hdiutil info | grep "$(WC_DIR)" | grep "Apple_HFS" | awk '{print $$1}'` && \ + hdiutil detach $$WC_DEV -quiet -force + rm -f "$(MASTER_DMG)" + hdiutil convert "$(WC_DMG)" -quiet -format UDZO -imagekey zlib-level=9 -o "$@" + rm -rf $(WC_DIR) + @echo + +.PHONY: clean +clean: + -rm -rf $(TEMPLATE_DMG) $(MASTER_DMG) $(WC_DMG) From 97cb429b57c48d2305e569112d0b696d99c06035 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 6 Apr 2016 21:21:48 +0200 Subject: [PATCH 10/15] Makefile-dmg: Set variables --- scripts/dev/Makefile-dmg | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/scripts/dev/Makefile-dmg b/scripts/dev/Makefile-dmg index 1e5b7b3ce..d18d39fdf 100644 --- a/scripts/dev/Makefile-dmg +++ b/scripts/dev/Makefile-dmg @@ -18,20 +18,19 @@ # Customizable variables ################################################################################ -NAME ?= MyApp -VERSION ?= 0.1 +NAME ?= qutebrowser -SOURCE_DIR ?= src -SOURCE_FILES ?= MyApp.app README COPYING +SOURCE_DIR ?= . +SOURCE_FILES ?= dist/qutebrowser.app COPYING TEMPLATE_DMG ?= template.dmg -TEMPLATE_SIZE ?= 40m +TEMPLATE_SIZE ?= 120m ################################################################################ # DMG building. No editing should be needed beyond this point. ################################################################################ -MASTER_DMG=$(NAME)-$(VERSION).dmg +MASTER_DMG=$(NAME).dmg WC_DMG=wc.dmg WC_DIR=wc From 03be10b4fe8bca8d7c4ef4bf85bafd52a345865a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 6 Apr 2016 21:21:55 +0200 Subject: [PATCH 11/15] Makefile-dmg: Copy files from subdirs We don't want a /dist/qutebrowser.app in the dmg, only a /qutebrowser.app. --- scripts/dev/Makefile-dmg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dev/Makefile-dmg b/scripts/dev/Makefile-dmg index d18d39fdf..17c48b7e0 100644 --- a/scripts/dev/Makefile-dmg +++ b/scripts/dev/Makefile-dmg @@ -59,7 +59,7 @@ $(MASTER_DMG): $(WC_DMG) $(addprefix $(SOURCE_DIR)/,$(SOURCE_FILES)) hdiutil attach "$(WC_DMG)" -noautoopen -quiet -mountpoint "$(WC_DIR)" for i in $(SOURCE_FILES); do \ rm -rf "$(WC_DIR)/$$i"; \ - ditto -rsrc "$(SOURCE_DIR)/$$i" "$(WC_DIR)/$$i"; \ + ditto -rsrc "$(SOURCE_DIR)/$$i" "$(WC_DIR)/$${i##*/}"; \ done #rm -f "$@" #hdiutil create -srcfolder "$(WC_DIR)" -format UDZO -imagekey zlib-level=9 "$@" -volname "$(NAME) $(VERSION)" -scrub -quiet From 39844374842f220c7e1da440f445e6340c4e5d0f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 6 Apr 2016 21:22:30 +0200 Subject: [PATCH 12/15] build_release: Build dmg via Makefile-dmg --- scripts/dev/build_release.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/dev/build_release.py b/scripts/dev/build_release.py index 3a8f8305b..a3598f99b 100755 --- a/scripts/dev/build_release.py +++ b/scripts/dev/build_release.py @@ -93,6 +93,13 @@ def build_osx(): """Build OS X .dmg/.app.""" utils.print_title("Building .app via pyinstaller") call_tox('pyinstaller') + utils.print_title("Building .dmg") + subprocess.check_call(['make', '-f', 'scripts/dev/Makefile-dmg']) + utils.print_title("Cleaning up...") + for f in ['wc.dmg', 'template.dmg']: + os.remove(f) + for d in ['dist', 'build']: + shutil.rmtree(d) def build_windows(): From 3f0429574ced02de8b6fb3bd1b148107e9c98b4d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 6 Apr 2016 21:26:31 +0200 Subject: [PATCH 13/15] Makefile-dmg: Add /Applications link to dmg --- scripts/dev/Makefile-dmg | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/dev/Makefile-dmg b/scripts/dev/Makefile-dmg index 17c48b7e0..1ecdb1514 100644 --- a/scripts/dev/Makefile-dmg +++ b/scripts/dev/Makefile-dmg @@ -61,6 +61,7 @@ $(MASTER_DMG): $(WC_DMG) $(addprefix $(SOURCE_DIR)/,$(SOURCE_FILES)) rm -rf "$(WC_DIR)/$$i"; \ ditto -rsrc "$(SOURCE_DIR)/$$i" "$(WC_DIR)/$${i##*/}"; \ done + ln -s /Applications $(WC_DIR) #rm -f "$@" #hdiutil create -srcfolder "$(WC_DIR)" -format UDZO -imagekey zlib-level=9 "$@" -volname "$(NAME) $(VERSION)" -scrub -quiet WC_DEV=`hdiutil info | grep "$(WC_DIR)" | grep "Apple_HFS" | awk '{print $$1}'` && \ From 0e6bada68f6f7dc6f6adf0008ac23a9695fd9c0b Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 6 Apr 2016 21:37:06 +0200 Subject: [PATCH 14/15] build_release: Build docs/update 3rdparty on OS X --- scripts/dev/build_release.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/dev/build_release.py b/scripts/dev/build_release.py index a3598f99b..659407ae2 100755 --- a/scripts/dev/build_release.py +++ b/scripts/dev/build_release.py @@ -91,6 +91,8 @@ def smoke_test(executable): def build_osx(): """Build OS X .dmg/.app.""" + utils.print_title("Updating 3rdparty content") + update_3rdparty.update_pdfjs() utils.print_title("Building .app via pyinstaller") call_tox('pyinstaller') utils.print_title("Building .dmg") @@ -216,6 +218,7 @@ def main(): run_asciidoc2html(args) build_windows() elif sys.platform == 'darwin': + run_asciidoc2html(args) build_osx() else: build_sdist() From d507727bb3776f87c4d10319bebd974a65745e97 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 13 May 2016 05:23:19 +0200 Subject: [PATCH 15/15] tox: Update PyInstaller to 3.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Even the “main” script is now byte-compiled - The manual is on readthedocs.io now - On installation try to compile the bootloader if there is none for the current plattform - (Unix) Use objcopy to create a valid ELF file - (Linux): Compile with _FORTIFY_SOURCE - New, updated and fixed hooks: CherryPy, Cryptography, enchant, gi.repository.GdkPixbuf, gst, Lib2to3, PyQt4, PyQt5, PySide, SciPy, sphinx, sqlalchemy, traitlets, wx.lib.pubsub - For windowed mode add isatty() for our dummy NullWriter - Suppress “Failed to execute script” in case of SystemExit - Do not apply Upx compressor for bootloader files - Fix absolute path for lib used via ctypes - (OSX) Fix binary cache on NFS - (Windows) Fix message in grab_version - (Windows) Fix wrong icon paramter in Windows example - (Windows) Fix win32 unicode handling - (Windows) Fix unnecessary rebuilds caused by rebuilding winmanifest - (Cygwin) Fix finding the Python library for Cygwin 64-bit - (OSX) Fix compilation issue - (Windows) No longer bundle pefile, use package from for windows - (Windows) Provide a more robust means of executing a Python script - AIX fixes. - Update waf to version 1.8.20 - Fix excludedimports, more predictable order how hooks are applied - Internal impovements and code clean-up - Clean-ups fixes and improvements for the test suite --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 1131141f0..f19007c4d 100644 --- a/tox.ini +++ b/tox.ini @@ -213,7 +213,7 @@ basepython = python3 -skip_install = true deps = -r{toxinidir}/requirements.txt - PyInstaller==3.1.1 + PyInstaller==3.2 commands = {envpython} scripts/link_pyqt.py --tox {envdir} {envbindir}/pyinstaller --noconfirm misc/qutebrowser.spec