2009-12-02 16 views
5

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

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

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

私は、自分のアプリケーションがアプリケーションバンドルのどこかでdynlibを探すのが好きですが(特定のドキュメントはこれを正しいアプローチとして確認しているようですが)、私は方法がわかりません。

実際にdylibがアプリケーションバンドルにコピーされるように、アプリケーションがXcodeでプロジェクトを設定することはできますか?


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

だから、私の質問(他のスレッドで答えていない)今、次のとおりです。 1.私は相対的な意味のあるを入力するにはどうすればよいですTarget Info - > ... - > Installation Directoryの設定で、 のパスを指定します。2. dylib 'target'を相対位置のアプリケーションバンドルターゲットのバンドルフォルダに自動的にコピーするにはどうすればよいですか?

答えて

6

最後に。いくつかを見つけたofficial documentation。これはXCode内で完全に可能です。

私は、ライブラリのインストールディレクトリの設定を変更する途中だった:それはする必要: @executable_path/../Frameworks

それから私は「ファイルのコピー」は、実際にフレームワークにそれをコピーするには、ライブラリへのステップを構築追加する必要がフォルダ。

シンプルです。自動。

1

Iコンパイル時に動的ライブラリをアプリケーションバンドルにコピーしていないと考えてください。

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

これまでに質問されたこの回答は、 How Do I Create a Dynamic Library in Xcodeです。

幸運。

0

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

Dylibには、最初にインストールしたときにインストールした場所を示すインストール名があります(macportsは/ opt/local/lib /にインストールします)。 彼らは仕事に必要な他のdylibへの道も持っています。

otool -L libopencv_core.2.4.8.dylib 

は、コマンドの出力は次のとおりです。あなたが「libopencv_core.2.4.8.dylib」と呼ばれるdylibを持っている場合たとえば、あなたはそれがこのコマンドで使用する名前と他のdylibsへのパスをインストールチェックすることができます:

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に配布して "ライブラリが見つかりません"というエラーが出るのはなぜでしょうか)

5 - 4と5:すべてのmacOSXシステムの中のdylibs。プロジェクトでコピーする必要はありません。

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

の1-変更dylibs内のすべてのパス(必要とされ、他のdylibsに名前とパスをインストールする)我々はアプリ内で私たちのdylibsを入れしようとしているので、 "Frameworks"ディレクトリに移動し、アプリケーションを移動したり別のMacにコピーしたりすると、アプリケーションのディレクトリ内にある "frameworks"フォルダ内でdylibをお互いに探すことができます:

(2つの点は非常に重要です)

2必要なすべてのdylibをxCodeにコピーしますが、/ opt/local/libフォルダ内のすべてのdylibをコピーする必要はありません(すべてがあまりにも多分、おそらく500Mbです)。私たちが必要と知っているdylib(通常は4または5)からのリンクと、4または5人が作業のために必要とするために含まれるdylibです。

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

の1-すべてコピーは/ opt/libに/ローカルファイルをデスクトップに

Yは最終的に、このようにそれをやりました。

2 libフォルダ内の.dylibアーカイブ以外のすべてのファイルを削除します。

が(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 

私達はちょうどデスクトップにコピーした(dylibsと一緒に)のlibフォルダ内に、このスクリプトを3入れて

、4-それを実行します。dylibsは書き込み保護可能性があるため

cd Desktop/lib 
sudo ./theNameYouPrefer.sh 

sudoのようにそれを実行するために非常に重要です。

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

otool -L theDylibYouPrefer.dylib 

b)のlibフォルダのすべて、必要なだけdylibsを選択していない:

LIB2にlibフォルダを1-名前の変更:libが=== ==> lib2

2-デスクトップのNEXT TO lib2フォルダに別のフォルダ(好きな名前、たとえばexampleFolder)を作成します。

3-私の場合、それらが必要であることがわかっている重要なdylibをexampleFolder内にコピーします: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-スクリプト:重要なdylibの横にexampleFolderの中にコピーします。私は、スクリプトについて多くを知らないので、この1はもう少し汚れている:あなたはexampleFolder内のファイルの数が変化しないことを理解するまで

#!/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-、このスクリプトを多くの時間を実行します。

6必要なdylibはすべてexampleFolderの中にあります!私の場合、私は61のdylibを手に入れました。 (私たちがそこに4つのdylibを置いた時を思い出してください)

7最後にする必要があるのは、xCodeの "Frameworks"フォルダ内にドロップすることです。その後、ビルドフェーズに移動し、コピーファイルを追加してください。フェーズ: "エディタ" => "ビルドフェーズを追加" => "コピーファイルをビルドフェーズを追加する"と "コピーファイル"を挿入しますPHASE CLICK IN THE PLUSアイコンを追加し、「Framewroks」フォルダ内のすべての塵を追加します。あなたが必要とする目的地はFrameworksです。

そして、それは多かれ少なかれこのようにしています。

関連する問題