Mac OS上的ImageMagick部署

时间:2013-04-15 04:29:13

标签: macos imagemagick cmake

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

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

P.S。我有所有ImageMagick库,包括MacOS bundle子文件夹中可执行文件附近的编码器SO。

3 个答案:

答案 0 :(得分:4)

如何在捆绑中设置MAGICK_CODER_MODULE_PATH?

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

修改

改善信息:

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

  1. 我们的应用程序和IM dylibs未找到引用的IM dylibs,
  2. IM未找到其配置文件,
  3. IM未找到编码器(No Decode Delegate错误)
  4. 我们尝试使用install_name_tool更改dylib中的硬编码路径,但最后在进行一些测试时将IM移动到不同的目录并进行测试

    convert -debug configuration 
    

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

    DYLD_LIBRARY_PATH
    MAGICK_CONFIGURE_PATH
    MAGICK_CODER_MODULE_PATH
    

    凭借这段经验,我们回到了我们的捆绑包,并在开始时尝试使用Info.plist fiel来设置这些变量,但它似乎没有用 - 可能是因为在内部建立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)。

    从我们的测试中可以看出,以这种方式设置环境变量使它们只对这个应用程序执行上下文可见 - 即当我们使用bundle启动我们的app时,打开终端并键入

    env
    

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

    希望这可以帮助其他人节省几天的研究时间并将头发拉出来;)

答案 1 :(得分:2)

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

首先,您需要知道ImageMagick在您自己的代码中使用它时尝试查找的内容和位置。要找到它,您可以使用 MAGICK_DEBUG 环境变量,该变量可以设置为those个参数。调试ImageMagick时它确实很有用。

先决条件: 我假设你使用FIND_PACKAGE和FIXUP_BUNDLE来查找ImageMagick并在bundle中设置它的二进制路径。唯一剩下的就是部署编码器。另外我假设你已经从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)
    
  5. 脚本内容:

    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设置为脚本名称。

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

答案 2 :(得分:1)

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

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