【问题标题】:ImageMagick deployment on Mac OSMac OS 上的 ImageMagick 部署
【发布时间】:2013-04-15 04:29:13
【问题描述】:

我正在尝试使用我自己的软件部署 ImageMagick。在 Windows 上,我刚刚在 exe 路径中包含了所有带有编码器 dll 的核心 dll,它运行良好。 但是在 mac os 上,我遇到了编码器的麻烦。我通过 macports 安装了 ImageMagick,并在 CMake 的帮助下找到了它。 CMake 完成了复制和修复我链接的所有核心库的所有工作。然后我复制了所有的编码器库并修复了它们,但是当我启动我的应用程序时,它就是找不到任何编码器。所以我想知道我在那里错过了什么。

注意:如果我没有修复任何路径,它运行良好。只有我的部署有问题。也许我应该包含某种配置文件?

附:我在 MacOS 捆绑子文件夹中的可执行文件附近拥有所有 ImageMagick 库,包括编码器 SO。

【问题讨论】:

  • 你签出dyld了吗?
  • @Alvin,在这种情况下帮助不大。

标签: macos imagemagick cmake


【解决方案1】:

在你的包中设置 MAGICK_CODER_MODULE_PATH 怎么样?

请看这里:http://www.imagemagick.org/script/resources.php

编辑:

改善信息:

最初在我们自己的 app bundle 中嵌入 IM 时,我们遇到了三个问题:

  1. 我们的应用和 IM dylib 没有找到引用的 IM dylib,
  2. IM 找不到它的配置文件,
  3. IM 找不到编码器(No Decode Delegate 错误)

我们尝试使用 install_name_tool 更改 dylib 中的硬编码路径,但最终在进行一些测试时将 IM 移动到不同的目录并进行测试

convert -debug configuration 

我们发现以上三个问题都可以通过在运行转换之前在终端控制台中设置和导出至少这三个环境变量来解决:

DYLD_LIBRARY_PATH
MAGICK_CONFIGURE_PATH
MAGICK_CODER_MODULE_PATH

有了这个经验,我们回到了我们的包,一开始尝试使用 Info.plist 字段来设置这些变量,但它似乎不起作用 - 可能是因为在内部制作 IM 的路径时存在问题捆绑相关。

最后,我们创建了一个简单的 sh 脚本并将其放入我们的包中,并将此包配置为运行此脚本而不是主应用程序:

#!/bin/sh
CURR_DIR="$( cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
IMAGE_MAGICK_PATH=$CURR_DIR/../Resources/ImageMagick

export DYLD_LIBRARY_PATH=$IMAGE_MAGICK_PATH/lib
export MAGICK_CONFIGURE_PATH=$IMAGE_MAGICK_PATH/lib/ImageMagick-6.8.0/config
export MAGICK_CODER_MODULE_PATH=$IMAGE_MAGICK_PATH/lib/ImageMagick-6.8.0/modules-Q16/coders

# run application
exec $CURR_DIR/OurAppName

使其正常工作的关键是正确获取应用程序包的 CURR_DIR(感谢 this post)。

正如我们的测试所得出的那样,以这种方式设置环境变量使它们仅在此应用程序执行上下文中可见 - 即当我们使用捆绑包启动应用程序时,打开终端并输入

env

输出中缺少上述三个变量。

希望这将帮助其他人节省几天的研究时间并从头上拔毛;)

【讨论】:

  • 为什么只是部分?说实话,我的团队现在正致力于创建嵌入了 IM 的应用程序包,我们也遇到了问题。设置 MAGICK_CODER_MODULE_PATH 解决了当我们在 IM 库中移动进行测试时出现的 NoDecodeDelagate 错误......所以你现在在哪里,如果我们处于相似阶段,也许我们可以一起解决问题;)
  • 对我来说,它需要清除 .la 中包含路径的两个字段。设置 MAGICK_CODER_MODULE_PATH 并清除这些字段后,它开始工作。这就是为什么我说它有部分帮助。
  • Another 使用 MAGICK_CODER_MODULE_PATH 时出现问题
  • 哪个问题 - 需要调用 lsregister?我认为只有在您更改它时才需要这样做,当应用程序第一次运行时,应该没有问题......或者您有其他问题?
  • LSEnvironment 是否适合您?因为对我来说没有,但我不知道缓存。
【解决方案2】:

我找到了一个完整的解决方案,可以在 CMake 的帮助下将 ImageMagick 部署到一个包中。如果您不使用 CMake,那么 @Tomasz 的回答也会有所帮助。 那么让我们开始吧:

首先,您需要知道从您自己的代码中使用 ImageMagick 时它试图定位的内容和位置。要找出它,您可以使用 MAGICK_DEBUG 环境变量,该变量可以设置为 those 参数。调试 ImageMagick 时真的很有帮助。

先决条件: 我假设您使用 FIND_PACKAGE 和 FIXUP_BUNDLE 来查找 ImageMagick 并在包中设置其二进制路径。剩下的唯一事情就是部署编码器。我还假设您已经从 Mac Ports 安装了 ImageMagick。

  1. 我们需要获取 ImageMagick 版本字符串才能正确定位编码器:

    STRING(REGEX REPLACE "-.+" "" ImageMagick_SHORT_VERSION ${ImageMagick_VERSION_STRING})
    

    现在 ImageMagick_SHORT_VERSION 包含完整版本,没有任何子版本。

  2. 然后我们需要将所有编码器复制到某个预定义的文件夹(我使用了捆绑包的 MacOS 部分下的 ImageMagick/coders 子文件夹)

    FILE(COPY /opt/local/lib/ImageMagick-${ImageMagick_SHORT_VERSION}/modules-Q16/coders/ DESTINATION ${PATH_TO_YOUR_BUNDLE}/Contents/MacOS/ImageMagick/coders/)
    
  3. 现在我们需要修复我们拥有的所有 *.so 库,因此我们将其列出并传递给 fixup_bundle

    FILE(GLOB IMAGEMAGICK_CODERS ${PATH_TO_YOUR_BUNDLE}/Contents/MacOS/ImageMagick/coders/*.so)
    
  4. 现在我们应该更新伴随编码器 *.so 的 *.la 文件。为了实现它,我使用了脚本:

    INSTALL(SCRIPT LaScript.cmake COMPONENT Runtime)
    

脚本内容:

SET(TARGET_BINARY_DIR "${PATH_TO_YOUR_BUNDLE}")
FILE(GLOB IMAGEMAGICK_CODERS_LA ${TARGET_BINARY_DIR}/Contents/MacOS/ImageMagick/coders/*.la)
FOREACH(file ${IMAGEMAGICK_CODERS_LA})
    FILE(READ ${file} FILE_CONTENT)
    STRING(REGEX REPLACE "dependency_libs='.*'" " " MODIFIED_FILE_CONTENT ${FILE_CONTENT})
    STRING(REGEX REPLACE "libdir='.*'" " " MODIFIED_FILE_CONTENT ${MODIFIED_FILE_CONTENT})
    FILE(WRITE ${file} ${MODIFIED_FILE_CONTENT})
ENDFOREACH()

我们几乎准备好了,唯一剩下要做的就是改变我们启动应用程序的方式。但让我们跑题一点,看看 ImageMagick 在哪里搜索编码器:

  • 它试图获取MAGICK_CODER_MODULE_PATH环境变量的内容
  • 然后它会检查是否定义了 MAGICKCORE_CODER_PATH 宏(事实上确实如此!)并使用它的值。

然后它会尝试使用 MAGICK_HOME 环境变量和 MAGICKCORE_CODER_RELATIVE_PATH 来获取模块的路径,但我们不在乎,因为无论如何我们都会在 #2 上停止!(注意:Mac Ports 安装也是如此)

所以我们可以干扰搜索的唯一方法是设置 MAGICK_CODER_MODULE_PATH 环境变量(我们也可以编辑 libMagickCodre 并将 MAGICKCORE_CODER_PATH 替换为我们需要的一些静态路径,但它做事的方式太脆弱了,如果有人设置了 MAGICK_CODER_MODULE_PATH 也救不了我们) 我们不应该在系统范围内设置它,因为我们可能会破坏一些用户安装,所以我们有 2 个选项:

  • 使用 LSEnvironment 将 MAGICK_CODER_MODULE_PATH 设置为某个预定义位置
  • 使用脚本启动我们的应用并在其中设置此变量。

我选择了后者,因为它更灵活, 我有以下脚本:

#!/bin/bash
working_dir="${0%/*}"
export MAGICK_CODER_MODULE_PATH=$working_dir/ImageMagick/coders
executable="${working_dir}/ApplicationName"
"$executable"

并将CFBundleExecutable 设置为脚本的名称。

仅此而已,我希望它可以帮助某人节省他/她的时间。

【讨论】:

    【解决方案3】:

    您应该遵循Mac OS X-specific Build instructions,但在configure 选项中指定--enable-shared(有关详细信息,请参阅this document)。

    我猜您的应用程序找不到编解码器,因为它们已静态链接到 ImageMagick 工具。通常这样做是为了解决可移植性问题。要使编解码器在您的应用程序中可用,您应该将它们构建为共享对象。

    【讨论】:

    • 虽然您的回答很有价值,但它回答了完全不同的问题。我没有问“如何在 MAC OS 下构建 ImageMagick”
    • @ixSci 我猜您的应用程序找不到编解码器,因为它们已静态链接到 ImageMagick 工具。通常这样做是为了解决可移植性问题。要使编解码器在您的应用程序中可用,您应该将它们构建为共享对象。因此你需要 --enable-chared。
    • 不,问题不同。我有一个正确的方向,但我仍在努力解决它。我会在解决时发布我的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2013-12-13
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    相关资源
    最近更新 更多