web-dev-qa-db-ja.com

Xcodeに必要なdylibを埋め込むようにする

Xcodeプロジェクトでダイナミックリンクライブラリを使用し、必要なすべてのライブラリを埋め込んでデプロイするという、非常にシンプルで典型的なことをしようとしています。

ただし、Xcode 8では.dylibファイルを埋め込むことができず、フレームワークのみを埋め込むことができるため、間違った方法で何かをしている必要があります。次の図は、Embedded Binairesに何かを追加しようとすると、dylibが表示されず、Add Other ...がプロジェクトに追加しますが、EmbeddedBinariesには追加しません。

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のコピー後にスクリプトの実行ステップを追加して、引数なしで実行するだけです(環境変数には必要なものがすべて含まれています)。

15
Michel Rouzic

「EmbeddedLibraries」を使用したことはありませんが、代わりにコピーフェーズを使用して、必要なすべてのサードパーティライブラリとプロジェクト内のさまざまなターゲットによって作成されたライブラリをコピーしました。コピーしたいdylibを「Frameworks」および「Products」アウトラインノードからこのコピーフェーズにドラッグするだけです(または「+」ボタンを使用して追加します)。 XCodeは、有効になっている場合(デフォルトで有効になっている場合)、各ライブラリに自動的に署名します。

enter image description here

「インストールディレクトリ」の設定もご覧ください。この値を@ executeable_path /../ Frameworksに設定する必要があります(これが実際のフレームワークフォルダーである場合、少なくともそれが推奨されるフォルダーです)。この値は、dylibのIDを設定するためにXCodeによって使用され、正しくロードするために不可欠です。

enter image description here

MacDependency のようなツールを使用して、.app.dylib、および.frameworkパッケージの詳細を確認することもできます。また、ライブラリが依存している他のdylibと、それらを予期するパスも表示されます。そのパスは、リンクされたライブラリのIDと同じである必要があります。そうでない場合、ロードは失敗します。

もう1つの非常に便利なツールは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)

ローダーパスに関する別の議論はここにあります: Xcodeでdyld_library_pathを設定する方法

作成したアプリまたはライブラリが相対的な場所ではなくシステムの場所からのdylibを予期している場合は、間違ったライブラリをそれにリンクしている可能性があります。 「バイナリのリンク」ビルドフェーズでは、リンクするライブラリを選択できます。選択ダイアログには、そこにあるすべてのプロジェクトターゲットが一覧表示されます。また、リンカーリストの場合は、プロジェクトアウトラインの[製品]ノードからdylibをドラッグして、設定を行うことができます。また、そのようなライブラリの場合、適切なパスを設定するという要件が当てはまります。これは、コピーフェーズの後にIDを変更するスクリプトを使用するか、これらのライブラリのコピーを別の場所に保持し、一度(ダウンロードした後など)IDを変更して、そこから最終的なアプリにコピーすることで実行できます。

14
Mike Lischke

Dylibの埋め込みが機能するようになりました(Xcodeバージョン10.2で確認済み)。ターゲット->フレームワーク、ライブラリ、埋め込みコンテンツ。

https://help.Apple.com/xcode/mac/11.0/index.html?localePath=en.lproj#/dev51a648b07 を参照してください。

0
Waterman