qt编译的一些问题:
1、qt static
编译程序时默认gcc静态编译,libtommath也是静态编译
只能生成.a库文件,生成不了动态库因为.so库不可包含静态qt库;生成.a库后,可以动态使用,也可静态编译进程序中
2、qt run 或 deb
编译程序时默认动态编译链接,生成elf;需要库文件,不管是.a 还是.so 都需要;不过可以修改makefile把.a静态编进去
生成.so库文件时不能包含静态库,生成so,可以依赖于另外一个.so,程序调用该库时把依赖库加进去就可以了
动态库静态库的生成
1、一个dll或so文件,如果要生成一个动态库,那么源程序所引用的库也必须是动态的,因为静态库没有经过重定位(??待考证)。静态库不是使用PIC选项编译的,所以不能用来生成动态库,必须重新编译源文件;也即编译动态库,不可以引用静态库。
2、一个a和lib静态库,只是编译没有经过链接。所以生成静态库可以不用管任何依赖(动态库依赖,静态库依赖),只要有库头文件包含进去,编译通过即可,因为生成静态库只是.o的打包而已,没有经过链接这一步。既然没有经过链接,那么即使源程序用到动态库也没问题(只用引用动态库头文件解决编译问题即可)。也即生成静态库的程序,可以里边包含静态和动态库。
(error 也即想要生成一个静态库,最好将程序源文件所有依赖都转为静态,然后静态编译才能生成一个不依赖任何库的a和lib; error);
3、不管静态或动态库,生成的时候,都可以不用指定任何依赖库,只要有相应头文件编译通过即可。至于指定库完全可以交给引用该库的程序来做。 但这样做非常不好,因为库的依赖关系不明确,别人都不知道你这个库,还依赖于另外一个什么库,只有你自己知道,别人也没法用。
4、建议生成动态库时,一定要把所依赖的库文件指定一下,这样"ldd libxxx.so"就可以查看到依赖关系,别人也可以找到相应依赖库。如果不指定依赖,那么ldd查看不到依赖库,本以为解决了依赖,可总也链接不通过,别人也不知道到底还有啥依赖库。
建议生成静态库时,不必指定任何所依赖的静态库和动态库,有头文件即可,因为只编译不链接。
5、注意静态库不可执行(readelf -a libxxx.a|grep lib),动态库可执行和elf一样(ldd libxxx.so)。
生成一个可执行文件,可以部分静态编译,部分动态链接(注意非编译)。
动态库静态库的使用
1、明确:动态库使用时:只能非静态使用。本质只有在链接才起作用,仅.h文件在编译阶段起作用。(其实.h都可以不要,但前提你要知道dll都有什么函数),生成elf必须能找到动态库。
2、明确:静态库使用时:
如果静态编译程序,那么该库就会在编译阶段,完全包括进去,链接就没有什么作用了,并且生成elf文件后,库就没什么作用了
如果非静态编译程序,那么该库就会在链接阶段起作用,生成elf文件必须能找到静态库。此时就和动态库没有什么区别了。
3、明确:生成一个可执行文件,可以部分用一个静态库来静态编译,部分用一个动态库来动态链接。 -Wl,-static -lev -Wl,-call_shared -lnsl -lclntsh -lnnz11 -lm
http://blog.zheezes.com/senior-gcc-compiler-link-parameters.html
4、明确:前边说到elf运行时必须要找到库,那么怎么指定库的路径呢? 程序运行时,又是按什么顺序搜索的呢?
1)运行时搜索库顺序 (http://blog.sina.com.cn/s/blog_5ac88b350100bdd8.html)
a)-Wl,-rpath
b)export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
c)/etc/ld.so.conf
d)默认路径/lib和/usr/lib
2)最好编译链接时添加 -Wl,-rpath=./ (当前目录查找) -Wl,-rpath=/home/oracle/db_1/lib -Wl,-rpath=/home/app/oracle
3)其他方法增加一个初始化的脚本设置PATH或者修改profile文件
(http://www.cnblogs.com/panfeng412/archive/2011/10/20/library_path-and-ld_library_path.html)
a)export LD_LIBRARY_PATH=LIBDIR1:LIBDIR2:$LD_LIBRARY_PATH (运行时库路径查找) 可以写一个shell,每次自动运行
b)/etc/ld.so.conf ldconfig 这个必须手动修改了就。
c)当然也可以直接把所有库cp放进/usr/lib /usr/share/lib等等系统默认库路径中。
5、明确:程序编译链接时,也要找到库的位置,那么怎么指定库的路径呢? 程序编译链接时,按什么顺序搜索呢?
1)编译时搜索库顺序 (http://blog.sina.com.cn/s/blog_7195909a0100zi7i.html)
a)gcc会去找-L
b)再找gcc的环境变量LIBRARY_PATH
c)再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的(不可配置的?)
2) 最好这样使用 -L./lib -Wl,-static -lev -Wl,-call_shared -lnsl -lclntsh -lnnz11 -lm
6、 -L/usr/lib -lwdapi1160 -lQtGui -Wl,-O1 -shared -Wl,-soname,libsmx.so.1