用objective-c开发的第一个mac程序(3)——动态库与静态库的问题

来源:互联网 发布:二战三巨头知乎 编辑:程序博客网 时间:2024/05/22 09:02

打包之后,在测试电脑安装后,程序需无法运行,错误是缺少链接库的错误:
错误代码:xxxxxxxxxxxx

在windows下,只要是将动态库放到可执行文件相同目录下就可以了,但是mac则不能使用这样的方法,拷到目录下运行依然出错;
–> 发现mac下的app是一个目录(这个根win的exe有很大区别),那拷到xxxx.app/Contents/MacOS/目录下也是不行;
–> 问了老大,放在xxxx.app/Contents/Frameworks下试试,依然是缺少链接库的错误;
–> 在Xcode工程目录下有个Runpath Search Paths的属性,默认是:$(inherited) @executable_path/../Frameworks
–> 那应该放在Frameworks是没有问题的啊,究竟为什么呢?
–> 另外动态库放在/Contents/MacOS/目录也应该是没有问题的?究竟又是为什么?

–> 使用 otool -L xxxxx.dylib 命令可查看其依赖的库
xxxx.dylib:
/usr/local/lib/xxxx.dylib (compatibility version 1.0.0, current version 1.0.0)
libboost_thread.dylib (compatibility version 0.0.0, current version 0.0.0)
libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
/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 1213.0.0)
xxxx.dylib /usr/local/lib/xxxx.dylib 这个是绝对目录,其他库/可执行文件调用他时,是在绝对路径:/usr/local/lib/下搜索
(不过这个例子不太好,/usr/local/lib/是系统目录,默认搜索的目录之一)
libboost_thread.dylib 依赖的库1,相对路径,xxxx.dylib在当前目录调用它;
libboost_system.dylib 依赖的库2,同上;
libc++1.dylib 依赖的库3,系统的库;
libSystem.B.dylib 同上;

–> xxxx.dylib 有个install_name的属性,可使用 install_name_tool 命令修改,如:
install_name_tool -id “@executable_path/../Frameworks/xxxx.dylib” xxxx.dylib
修改完成后,使用 otool -L xxxx.dylib 得如下结果:xxxx.dylib 已修改
xxxx.dylib:
@executable_path/../Frameworks/xxxx.dylib (compatibility version 1.0.0, current version 1.0.0)
libboost_thread.dylib (compatibility version 0.0.0, current version 0.0.0)
libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
/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 1213.0.0)

–> 修改install_name之后,重新生成可执行文件;

–> 出错,因为MacApp.app/Contents/Frameworks默认不存在,还手动需要拷贝到该目录下(不清除有没有自动添加这个目录的方法);

–> 再重新生成可执行文件,OK,但是无论是打包或者直接拷贝到测试的电脑,都是原来的错误;
–> 另外这样做经常会出现一个bug,Xcode中丢失mainmenu.xib找不到,
–> 把工程文件拷贝一份,在拷贝的那个工程打开再重新编译又OK了,
–> 但是打包后拿到测试电脑多错误始终没有解决,
–> 把@executable_path 换成@loder_path/../Frameworks/或者@loder_path/../dylibs/下也是这样,我就纳闷了;

–> 难不成它依赖的其他的库boost_system boost_thread的install_name有问题?换成想对路径,绝对路径都不行;
–> 难道要重新编译依赖库?这个我就暂时没有试验;
–> 面对一坨坨大问题,心态不够淡定啊;然后回家了,想着还有最后一个办法,不要动态库了,这个程序改用静态库链接算了;
–> 然后快快乐乐的改了,结果……

–> 重新编译boost的boost_system boost_thread库,./b2 variant=release link=static
–> 重新编译tinyxml库,cmake 生成 Xcode工程,编译release版的静态库tinyxml
–> 重新编译xxxx库,cmake GUI修改链接boost、tinyxml、t2l头文件和库文件所在目录,生成Xcode工程,编译release的静态库
–> 在objective-c的MacApp工程重新链接这个头文件库文件,然后,编译通过了,链接时出现一大堆的问题:apple mach-o linker error

–> 用xcode建个c++的工程,然后链接xxxx.a静态库(直接将xxxx.a拖到左边目录,就路径等就自动配置了),然后一大坨相同的错误;

–> 使用动态库的时候都能链接成功的,究竟是什么原因呢?

分析了这样的情况,比如有一下目录:
|-- main.cpp
|-- a.cpp inc1.h inc2.h
|-- b.cpp inc2.h inc3.h

用g++编译程序的时候应该是这样的:
gcc -c a.cpp 生成 a.o #编译
gcc -c b.cpp 生成 b.o #编译
gcc -static -o ab.a a.o b.o # 静态库
gcc -o test1 main.cpp ab.a # 链接

gcc -shared -o ab.dylib a.o b.o # 动态库
gcc -o test2 main.cpp -L ./ -lab #链接

使用命令:otool -L ab.a,看到的依赖的库是:a.o b.o,
原来静态库是不做链接对,只是将一个一个的.o集在一起,做成一个.a,
也就是.a是只编译但没有链接的,
难怪编译依赖库的静态库时基本不会出问题,而动态库却经常链接出错,因为静态库不做链接(这就意味着生成可执行文件(调用这个静态库的)时就需要链接了);
所以也不难解释,现在加到项目工程中,编译、生成可执行文件时,链接静态库的时候还是出一大堆的问题;

但是我将所有依赖的库的静态库都加进工程里,还是出现这样的错误,奇怪了;

到最后,不干了,到最后不用xxxx.a静态库了,重新编译一个xxxx.dylib(不依赖于boost库)
将xxxx.dylib的install_name改成:/Users/Shared/xxxx/xxxx.dylib

xxxx.dylib:
/Users/Shared/xxxx/xxxx.dylib (compatibility version 1.0.0, current version 1.0.0
/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 1213.0.0)

然后将xxxx.dylib放到/Users/Shared/xxxx/目录下,
将objective-c工程的库目录改成/Users/Shared/xxxx,编译,通过,
打包,将依赖的动态库放在Packages工程的payload的content列表多Users-Shared-xxxx下;
生成mpkg安装包,拿去测试的电脑,测试通过了!!!

注:以上是测试安装包;

总结:对编译原理没完全懂,有些方法还没有试就已经不淡定了;
这个解决方法算是用了旁门左道的,xxxx.app/Contents/Frameworks/这个东西还没解决;
这东西又催的急,感觉快撑不住了!还好算是好了!

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 养老保险领了几个月就挂了怎么办 高铁餐吧乘务员东西卖不出去怎么办 铁路局如果查出有乙肝怎么办 在火车站丢了东西怎么办 在新乡火车站丢了东西怎么办 自己的行李忘到高铁安检怎么办 高铁二等座睡觉怎么办 空少岁数大了怎么办 美国留学生办欧洲签证怎么办 苏州小区不让装充电桩怎么办 饿了么运力不足怎么办 书法落款写偏了怎么办 辐射4运行不流畅怎么办 vgs币忘了映射怎么办 货车把我的货物运输中损坏怎么办 道路货物运输从业资格证过期怎么办 高铁喷雾被扣了怎么办 宝宝不好好吸奶怎么办 宝宝不用劲吸奶怎么办 刚出生的宝宝不吃奶怎么办 老婆怀孕想吐怎么办呢 菜把下水道堵了怎么办 一楼厕所堵了怎么办 农村房屋确权有争议怎么办 盲审一个没过怎么办 本科生论文盲审不过怎么办 本科盲审没通过怎么办 一篇论文多次引用著作怎么办 学生毕业后改名学籍怎么办 大学毕业后改名字后学籍怎么办 考科目三下暴雨怎么办 挂科太多拿不到毕业证怎么办 挂科太多不给毕业证怎么办 大专毕业拿不到毕业证怎么办 高考差一分二本怎么办 3个月宝宝大小眼怎么办 华东交大理工学院没有评教怎么办 学校断4g网怎么办 学校移动4g网卡怎么办 没上专科线怎么办福建 联考没过本科线怎么办