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干啥的?。。。。哈哈啊

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM