This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
proj:macdev [2015/03/14 22:07] admin [Ghostscript (gs)] |
proj:macdev [2016/04/21 04:35] (current) admin [Testing Results] |
||
|---|---|---|---|
| Line 4: | Line 4: | ||
| ====== Mac Development Environment ====== | ====== Mac Development Environment ====== | ||
| + | |||
| + | For packaging of latest version, see [[proj:macinstallers]] | ||
| + | |||
| + | This page is relevant to building new template (containing binaries etc). | ||
| + | |||
| + | NOTE - need a new version to handle 10.7 (Lion) upwards. Explanation: | ||
| + | |||
| + | Hi Grant, | ||
| + | | ||
| + | I remembered the reason that for OS X support sometimes being limited to 10.7. | ||
| + | It's because of C++11. The standard library that goes with this, libc++, is only | ||
| + | supported as far back as 10.7. If you want to support earlier versions then all | ||
| + | of the C++ bits need to be built for and linked against the old stdc++ library. | ||
| + | | ||
| + | Cheers | ||
| + | Glenn | ||
| ===== Virtualising Mac OSX ===== | ===== Virtualising Mac OSX ===== | ||
| Line 115: | Line 131: | ||
| I thought I could get away with --with-drivers=PNG but it failed but =FILES dropped it enough (about 17MB) and worked. | I thought I could get away with --with-drivers=PNG but it failed but =FILES dropped it enough (about 17MB) and worked. | ||
| - | --disable-dynamic bakes in a whole lot so gs doesn't try to find it outside e.g. gs_init.ps. | + | --disable-dynamic bakes in a whole lot so gs doesn't try to find it outside e.g. gs_init.ps. No need to have a parallel share/ghostscript/...gs_init.ps |
| ===== convert and gs ===== | ===== convert and gs ===== | ||
| Line 126: | Line 142: | ||
| Success! | Success! | ||
| + | |||
| + | If delegates.xml can't be found, the error message might be something like: | ||
| + | |||
| + | convert: UnableToOpenConfigureFile `delegates`.xml' @warning/configure.c/GetConfigureOptions/706. | ||
| + | |||
| + | If the command used to handle something doesn't work the error message from imagemagick is not very useful. It will be something like: | ||
| + | |||
| + | convert: NoImagesDefined `/Users/g/Desktop/test.png' @error/convert.c/ConvertImageCommand/3212. | ||
| ====== Linking Dependencies to @executable_path ====== | ====== Linking Dependencies to @executable_path ====== | ||
| Line 317: | Line 341: | ||
| * Frameworks | * Frameworks | ||
| * convert | * convert | ||
| + | * gs | ||
| * pdftk | * pdftk | ||
| * wkhtmltopdf | * wkhtmltopdf | ||
| + | * and all the dylibs etc that these libraries require (other than pdftk - see below) | ||
| Also a lib folder containing the dylibs required by pdftk (namely, the contents of /opt/pdflabs/pdftk/lib. pdftk expects its dylibs to be in ../lib) | Also a lib folder containing the dylibs required by pdftk (namely, the contents of /opt/pdflabs/pdftk/lib. pdftk expects its dylibs to be in ../lib) | ||
| Line 337: | Line 363: | ||
| install_name_tool -change '/usr/local/Cellar/imagemagick/6.9.0-3/lib/libMagickCore-6.Q16.2.dylib' '@executable_path/libMagickCore-6.Q16.2.dylib' | install_name_tool -change '/usr/local/Cellar/imagemagick/6.9.0-3/lib/libMagickCore-6.Q16.2.dylib' '@executable_path/libMagickCore-6.Q16.2.dylib' | ||
| + | |||
| + | I have automated this with a script called dependable.py: | ||
| + | |||
| + | #! /usr/local/Cellar/python/2.7.9/bin/python2.7 | ||
| + | # -*- coding: utf-8 -*- | ||
| + | """ | ||
| + | Inspired by http://thecourtsofchaos.com/2013/09/16/how-to-copy-and-relink-binaries-on-osx/ | ||
| + | | ||
| + | Copy everything into a working folder so we don't mess up any original binaries. | ||
| + | | ||
| + | Must run as sudo otherwise no permissions. | ||
| + | """ | ||
| + | from __future__ import print_function | ||
| + | import os | ||
| + | import shutil | ||
| + | import subprocess | ||
| + | | ||
| + | working_folder = "/Users/grantpaton-simpson/Desktop/indeps/" | ||
| + | processed_binpaths = [] | ||
| + | | ||
| + | def relink_dep(working_binpath, dep_path): | ||
| + | """ | ||
| + | working_binpath - never want to change original versions of binaries - only | ||
| + | copies in the working folder. | ||
| + | """ | ||
| + | old_link = dep_path | ||
| + | dep_fname = os.path.split(dep_path)[1] | ||
| + | new_link = "@executable_path/" + dep_fname | ||
| + | retval = subprocess.call(["install_name_tool", "-change", old_link, new_link, | ||
| + | working_binpath]) | ||
| + | if retval != 0: | ||
| + | raise Exception("Problem relinking %s inside %s" % (old_link, working_binpath)) | ||
| + | | ||
| + | def get_deps(orig_binpath, working_folder): | ||
| + | """ | ||
| + | Adjust copy of file originally at orig_binpath so expects dependencies to be in | ||
| + | same path it is in. | ||
| + | | ||
| + | Pass any dep files that have not been processed already back through get_deps. | ||
| + | """ | ||
| + | # check not a repeat | ||
| + | if orig_binpath in processed_binpaths: | ||
| + | print("Not copying or relinking %s. Already handled" % orig_binpath) | ||
| + | return | ||
| + | processed_binpaths.append(orig_binpath) | ||
| + | # make working copy of binary (we never mess with the original) | ||
| + | bin_fname = os.path.split(orig_binpath)[1] | ||
| + | working_binpath = os.path.join(working_folder, bin_fname) | ||
| + | shutil.copy(orig_binpath, working_binpath) | ||
| + | # identify dependencies | ||
| + | output = subprocess.check_output(["otool", "-L", working_binpath]) | ||
| + | dep_path_output = [x.strip().split(" ")[0] for x in output.split("\n") if x.strip() != ""] | ||
| + | if len(dep_path_output) < 2: | ||
| + | print("%s has no dependencies" % working_binpath) | ||
| + | return | ||
| + | else: | ||
| + | # Handle dependencies - flexibly relink to each and send them through again in case | ||
| + | # they have their own dependencies. | ||
| + | dep_paths = dep_path_output[1:] # always displays binary as first item so ignore that one | ||
| + | for dep_path in dep_paths: | ||
| + | relink_dep(working_binpath, dep_path) | ||
| + | get_deps(dep_path, working_folder) # back down the rabbit hole with you! | ||
| + | | ||
| + | def fix_binpath(binpath, working_folder_root, bin_shortname=None): | ||
| + | if raw_input("Are you running as sudo? y/n ") != "y": | ||
| + | print("Maybe next time") | ||
| + | return | ||
| + | if not bin_shortname: | ||
| + | bin_shortname = os.path.split(binpath)[1] | ||
| + | working_folder = working_folder_root + "_" + bin_shortname | ||
| + | try: | ||
| + | shutil.rmtree(working_folder) | ||
| + | except OSError: | ||
| + | pass | ||
| + | os.mkdir(working_folder) | ||
| + | get_deps(binpath, working_folder) | ||
| + | subprocess.call(["chmod", "-R", "777", working_folder]) | ||
| + | print("Processed:\n" + ";\n".join(processed_binpaths)) | ||
| + | print("Finished") | ||
| + | | ||
| + | fix_binpath(binpath="/usr/local/Cellar/imagemagick/6.9.0-9/bin/convert", | ||
| + | working_folder_root="/Users/grantpaton-simpson/Desktop/indeps") | ||
| + | | ||
| + | fix_binpath(binpath="/usr/local/Cellar/ghostscript/9.15/bin/gs", | ||
| + | working_folder_root="/Users/grantpaton-simpson/Desktop/indeps") | ||
| + | |||
| + | ===== Practical Packaging ===== | ||
| + | |||
| + | To simplify things, maybe do the dependable.py strategy on pdftk so ALL files are in one folder. One less thing to have to handle. | ||
| + | |||
| + | That would mean we have stable Frameworks (convert, gs, delegates.xml, colors.xml, wkhtmltopdf etc etc) and Resources folders (has sofastatistics.icns and all the pyinstaller bits and pieces) and the only thing that changes is the MacOS folder. | ||
| + | |||
| + | So modify spec file to copy across those two folders into app once made, and copy contents from sofa.main into MacOS and we have a package ready to go. | ||
| + | |||
| + | ===== Testing Results ===== | ||
| + | |||
| + | ^ OS X Version ^ PDF ^ Images ^ Contact ^ Help more ^ Other ^ | ||
| + | | Yosemite 10.10 | Yes | No | R. B. Lenin - rblenin@gmail.com | Yes | US | | ||
| + | | Yosemite 10.10.2 | Yes | No | Richard O'Donovan - odonovan.richard@gmail.com | Yes | Percentage Label clipped on left in multiple bar charts. Can help TEST COMPILED files. | | ||
| + | | Lion 10.7.5 | Yes | No | Teresa Colucci - teresacolu12@att.net | Yes | US High School Maths Teacher | | ||
| + | | Snow Leopard 10.6 | Yes | Yes | Me | Yes | | | ||
| + | | El Capitan 10.11 and Mavericks 10.9.5 | ? | ? | Rod Jacka - rod@panalysis.com | Yes | Managing Director Panalysis Pty Ltd Sydney Can COMPILE for me. | | ||
| + | | Maverick 10.10.5 | ? | ? | Brian Francis - bfrancis9898@gmail.com | Yes | on both Macbook Pro and Macbook Air | | ||