g++ 静态库连接顺序的巨坑

在编译最新版本(12.04)的alljoyn的chat示例的时候,想使用bundle daemon,依照在以前的经验修改文件:alljoyn-14.02.00-src/build/linux/x86_64/debug/dist/samples/chat/makefile:

LIBS = -lalljoyn ../../lib/BundledRouter.o -lajrouter -lstdc++ -lcrypto -lpthread -lrt

1). 编译ok,但运行时报错:

./chat
./chat: error while loading shared libraries: liballjoyn.so: cannot open shared object file: No such file or directory

原来../../lib/目录下有两个库:

ll ../../lib/
total 71552
drwxr-xr-x 2 z.rao CAF     4096 Apr  9 19:56 ./
drwxr-xr-x 6 z.rao CAF     4096 Apr  9 18:35 ../
-rw-r--r-- 1 z.rao CAF   529336 Apr  9 18:36 BundledRouter.o
-rw-r--r-- 1 z.rao CAF 38765950 Apr  9 18:36 libajrouter.a
-rw-r--r-- 1 z.rao CAF 24335844 Apr  9 18:35 liballjoyn.a
-rwxr-xr-x 1 z.rao CAF  9621229 Apr  9 19:56 liballjoyn.so*

默认连接的是动态库:liballjoyn.so*

虽然可以通过ldconfig搞定动态库的连接问题,但考虑到程序的发布问题,我决定连接静态库liballjoyn.a

2).于是,删除liballjoyn.so,这样程序就会连接到静态库liballjoyn.a了:

rm ../../lib/liballjoyn.so
make clean;make

很不幸报错:

g++ -c -Wall -pipe -std=c++98 -fno-rtti -fno-exceptions -Wno-long-long -Wno-deprecated -g -DQCC_OS_LINUX -DQCC_OS_GROUP_POSIX -DQCC_CPU_X86 -I../../inc -o chat.o chat.cc
g++ -o chat chat.o -L../../lib -lalljoyn ../../lib/BundledRouter.o -lajrouter -lstdc++ -lcrypto -lpthread -lrt
../../lib/BundledRouter.o: In function `BundledRouter::Start(ajn::NullTransport*)‘:
/home/z.rao/work/Library/alljoyn-14.02.00-src/alljoyn_core/router/bundled/BundledRouter.cc:263: undefined reference to `qcc::LoggerSetting::GetLoggerSetting(char const*, int, bool, _IO_FILE*)‘
../../lib/BundledRouter.o: In function `ajn::PasswordManager::GetPassword()‘:
/home/z.rao/work/Library/alljoyn-14.02.00-src/alljoyn_core/inc/alljoyn/PasswordManager.h:65: undefined reference to `ajn::PasswordManager::password‘
../../lib/BundledRouter.o: In function `ajn::PasswordManager::GetAuthMechanism()‘:
/home/z.rao/work/Library/alljoyn-14.02.00-src/alljoyn_core/inc/alljoyn/PasswordManager.h:71: undefined reference to `ajn::PasswordManager::authMechanism‘
../../lib/libajrouter.a(TCPTransport.o): In function `ajn::TCPTransport::GetListenAddresses(ajn::SessionOpts const&, std::vector<qcc::String, std::allocator<qcc::String> >&) const‘:
/home/z.rao/work/Library/alljoyn-14.02.00-src/alljoyn_core/router/TCPTransport.cc:1193: undefined reference to `qcc::IfConfig(std::vector<qcc::IfConfigEntry, std::allocator<qcc::IfConfigEntry> >&)‘
../../lib/libajrouter.a(TCPTransport.o): In function `ajn::TCPTransport::Connect(char const*, ajn::SessionOpts const&, qcc::ManagedObj<ajn::_BusEndpoint>&)‘:

没有定义?

看看导出了哪些符号?

nm -C ../../lib/liballjoyn.a |grep GetLoggerSetting
0000000000000476 T qcc::LoggerSetting::GetLoggerSetting(char const*, int, bool, _IO_FILE*)
0000000000000000 W qcc::LoggerSetting::GetLoggerSetting()

明明已经定义了啊.....哭。。。

之前连接动态库liballjoyn.so就可以,静态库liballjoyn.a为什么不行呢?。。。。百思不得其解

3).想来想去,可能是静态库的连接顺序导致了循环依赖,除此以外似乎没有其他可能了。

于是网上猛搜一通,发现

http://www.cnblogs.com/wujianlundao/archive/2012/06/06/2538125.html

将makefile修改为如下形式:

LIBS = -Xlinker "-(" -lalljoyn ../../lib/BundledRouter.o -lajrouter -Xlinker "-)" -lstdc++ -lcrypto -lpthread -lrt

果然搞定了!

要问-Xlinker干啥的?。。。。哈哈啊
时间: 2024-11-13 09:08:27

g++ 静态库连接顺序的巨坑的相关文章

CMake和静态库顺序

目录 目录 1 前言 1 方法 1 附1:链接静态库的顺序问题 2 附2:再议GCC编译时的静态库依赖次顺问题 3 附3:gcc链接参数--whole-archive的作用 4 附4:让有些"-l"链接静态库,而另一些链接共享库? 6 附5:相关博文 6 前言 C/C++程序的许多同学被静态库的依赖折腾,因为默认情况下要求被依赖的库放在依赖它的库后面,当一个程序或共享库依赖的静态库较多时,可能会陷入解决链接问题的坑中.如果对静态库不熟悉,需要结构nm等工具来解决顺序问题. 但也可以偷懒

gcc/g++链接时.o文件及库的顺序问题

折腾gcc/g++链接时.o文件及库的顺序问题 链接静态库的顺序问题 GCC 编译使用动态链接库和静态链接库--及先后顺序----及环境变量设置总结

技巧:Linux 动态库与静态库制作及使用详解

技巧:Linux 动态库与静态库制作及使用详解 标准库的三种连接方式及静态库制作与使用方法 Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 Linux 版本下不兼容的问题: 2)在 Linux 静态库的制作过程中发现有别于 Windows 下静态库的制作方法:3)在 Linux 应用程序链接第三方库或者其他静态库的时候发现链接顺序的烦人问题.本文就这三个问题针对 Linux 下标准库链接和如何巧妙构建 achrive(*.a) 展开相关介

Linux 静态库&amp;动态库调用

1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不兼容的.本文仅限于介绍linux下的库.2.库的种类linux下的库有两种:静态库和共享库(动态库).二者的不同点在于代码被载入的时刻不同.静态库的代码在编译过程中已经被载入可执行程序,因此体积较大.共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小.3.库存在

[Bada开发]使用静态库

bada是三星公司自主研发的操作系统,本文介绍了如何创建静态文件,将它们与你的程序连接起来,在你的程序中使用静态库的方法.静态库让用户可以连接程序,而不需重新编辑代码,从而节省了编辑时间. 静态库把目标文件集合起来,使用ar (archive)程序创建.静态库的二进制文件以"a"拓展名结束.静态库让用户可以连接程序,而不需重新编辑代码,从而节省了编辑时间. 本文介绍了如何创建静态文件,将它们与你的程序连接起来,在你的程序中使用它们的方法.(推荐阅读:在bada程序中使用共享库) 创建静

动态库与静态库优缺点比较

动态库与静态库优缺点比较 (2012-10-18 15:31)      我们在编写一个C语言程序的时候,经常会遇到好多重复或常用的部分,如果每次都重新编写固然是可以的,不过那样会大大降低工作效率,并且影响代码的可读性,更不利于后期的代码维护.我们可以把他们制作成相应的功能函数,使用时直接调用就会很方便,还可以进行后期的功能升级.  例如我要在一段代码中多次交换两个变量的值,我可以在代码中多次写入 i=x;x=y;y=i; 不过这样未免有点麻烦我们可以编写一个change_two_int()函数

gcc/g++动态链接库和静态库的链接顺序

转自:http://withc8212.blog.163.com/blog/static/11656983820109263562854/ so文件:动态库a文件: 静态库exe文件:可执行程序(linux下以文件属性来标示是否是可执行文件,与后缀名无关) 经过自己写的一些测试程序,大致了解了下gcc中链接顺序问题,总结出以下几点:1,动态库中可以包含另一个静态库,通过参数 -lxxx 把静态库libxxx.a加入so文件中,这样so文件中   就包含了libxxx.a的所有实现.当然,如果不包

g++编译使用生成静态库和动态库(Linux)

参考文献: Linux下g++编译与使用静态库和动态库 用g++编译生成动态链接库*.so的方法及连接(多个.cc生成一个*.so) 占坑

[转]Linux下用gcc/g++生成静态库和动态库(Z)

Linux下用gcc/g++生成静态库和动态库(Z) 2012-07-24 16:45:10|  分类: linux |  标签:链接库  linux  g++  gcc  |举报|字号 订阅 在 linux 下,库文件一般放在 /usr/lib 和 /lib 下, 静态库的名字一般为 libxxxx.a ,其中 xxxx 是该 lib 的名称 动态库的名字一般为 libxxxx.so.major.minor , xxxx 是该 lib 的名称, major 是主版本号, minor 是副版本号