使Xcode嵌入必要的dylib

问题描述 投票:13回答:2

我正在尝试做一些非常简单和典型的事情,它在我的Xcode项目中使用动态链接库,然后部署嵌入了所有必需的库。

但是我必须以错误的方式做某事,因为Xcode 8不允许我嵌入.dylib文件,只有框架!下面的图片是当我尝试向嵌入式Binaires添加任何东西时发生的事情,dylib只是没有显示,而Add Other ...将它们添加到项目中但不添加到嵌入式二进制文件中。

Xcode not allowing me to add any of the dylibs as embedded binaries

必须有一个非常简单的方法,但我找不到它...

结语

所以很明显,因为我需要运行一个调用install_lib_tool的脚本,我制作了一个非常通用的脚本,它将改变任何在其路径中嵌入/local/的嵌入式副本的路径:

#!/bin/sh

app=$BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH
fw_path=$BUILT_PRODUCTS_DIR/$FRAMEWORKS_FOLDER_PATH
app_dyl_list=(`ls $fw_path | grep dylib`)

function change_paths {
    local bin=$1
    echo change_path $bin
    dyl_list=(`otool -L $bin | grep local | awk '{print $1}'`)

    for dyl in ${dyl_list[*]}; do
        libname=$(basename $dyl)
        libname=${libname%%.*}
        actual_libname=(`ls $fw_path | grep $libname | xargs basename`)
        install_name_tool -change $dyl "@executable_path/../Frameworks/$actual_libname" $bin
        printf "\t%s edited\n" $actual_libname
    done
}

change_paths $app
for dyl_bin in ${app_dyl_list[*]}; do
    change_paths $fw_path/$dyl_bin
done

然后,只需在复制dylib之后添加一个Run Script步骤,就可以在没有参数的情况下运行它(环境变量包含所需的一切)。

xcode macos macos-sierra dylib
2个回答
14
投票

我从未使用过“嵌入式库”,而是使用复制阶段复制所有需要的第三方库以及项目中各种目标创建的库。您只需将想要从“框架”和“产品”轮廓节点复制的dylib拖到此复制阶段(或通过“+”按钮添加它们)。如果启用了XCode(默认情况下是这样),XCode也会自动对每个lib进行签名:

enter image description here

另请参阅“安装目录”设置。您应该将此值设置为@executable_path /../ Frameworks(假设这是您的实际框架文件夹,至少是推荐的那个)。 XCode使用该值来设置dylib的ID,这对于使它们正确加载至关重要

enter image description here

您还可以使用像MacDependency这样的工具来检查.app.dylib.framework包的详细信息。它还将向您显示库所依赖的其他dylib以及它所期望的路径。该路径必须与链接库的ID相同,否则加载将失败。

另一个非常有用的工具是otool,它带有XCode。它提供类似MacDependency等信息。以下是dylib的依赖项列表,其中包含它所需的路径和版本:

Mikes-iMac:Debug mike$ otool -L libcdbc.dylib
libcdbc.dylib:
    @executable_path/../Frameworks/libcdbc.dylib (compatibility version 1.0.0, current version 1.0.0)
    @executable_path/../Frameworks/libwbbase.dylib (compatibility version 1.0.0, current version 1.0.0)
    @executable_path/../Frameworks/libgrt.dylib (compatibility version 1.0.0, current version 1.0.0)
    @executable_path/../Frameworks/libgmodule-2.0.0.dylib (compatibility version 3401.0.0, current version 3401.2.0)
    @executable_path/../Frameworks/libgthread-2.0.0.dylib (compatibility version 3401.0.0, current version 3401.2.0)
    @executable_path/../Frameworks/libglib-2.0.0.dylib (compatibility version 3401.0.0, current version 3401.2.0)
    @executable_path/../Frameworks/libmysqlcppconn.7.1.1.8.dylib (compatibility version 7.0.0, current version 7.1.1)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.4.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)

关于装载机路径的另一个讨论是:How to set dyld_library_path in Xcode

如果您创建的应用程序或库需要来自系统位置的dylib而不是相对的,那么它可能意味着您将错误的lib链接到它。在“链接二进制”构建阶段,您可以选择要链接的库,选择对话框将列出所有项目目标。此外,对于链接器列表,您只需将dylib从项目大纲中的“Products”节点拖到其中即可进行设置。此外,对于此类库,设置正确路径的要求也适用。您可以使用在复制阶段之后更改ID的脚本,或者将这些库的副本保存在其他位置,更改它们的ID(例如,在下载之后)并将其从那里复制到最终应用程序。


0
投票

通过“嵌入式二进制”选项接缝嵌入dylib现在可以正常工作(使用Xcode Version 10.2 beta 4进行检查)。

© www.soinside.com 2019 - 2024. All rights reserved.