5

ダイナミックライブラリに実装されているMacアプリケーションをXCodeで作成しようとしています。

XCode cocoaプロジェクトに新しいターゲット(ダイナミックライブラリ)を追加し、フレームワークとプリコンパイル済みヘッダーと少し戦った後、dynlibをコンパイルしてデバッガーから正常に実行しました。

ただし、スタンドアロンで実行すると、dynlibが間違った場所にあることがわかります。「ライブラリがロードされていません:/usr/local/lib/testlib.dynlib」。Windows(私のより一般的なプラットフォーム)では、DLLはexeと同じフォルダーに配置でき、システムパス上の任意の場所に配置できます。

私はむしろ私のアプリケーションがそのアプリケーションバンドルのどこかでそのdynlibを探すことを望みます(そして特定の文書はこれが正しいアプローチであることを確認しているようです)、しかし私は方法がわかりません。

dylibが実際にアプリバンドルにコピーされ、アプリがそれを探す場所にあるように、XCodeでプロジェクトを構成することは可能ですか?


検索パスをリセットするためにotoolを使用する必要はないようです。ターゲット情報->ビルド->デプロイメント->インストールディレクトリを編集すると、XCode内から、dyldがdylibを探すパスを変更できます。新しいダイナミックライブラリプロジェクトのデフォルトでは、パスはに設定されていました/usr/local/lib。私が変更したもの./--otoolは、./がdyldがこの特定の動的モジュールを探している場所であることを確認します。残念ながら、./は実際には私のアプリケーションバンドル内のどのディレクトリも参照していないようです:(

したがって、私の質問(他のスレッドでは回答されていません)は次のとおりです。1。[ターゲット情報]->...->[インストールディレクトリ]設定に意味のある相対パスを入力するにはどうすればよいですか。2。XCodeを自動的に取得するにはどうすればよいですか。 dylib'target'をアプリケーションバンドルターゲットの相対的な場所にあるバンドルフォルダにコピーしますか?

4

3 に答える 3

6

やっと。いくつかの公式ドキュメントが見つかりました。これは完全にXCode内で行うことができます。

ライブラリのインストール済みディレクトリ設定を変更している途中でした。次のようにする必要がありました。 @executable_path/../Frameworks

次に、「ファイルのコピー」ビルドステップをライブラリに追加して、実際にフレームワークフォルダーにコピーする必要がありました。

単純。自動。

于 2009-12-02T14:36:41.400 に答える
1

コンパイル時にダイナミックライブラリをアプリケーションバンドルにコピーしていないと思います。

アプリケーションはファイルシステム内のポイントを探していますが、アプリケーションバンドル内でポイントを見つけられなかった場合にのみこれを行います。otoolコンパイル後にバイナリを変更するには、コマンドを使用する必要があります(ビルドスクリプトを使用)。

以前に尋ねられたこの質問に答えが見つかります: Xcodeでダイナミックライブラリを作成するにはどうすればよいですか。

幸運を。

于 2009-12-02T11:28:17.543 に答える
0

多くの調査の結果、「ライブラリがロードされていません:....」というエラーが表示されたため、openCVdylibをアプリケーションにパッケージ化しようとしました。

Dylibsには、最初にインストールしたときにインストールした場所を示すインストール名があります(macportsは/ opt / local / lib /にインストールします)。彼らはまた、彼らが働く必要がある他のdylibへの道を持っています。たとえば、「libopencv_core.2.4.8.dylib」というdylibがある場合は、次のコマンドで使用するインストール名と他のdylibへのパスを確認できます。

otool -L libopencv_core.2.4.8.dylib

コマンドの出力は次のとおりです。

libopencv_core.2.4.8.dylib:
/opt/local/lib/libopencv_core.2.4.dylib (compatibility version 2.4.0, current version 2.4.8)
/opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

1-最初の行:チェックしているファイルの名前。

2- 2行目:チェックしているdylibの名前をインストールします。(macportsはそれらを/ opt / local / lib /にインストールします)

3- 3行目:すべてのOSXシステムにない、動作する必要のある他のdylibへのパス。(macportsはそれらを/ opt / local / lib /にインストールし、以前にインストールしたためにそれらを持っています。そのため、アプリを他のMacに配布すると、「ライブラリが見つかりません」というエラーが発生します)

4&5- 4行目と5行目:すべてのmacOSXシステム内のdylibs。プロジェクトでそれらをコピーする必要はありません。

今、私たちはこれを知っています、私たちの目標は次のとおりです:

1- dylib内のすべてのパスを変更します(インストール名と必要な他のdylibへのパス)。これは、dylibをアプリ内の「Frameworks」ディレクトリに配置し、アプリを移動するか、他のMacにコピーするためです。アプリのディレクトリ内の「frameworks」フォルダ内でdylibが相互に検索するようにします。使用するパスは次のとおりです。

@executable_path/../Frameworks/nameOFTheDylib.dylib

(2つのポイントが本当に重要であることに注意してください!)

2-必要なすべてのdylibをxCodeにコピーしますが、/ opt / local / libフォルダー内のすべてのdylibではありません。必要なものだけです:(すべてが多すぎる、おそらく500Mb)必要であることがわかっているdylib(通常は4または5)からのリンクと、4または5が機能するために必要であるために含まれているdylibからのリンク。

Yはついにこのようにした:

a)パスを変更するには:

1-すべての/opt/ local/libファイルをデスクトップにコピーします。

2-.dylibアーカイブではないlibフォルダー内のすべてのファイルを削除します。

3-このスクリプトを(dylibsと一緒に)libフォルダー内に配置します。デスクトップにコピーしました。

(このテキストをtextEditにコピーして、theNameYouPrefer.shとして保存します)

#!/bin/bash
echo empieza el script

EXECFILE=${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}
OLDLIBPATH="/opt/local/lib/"
NEWLIBPATH="@executable_path/../Frameworks/"
ACTUALPATH=`pwd`
# space separated list of libraries
for TARGET in ${ACTUALPATH}/* ; do
TARGET=$(basename $TARGET)
    if [ ${TARGET: -6} == ".dylib" ]
    then
        echo otool -DX ${TARGET}
        TARGETID=`otool -DX ${TARGET}`
        echo ${TARGETID}

        echo install_name_tool -id ${NEWLIBPATH}${TARGET} ${TARGET}
        echo `install_name_tool -id ${NEWLIBPATH}${TARGET} ${TARGET}`

        for DYLIB in ${ACTUALPATH}/* ; do
        DYLIB=$(basename $DYLIB)
            if [ ${DYLIB: -6} == ".dylib" ]
            then
                echo install_name_tool -change ${TARGETID} ${NEWLIBPATH}${TARGET} ${DYLIB}
                echo `install_name_tool -change ${TARGETID} ${NEWLIBPATH}${TARGET} ${DYLIB}`
            else
                if [ ${DYLIB: -3} == ".sh" ]
                then
                    echo soyYo
                else
                    echo mkdir ${ACTUALPATH}/eliminadas/
                    echo `mkdir ${ACTUALPATH}/eliminadas/`
                    echo mv ${DYLIB} ${ACTUALPATH}/eliminadas
                    echo `mv ${TARGET} ${ACTUALPATH}/eliminadas`
                fi
            fi
        done
    else
if [ ${TARGET: -3} == ".sh" ] || ![ -h ${TARGET} ]
        then
            echo noMeElimino
        else
            echo mkdir ${ACTUALPATH}/eliminadas/
            echo `mkdir ${ACTUALPATH}/../eliminadas/`
            echo mv ${TARGET} ${ACTUALPATH}/eliminadas/${TARGET}
            echo `mv ${TARGET} ${ACTUALPATH}/../eliminadas`
        fi
    fi
done

echo finaliza el script

4-それを実行します:

cd Desktop/lib
sudo ./theNameYouPrefer.sh

dylibは書き込み保護されている可能性があるため、sudoとして実行することは非常に重要です。

この時点で、すべてのdylibsパスを変更する必要があります。次のコマンドを使用して、いくつかのdylibで確認できます。

otool -L theDylibYouPrefer.dylib

b)すべてのlibフォルダーではなく、必要なdylibのみを選択します。

1-libフォルダーの名前をlib2に変更します:lib =====> lib2

2-デスクトップに、lib2フォルダーの隣に別のフォルダー(たとえば、Folderなどの名前を付けて)を作成します。

3-exampleFolder内にコピーします。確実に必要になることがわかっている重要なdylibをコピーします。私の場合は、libopencv_core.2.4.8.dylib、libopencv_highgui.2.4.8.dylib、libopencv_imgproc.2.4.8.dylib、libopencv_objdetectです。 2.4.8.dylib

4-スクリプト:exampleFolder内の重要なdylibの横にコピーします。私はスクリプトについてあまり知らないので、これはもう少し汚いです:

#!/bin/bash
echo empieza el script

EXECFILE=${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}
OLDLIBPATH="/opt/local/lib/"
NEWLIBPATH="@executable_path/../Frameworks/"
ACTUALPATH=`pwd`
# space separated list of libraries
for TARGET in ${ACTUALPATH}/* ; do
TARGET=$(basename $TARGET)
    if [ ${TARGET: -6} == ".dylib" ]
    then
        echo otool -DX ${TARGET}
        TARGETID=`otool -L ${TARGET}`
echo ${TARGETID}

echo :::::::::::::::::::::::::::

ELIM=`echo ${TARGETID} | sed 's/([^)]*)/UUU/g'`
echo $ELIM
#echo ${TARGETID} | sed 's/([^)]*)/UUU/g'
ELIM=`echo $(awk '{gsub("@executable_path/../Frameworks/", "");print}' <<< ${ELIM})`
echo $ELIM

ELIM=`echo $(awk '{gsub(" UUU", "");print}' <<< ${ELIM})`
echo $ELIM

ELIM=`echo $(awk '{gsub(":", "");print}' <<< ${ELIM})`
echo $ELIM

IFS=' ' read -a ARRAY <<< $ELIM

for element in ${ARRAY[@]}
do
    echo $element
    if [[ ${element} == */* ]]
    then
        echo "NO FRAMEWORK";
    else
        echo `mkdir ${ACTUALPATH}/../copy`
        echo `cp ${ACTUALPATH}/../lib2/${element} ${ACTUALPATH}/${element}`
    fi
done


    else
if [ ${TARGET: -3} == ".sh" ] || ![ -h ${TARGET} ]
        then
            echo noMeElimino
        else
            echo mkdir ${ACTUALPATH}/eliminadas/
            echo `mkdir ${ACTUALPATH}/../eliminadas/`
            echo mv ${TARGET} ${ACTUALPATH}/eliminadas/${TARGET}
            echo `mv ${TARGET} ${ACTUALPATH}/../eliminadas`
        fi
    fi
done

echo finaliza el script

5- exampleFolder内のファイル数が変わらないことがわかるまで、このスクリプトを何度も実行します。

6-必要なdylibはすべてexampleFolder内にあります!私の場合、61のdylibを取得しました。(私たちが始めたとき、私はそこに4つのdylibを置いたことを思い出してください)

7-最後に行う必要があるのは、xCodeの「Frameworks」フォルダー内にドロップすることです。その後、「ビルドフェーズ」に移動して「ファイルのコピー」フェーズを追加することを忘れないでください:「エディタ」=>「ビルドフェーズの追加」=>「コピーファイルのビルドフェーズの追加」そして「ファイルのコピー」フェーズの内側をクリックします。アイコンを作成し、「Framewroks」フォルダで見つけたすべてのDYLIBを追加します。必要な宛先はフレームワークです。

そしてそれはそれです、私は多かれ少なかれこの方法でそれを手に入れました。

于 2014-02-26T01:57:02.173 に答える