3

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

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

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

4

3 回答 3

4

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

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

编辑:

改善信息:

最初在我们自己的应用程序包中嵌入 IM 时,我们遇到了三个问题:

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

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

convert -debug configuration 

我们发现,只要在运行 convert 之前在终端控制台中设置和导出至少这三个环境变量,就可以解决上述所有三个问题:

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(感谢这篇文章)。

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

env

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

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

于 2013-04-24T08:54:31.390 回答
2

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

首先,您需要知道在您自己的代码中使用 ImageMagick 时试图定位的内容和位置。要找出它,您可以使用可以设置为这些参数的MAGICK_DEBUG环境变量。当您调试 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)我们不应该在系统范围内设置它,因为我们可以破坏一些用户安装,所以我们有两个选项:

  • 使用 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为脚本的名称。

这就是全部,我希望它可以帮助某人节省他/她的时间。

于 2013-05-01T06:02:34.540 回答
1

您应该遵循Mac OS X 特定的构建说明,但--enable-sharedconfigure选项中指定(有关详细信息,请参阅本文档)。

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

于 2013-04-24T06:33:06.500 回答