I am very pleased to be able to say I have managed to get imagemagick
convert and ghostscript to play nicely together and to work when installed
on a clean Snow Leopard machine. I will elaborate on the details (which are
already written up in a private wiki page) in the near future in the SOFA
Statistics blog. The main tricks (apart from those involved in the
compiling of the binaries) are to set the environment variables correctly
and have a delegates.xml (and colors.xml) file in the correct location.
Assuming all the special binaries such as convert and gs, and the
configuration files such as delegates.xml, are in the same folder, that
folder must lead the PATH (e.g. export PATH=<foldername>:${PATH}) and
MAGICK_CONFIGURE_PATH must be set to the same folder. The delegates.xml
file must have lots of references to gs throughout and these do not need to
be replaced with fully-qualified file names given the PATH setting
described earlier.
I have also attached a hacky python script I wrote which relies on xcode
being on the machine in question (IIRC) because it uses otool and
install_name_tool.
On Thursday, 29 January 2015 19:55:43 UTC+13, Grant Paton-Simpson wrote:
>
> Hi,
>
> I am about to try making a new Mac installer for SOFA Statistics
> (http://www.sofastatistics.com/home.php). SOFA is open source (190K
> downloads) and written in Python 2.7. My old tool-chain can't cope with
> some of the new libraries SOFA depends on - especially around image
> processing - so I am working out a new process.
>
> The installer is being built on Snow Leopard (inside VirtualBox) and I
> have decided to drop py2app and use pyinstaller instead because of its
> more active community.
>
> Based on past experience I am expecting the main pain points to be the
> homebrew-installed libraries ( and imagemagick's convert program. IIRC
> one of the key challenges is getting imagemagick to detect the location
> of ghostscript correctly. I may even need to compile my own version of
> imagemagick to make packaging successful.
>
> Any words of advice before I start the process? One of the main things
> I'm lacking is a decent mental model of what the packaging actually
> does. My background is Sociology not computer science ;-).
>
> If anyone wants to go further in supporting the SOFA project by
> providing more focused support that would be great though I appreciate
> everyone is busy on their own projects. Just thought I'd mention it in
> case anyone was looking for a project to get involved in.
>
> All the best,
> Grant
> Creator SOFA Statistics
>
--
You received this message because you are subscribed to the Google Groups
"PyInstaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/pyinstaller.
For more options, visit https://groups.google.com/d/optout.
#! /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")