質問
私は、動的ライブラリでの実装のいくつかを持ってXcodeでMacのアプリケーションを作成しようとしています。
私はXCodeのココアプロジェクトに新しいターゲット(動的ライブラリ)を追加し、フレームワークとプリコンパイル済みヘッダーを戦うのビットの後、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「ターゲット」をコピーするために得ることができますか?
解決
最後に。いくつかのをrel="noreferrer">が見つかりました。完全にXCodeの内、これを行うために、その可能ます。
私は、ライブラリのインストールディレクトリの設定を変更する途中だった:それはする必要がありました。
@executable_path/../Frameworks
は、それから私は、「ファイルのコピー」を追加し、実際にフレームワークのフォルダにコピーするライブラリへのステップを構築するために必要な。
シンプル。自動ます。
他のヒント
私はあなたがコンパイル時にアプリケーションバンドルに動的ライブラリをコピーしていないと信じています。
アプリケーションは、ファイルシステム内のポイントを探しているが、それは唯一のアプリケーションバンドル内でそれを見つけていない後にこれを行います。あなたはそれが(ビルドスクリプトを使用して)コンパイルされた後、バイナリを変更するためにotool
コマンドを使用する必要があります。
あなたはこれ以前に尋ねた質問に答えています: どのように私はXcodeで動的ライブラリを作成してください。。
幸運ます。
私はそれを得た多くの研究の後、私は自分のアプリケーションでいくつかのOpenCVのdylib年代をパッケージ化しようとしていました
Dylibsは、あなたがそれを最初に行ったとき、あなたがそれらをインストールした場所(MacPortsのは、上の/ opt / local / libの/それらをインストールします)を示し、インストールの名前を持っています。 彼らはまた、彼らが作業する必要があることを他のdylibのパスを持っています。
:たとえば、あなたが「libopencv_core.2.4.8.dylib」と呼ばれるdylibを持っている場合は、このコマンドで使用する他のdylibsにインストール名とパスを確認することができます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システムにない仕事に必要他dylibsへのパス。 (MacPortsのはは/ opt / local / libの中にそれらをインストール/、あなたが以前にインストールされているため、あなたがそれらを持っている、のthatsなぜあなたは他のMacにアプリを配布する場合は、「ライブラリが見つかりません」というエラーが発生します)。
4&5 - ライン4および5:すべてのMacOSXのシステム内部dylibs。あなたのプロジェクトでそれらをコピーする必要はありません。
今、私たちはこのことを知って、私たちの目標は次のとおりです:
の1-変更dylibs内のすべてのパス(必要とされ、他のdylibsに名前とパスをインストールする)私たちは、「フレームワーク」ディレクトリにアプリ内で私たちのdylibsを入れしようとしているので、我々はアプリを移動またはコピーするとき他のMacに我々はdylibsは我々のアプリのディレクトリ内に互いに内側に「フレームワーク」フォルダを探したい:私たちが使用するパスはあります:
@executable_path/../Frameworks/nameOFTheDylib.dylib
(2つの点が非常に重要であることに注意してください!)
(それらのすべてが、あまりにも多分500MBです)私たちが必要となります。2 - コピーは、/ opt / local / libのフォルダ内のすべてのdylibs、私たちに必要なものだけを、私たちが必要とするすべてdylibsをXCodeのではなくします我々は(通常は4または5)必要知っdylibs及びそれらの4または5が作業のためにそれらを必要とするため、含まれているdylibsからリンクをたどるます。
Yは最終的に、このようにそれをしなかった。
A)パスを変更する
1-デスクトップにすべての/ opt / local / libのファイルをコピーします。
2 - アーカイブのは.dylibされませんlibフォルダ内のすべてのファイルを削除します。
libフォルダ(一緒にdylibsで)私達はちょうどデスクトップにコピーした内部では、このスクリプトを3-置きます:
(テキストエディットでこのテキストをコピーし、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
dylibsが書き込み保護される可能性があるため、sudoのようにそれを実行するために本当に重要です。
この時点で、すべてのdylibsパスが変更されている必要があります。あなたは、コマンドを使用して、いくつかのdylibsでそれを確認することができます:
otool -L theDylibYouPrefer.dylib
B)だけdylibsは、libフォルダのすべてを必要としませ選びます:
1-名前の変更LIB2にlibフォルダ:LIB =====> LIB2
2-デスクトップで、次のフォルダをLIB2 TO(たとえばexampleFolderのために、お好みの名前の)別のフォルダを作成します。
exampleFolder内部の3-コピーし、あなたは確かに彼らが必要になります知っている重要なdylibsは、私の場合には、それらは以下のとおりです。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 - スクリプト:次の重要なdylibsに、exampleFolder内にコピーします。私は、スクリプトについて多くを知らないので、この1はもう少し汚れてます:
#!/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
あなたはexampleFolder内のファイルの数が変化しないことを理解するまで、5-、このスクリプトを多くの時間を実行します。
あなたが必要とする6 dylibsは、それらのすべてexampleFolder内側にあります!私の場合、私は61 dylibsを得ました。 (私たちは、私はそこに4 dylibsを置い始めたときを思い出してください)。
あなたがする必要がある、7-最後の事は、Xcodeで、「フレームワーク」フォルダ内にドロップします。それは、「ビルドフェーズ」に移動し、「コピーファイル」フェーズを追加することを忘れないでください後:「編集者は」=>「ビルドフェーズを追加」=>は、「コピーファイルはビルドフェーズ追加」AND PL IN「のコピーファイル」PHASEかちりINSIDE米国のアイコンとそこには「フレームワーク」フォルダ内にFIND ALL DYLIBSを追加します。あなたが必要とする先がフレームワークです。
そして、それのthats、私はそれを得た。この方法多かれ少なかれます。