经过大量研究,我得到了它,我试图用我的应用程序打包一些 openCV dylib,因为我收到“库未加载:....”错误。
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- 第二行:安装您正在检查的 dylib 的名称。(macports 将它们安装在 /opt/local/lib/ 中)
3- 第三行:它需要工作的其他 dylib 的路径,这些路径并非在所有 OSX 系统中。(macports 将它们安装在 /opt/local/lib/ 中,因为您以前安装了它们,这就是为什么如果您将应用程序分发到其他 mac 会出现“找不到库”错误)
4 & 5 - 第 4 和 5 行:所有 macOSX 系统中的 dylib。您不需要将它们复制到您的项目中。
现在我们知道了这一点,我们的目标是:
1- 更改 dylibs 中的所有路径(安装名称和其他所需 dylibs 的路径),因为我们将把我们的 dylibs 放在应用程序的“Frameworks”目录中,当我们移动应用程序或将其复制到其他 mac我们希望 dylib 在我们应用程序目录内的“frameworks”文件夹中相互查找:我们将使用的路径是:
@executable_path/../Frameworks/nameOFTheDylib.dylib
(注意这两点非常重要!)
2-将我们需要的所有dylib复制到xCode,但不是/opt/local/lib文件夹中的所有dylib,只是我们需要的:(它们都太多了,可能500Mb)我们需要遵循来自我们知道我们需要的 dylib(通常是 4 或 5 个)和包含的 dylib 的链接,因为这 4 或 5 个需要它们才能工作。
Y终于这样做了:
a) 更改路径:
1- 将所有 /opt/local/lib 文件复制到桌面。
2- 删除 lib 文件夹中所有不是 .dylib 档案的文件。
3-将此脚本放入我们刚刚复制到桌面的 lib 文件夹中(连同 dylibs):
(将这段文字复制到 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
将它作为 sudo 运行非常重要,因为 dylib 可以被写保护。
此时,您应该更改了所有 dylibs 路径。您可以使用以下命令在一些 dylib 中检查它:
otool -L theDylibYouPrefer.dylib
b) 只选择所需的 dylib,而不是所有 lib 文件夹:
1-将lib文件夹重命名为lib2:lib =====> lib2
2- 在桌面的 NEXT TO lib2 文件夹中创建另一个文件夹(使用您喜欢的名称,例如 exampleFolder)。
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-你需要的dylibs都在exampleFolder里面!就我而言,我有 61 个 dylib。(记得我们开始的时候我放了 4 个 dylib)
7-您需要做的最后一件事是将xCode中的“Frameworks”文件夹放入其中。之后记得转到“构建阶段”并添加“复制文件”阶段:“编辑器”=>“添加构建阶段”=>“添加复制文件构建阶段”并在“复制文件”阶段中单击加号图标并添加您在“Framewroks”文件夹中找到的所有 DYLIBS。您需要的目的地是框架。
就是这样,我或多或少是这样理解的。