I am developing a command line utility for macOS (Mojave) that manipulates images using ImageMagick. I want to share it as a standalone app in such a way that others can use it out-of-the-box without having to install any additional dylibs or frameworks. The Homebrew and MacPorts versions of ImageMagick seem to be "hardwired" to the Mac's system directory structure (/usr/local
and /opt/local
, respectively) in such a way that it's difficult (impossible?) to put ImageMagick and its delegate libraries into a portable application bundle. So I am instead using the distribution directly from the ImageMagick website.
I followed the installation instructions on that page and put the ImageMagick folder in my home directory (at ~myname
). As instructed, I did export DYLD_LIBRARY_PATH="/Users/myname/ImageMagick-7.0.8/lib/"
. But when I run magick
, I get an error message:
$ ~myname/ImageMagick-7.0.8/bin/magick logo: test.jpg
dyld: Library not loaded: /ImageMagick-7.0.8/lib/libMagickCore-7.Q16HDRI.6.dylib
Referenced from: /Users/myname/ImageMagick-7.0.8/bin/magick
Reason: image not found
Abort trap: 6
$
Clearly magick
isn't finding its dylibs, even when I set DYLD_LIBRARY_PATH
as instructed. It appears, in fact, that I can't even export DYLD_LIBRARY_PATH
into the environment:
$ export MAGICK_HOME="/Users/myname/ImageMagick-7.0.8"
$ export DYLD_LIBRARY_PATH="$MAGICK_HOME/lib/"
$ echo $DYLD_LIBRARY_PATH
/Users/myname/ImageMagick-7.0.8/lib
$ printenv | grep DYLD_LIBRARY_PATH
# (nothing)
$ printenv | grep ImageMagick
MAGICK_HOME=/Users/myname/ImageMagick-7.0.8
$
What's going on? How can I make ImageMagick portable?
First of all, the version of IM currently on the ImageMagick website (version 7.0.8) is for macOS High Sierra. It's therefore not too surprising that you're having trouble installing it on Mojave. (FWIW, the current Homebrew version (IM 7) and MacPorts (IM 6) do, however, work on Mojave. But, like you, I don't know how to make those versions' handling of the delegates truly portable.)
The reason you can't export DYLD_LIBRARY_PATH
is because of Apple's "System Integrity Protection" (SIP), which it added to newer versions of macOS (El Capitan and later). By default, SIP prohibits doing things like changing the env variable DYLD_LIBRARY_PATH
. Although it is possible to disable SIP, Apple does not recommend doing so.
You can, however, modify magick
and its dylibs manually using install_name_tool
so that IM 7.0.8 works fine on Mojave. Here's how (in bash
):
# magick: set the correct path to libMagickCore.dylib
install_name_tool -change \
/ImageMagick-7.0.8/lib/libMagickCore-7.Q16HDRI.6.dylib \
@executable_path/../lib/libMagickCore-7.Q16HDRI.6.dylib \
/Users/myname/ImageMagick-7.0.8/bin/magick
# magick: set the correct path to libMagickWand.dylib
install_name_tool -change \
/ImageMagick-7.0.8/lib/libMagickWand-7.Q16HDRI.6.dylib \
@executable_path/../lib/libMagickWand-7.Q16HDRI.6.dylib \
/Users/myname/ImageMagick-7.0.8/bin/magick
# libMagickWand.dylib: set the correct ID
install_name_tool -id \
@executable_path/../lib/libMagickWand-7.Q16HDRI.6.dylib \
/Users/myname/ImageMagick-7.0.8/lib/libMagickWand-7.Q16HDRI.6.dylib
# libMagickWand.dylib: set the correct path
install_name_tool -change \
/ImageMagick-7.0.8/lib/libMagickCore-7.Q16HDRI.6.dylib \
@executable_path/../lib/libMagickCore-7.Q16HDRI.6.dylib \
/Users/myname/ImageMagick-7.0.8/lib/libMagickWand-7.Q16HDRI.6.dylib
# libMagickCore.dylib: set the correct ID
install_name_tool -id \
@executable_path/../lib/libMagickCore-7.Q16HDRI.6.dylib \
/Users/myname/ImageMagick-7.0.8/lib/libMagickCore-7.Q16HDRI.6.dylib
Now it works:
$ /Users/myname/ImageMagick-7.0.8/bin/magick logo: test.jpg
$ open test.jpg
$ # (Preview opens a nice picture of the ImageMagick logo.)
This modifies the paths to the dylibs relative to the location of the magick
command. As long as you keep the directory structure of the ImageMagick folder intact, it should now be completely portable.
You can easily put those five install_name_tools
commands into a little bash
script. I'll leave that as an exercise for the reader. :)