题
我想在Xcode中创建一个MAC的应用程序,有一些在动态库实现的。
我添加了一个新的目标(动态链接库),以我的XCode可可项目和一个位与框架和预编译头的战斗后,有dynlib编译 - 从调试成功运行
当独立运行但是其明显的是,dynlib是在错误的地方。 “库未加载:/usr/local/lib/testlib.dynlib”。在Windows上 - 我更常见的平台 - 的dll可以放在同一文件夹中的exe和系统路径上的任何地方。
。我宁愿像我的应用程序查找其dynlib都在其应用程序包(和某些文件似乎证实这是正确的做法),但我不知道怎么办。
是否有可能配置在Xcode项目,让dylib实际上被复制到应用程序包,在一个地方,应用程序将寻找它?
看来,我不需要用otool重置搜索路径。如果我编辑目标信息 - >构建 - >部署 - >安装目录,我可以改变,从里面的XCode,这dyld的路径是要去看看的dylib。默认情况下,一个新的动态库项目,路径设置为/usr/local/lib
。这是我改变./
- otool确认./是现在在哪里dyld的是要寻找这个特定的动态模块。不幸的是./似乎并没有实际上是指任何目录在我的应用程序包:(
所以,我的问题(在其他线程没有回答)现在: 1.我如何输入一个有意义的相对的在目标信息路径 - > - >安装目录设置, 2.我怎样才能获得的XCode到dylib“目标”自动复制到应用程序包中目标的包文件夹中的相对位置?
解决方案
最后。发现了一些官方文档。其可能做到这一点完全内的XCode。
我中途有修改库的安装的目录设置:它需要的是:
@executable_path/../Frameworks
然后我需要添加一个“复制文件”建立步骤实际上它复制到文件夹框架库。
简单。自动的。
其他提示
我相信你是不是在编译时复制的动态库到应用程序包。
应用程序正在寻找在文件系统中的一个点,但应用程序束内部没有找到它之后它仅执行此操作。您需要使用otool
命令来修改它的二进制编译后(使用编译脚本)。
您会发现你在这以前问的问题回答: 如何创建一个动态库在Xcode
好运。
经过大量的研究,我知道了,我是想打包一些OpenCV的dylib与我的应用程序,因为我收到了“库未加载:......”。误差
Dylibs有一个安装名称,指示您安装它们,当你做了它的第一次(使用MacPorts安装它们的/ opt / local / lib目录/)。 他们也有路径与其他dylib的,他们需要工作。例如,如果你有称为dylib“libopencv_core.2.4.8.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-下联:安装正在检查的dylib的名称。 (MacPorts的安装它们在/ opt / local / lib目录/)
3-第三行:路径,它需要的是并非在所有OSX系统工作其他dylibs。 (MacPorts的安装它们在/ opt / local / lib目录/和你有他们,因为你以前安装的,这就是为什么如果你发布你的应用程序到其他Mac你得到的“库未找到”错误)
4&5 - 线4和5:dylibs所有MACOSX系统内部。你并不需要他们在你的项目中复制。
现在我们知道这一点,我们的目标是:
1更改内部dylibs所有路径(安装的名称和路径是需要的其他dylibs),因为我们要提出我们的dylibs内部应用程序,在“框架”目录,当我们移动应用程序或复制到其他Mac,我们希望dylibs寻找对方内线“框架”我们的应用程序的目录文件夹里面:我们将使用的路径是:
@executable_path/../Frameworks/nameOFTheDylib.dylib
(注意两点是很重要!)
2 - 复制到Xcode中,我们需要的所有dylibs,但不是到/ opt / local / lib目录文件夹内的所有dylibs,只是那些我们需要:(所有的人都太多了,也许有500MB),我们将需要跟随从我们知道我们需要的dylibs的链接(通常是4或5)和被包括,因为这些4或5需要他们工作dylibs。
ý终于做到了这种方式:
一)要改变的路径:
1-全部/选择/ local / lib目录文件复制到桌面上。
2-除去未名为.dylib档案库文件夹内的所有文件。
3将这个脚本lib文件夹(与dylibs一起)我们刚才复制在桌面内:
(在文本编辑复制这个文本并将其保存为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可以写保护。
在这一点上,你应该有所有的dylibs路径改变。你可以用命令来检查在一些dylibs:
otool -L theDylibYouPrefer.dylib
b)选择只是dylibs需要,不是所有的lib文件夹的:
1-重命名lib文件夹到LIB2:LIB =====> LIB2
2-创建另一个文件夹(与您喜欢的名称,例如exampleFolder)在桌面上,旁边LIB2文件夹中。
3-副本中exampleFolder,你知道你会需要他们肯定的重要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-脚本:复制它里面exampleFolder,旁边的重要dylibs。我不知道很多关于脚本,所以这一块是比较有点脏:
#!/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-你需要的dylibs都是他们的内部exampleFolder!就我而言,我得到了61个dylibs。 (记住,当我们开始我放在那里4个dylibs)
7,你需要做的是放下了“框架”文件夹在Xcode的最后一件事。在此之后记得要“建设阶段”,并添加“复制文件”阶段:“编辑” =>“添加构建阶段” =>“添加文件拷贝建设阶段”,INSIDE在PL“复制文件” PHASE CLICK美国图标并添加那里所有的DYLIBS你发现“框架”文件夹中。你需要的目的地是框架。
和那它,我知道了这种方式更多或更少。