公司最近有一个项目,要求跨平台。UI 层使用 js 来写(具体技术我不是很清楚),在 OSX 平台上,我们提供 dylib 库来实现平台特殊功能。
在整合 dylib 过程中发现,需要将 dylib 放到 /usr/local/lib/ 目录下才能够在 APP 上正常调用到。那么问题来了。如果系统进行升级或者其他原因,导致我们的 dylib 丢失,我们程序不就不可用了?因此需要一个方式,来修改我们程序加载 dylib 的路径。
未成功的方法
经过百度,google,stackoverflow 一番查找,我们找到了以下的解决方案:
-
将 Library 内嵌到 APP 中。
-
设置需要 public 的头文件
001.png
-
dylib 嵌入到 App 中去
002.png
-
在 App 工程中设置 App 的头访问路径
003.png
-
准备签名
004.png
-
-
Archive 代码,导出 App 包
-
archive
005.png
006.png
007.png
-
双击 App
008.png
009.png
-
-
修改内嵌到 APP 中的 dylib 的加载路径与链接路径
打开终端,进入到 App 目录中。使用命令
otool -L Contents/MacOS/UI
与otool -L Contents/Frameworks/libLibraryTest.dylib
查看 APP 的依赖库的路径。这时候发现我们自定义的 dylib 库链接到系统目录/usr/local/lib/
下去了。而我们是将其作为 App 包内的内容打入到 App 内的,所以这里有问题。需要修改。修改之前,我们这里先埋下一个伏笔:使用命令codesign -vv Contents/Frameworks/libLibraryTest.dylib
查看一下 libLibraryTest.dylib 的签名状态。010.png
使用命令
install_name_tool -change /usr/local/lib/libLibraryTest.dylib @executable_path/../Frameworks/libLibraryTest.dylib "Contents/MacOS/UI"
与install_name_tool -id @executable_path/../Frameworks/libLibraryTest.dylib Contents/Frameworks/libLibraryTest.dylib
修改我们自定义的 dylib 加载路径。再次双击程序的时候发现仍然打不开。使用命令codesign -vv Contents/Frameworks/libLibraryTest.dylib
查看一下 libLibraryTest.dylib 的签名状态,后发现签名被改变了。😂。所以这种方式修改,不正确。011.png
附: 网络上加载到 Xcode 中 Script 中的部分代码。实现的是上面修改加载路径部分。不一定准确。
TARGETS=liblib.dylib
EXECFILE=${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}
LIBPATH=${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}
NEWLIBPATH=@executable_path/../Frameworks
#@executable_path/Frameworks
for TARGET in ${TARGETS} ; do
LIBFILE=${LIBPATH}/${TARGET}
TARGETID=`otool -DX "${LIBPATH}/$TARGET"`
NEWTARGETID=${NEWLIBPATH}/${TARGET}
install_name_tool -id "${NEWTARGETID}" "${LIBFILE}"
install_name_tool -change ${TARGETID} ${NEWTARGETID} "${EXECFILE}"
done
实现功能的方法
后来我们在工程中设置 dylib 的加载路径后,dylib 可以使用了。
![](https://img.haomeiwen.com/i2159939/095ea9fd8e7c5e63.png)
然后 Archive 导出包后双击后,程序启动。
![](https://img.haomeiwen.com/i2159939/055d1cb918b685c1.png)
总结
查找资料的时候,不能一味的相信别人实现的方式就是真理,需要实践并思考是否会有官方的方法替代。
网友评论