用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/这个东西还没解决;
这东西又催的急,感觉快撑不住了!还好算是好了!
- 用objective-c开发的第一个mac程序(3)——动态库与静态库的问题
- 用objective-c开发的第一个mac程序(1)——依赖库的生成
- 用objective c开发的第一个mac程序(2)——初识oc cocoa swift
- Objective-C的第一个程序
- Objective-C——第一个OC程序,以及OC程序的结构分析
- Objective-C学习笔记(三)——用Objective-C编写第一个程序:Hello,World!
- Objective-C开发——最简单的Objective-C程序与基础语法解析
- 我的第一个Objective C程序 ,文件检索器
- 开发第一个C程序的步骤
- Objective-C 3 解析第一个程序
- 第一个Objective-C程序——Hello World!
- 黑马程序员--Objective-C——第一个OC程序
- 第一个Objective-C 程序
- 第一个objective-c程序
- 第一个Objective-C程序
- 第一个Objective-C程序
- objective-c : windows下搭建环境并编译自己的第一个objective-c程序
- Mac下的第一个C++程序—HelloWorld
- 暑假集训第三周周六赛 STL D - 胜利大逃亡
- 在VS2010上配置SGI_STL
- XCode上设备或证书不能自动建和修改的问题解决
- iOS UI04_Target-Action
- POJ1465 Multiple BFS+同余判重
- 用objective-c开发的第一个mac程序(3)——动态库与静态库的问题
- 黑马程序员——Java 面型对象_封装
- 27 水池数目【dfs】
- solr学习
- zoj 2100 Seeding 【dfs】
- 【Linux】如何用shell编写斐波那契函数
- Linux&C open creat read write lseek 函数用法总结
- openwrt 应用程序之netifd
- fork()和vfork()的区别,signal函数用法,exec()系列函数的用法小结