libjingle的XmppPump编译问题

Posted

技术标签:

【中文标题】libjingle的XmppPump编译问题【英文标题】:libjingle's XmppPump compilation problem 【发布时间】:2011-05-10 15:05:10 【问题描述】:

我刚开始使用 libjingle 编写一个 gtalk 聊天机器人。我在让编译器找到 XmppPump 类调用的 XmppClient 类时遇到问题。 XmppClient 由 libjingle 在 talk/xmpp/xmppclient.h 文件中提供,但由于某种原因,它对我不起作用,最近让我很沮丧。希望大家能帮帮我!

我使用的是 libjingle-0.5.1,我的 g++ 编译器版本是 4.4.5。我的操作系统是 Ubuntu 10.10,32 位。

这是我尝试编译代码的方式:

g++ -g -Werror -DPOSIX -DEXPAT_RELATIVE_PATH -DFEATURE_ENABLE_SSL -DHAVE_OPENSSL_SSL_H=1 -I../include -I../misc/libjingle-0.5.1 -I../misc/libjingle-0.5.1/talk/third_party/expat-2.0.1 -I../misc/libjingle-0.5.1/talk/third_party/srtp/include -L../lib -lpthread -lssl -o ../bin/gtalk_bot.bin ../obj/main.o /usr/local/lib/libglog.a ../misc/libjingle-0.5.1/talk/build/dbg/lib/libjingle.a ../misc/libjingle-0.5.1/talk/build/dbg/lib/libexpat.a ../misc/libjingle-0.5.1/talk/build/dbg/lib/libsrtp.a ../misc/libjingle-0.5.1/talk/build/dbg/lib/libxmpphelp.a

这是错误信息:

../misc/libjingle-0.5.1/talk/build/dbg/lib/libxmpphelp.a(xmpppump.o):在函数“XmppPump::XmppPump(XmppPumpNotify*)”中: xmpppump.cc:(.text._ZN8XmppPumpC2EP14XmppPumpNotify+0x6e): 未定义引用`buzz::XmppClient::XmppClient(talk_base::TaskParent*)' ../misc/libjingle-0.5.1/talk/build/dbg/lib/libxmpphelp.a(xmpppump.o):在函数“XmppPump::XmppPump(XmppPumpNotify*)”中: xmpppump.cc:(.text._ZN8XmppPumpC1EP14XmppPumpNotify+0x6e): 未定义引用`buzz::XmppClient::XmppClient(talk_base::TaskParent*)' ../misc/libjingle-0.5.1/talk/build/dbg/lib/libxmpphelp.a(xmpppump.o):在函数`XmppPump::DoLogin(buzz::XmppClientSettings const&,buzz::AsyncSocket*,buzz: :PreXmppAuth*)': xmpppump.cc:(.text._ZN8XmppPump7DoLoginERKN4buzz18XmppClientSettingsEPNS0_11AsyncSocketEPNS0_11PreXmppAuthE+0xa9):未定义引用`buzz::XmppClient::Connect(buzz::XmppClientSettings const&, std::basic_string, std::allocator > const&, buzz::AsyncSocket*, buzz ::PreXmppAuth*)' ../misc/libjingle-0.5.1/talk/build/dbg/lib/libxmpphelp.a(xmpppump.o):在函数“XmppPump::DoDisconnect()”中: xmpppump.cc:(.text._ZN8XmppPump12DoDisconnectEv+0x25): 未定义引用`buzz::XmppClient::Disconnect()' ../misc/libjingle-0.5.1/talk/build/dbg/lib/libxmpphelp.a(xmpppump.o):在函数“XmppPump::SendStanza(buzz::XmlElement const*)”中: xmpppump.cc:(.text._ZN8XmppPump10SendStanzaEPKN4buzz10XmlElementE+0x2c): 未定义引用`buzz::XmppClient::SendStanza(buzz::XmlElement const*)' collect2: ld 返回 1 个退出状态 制作:*** [../bin/gtalk_bot.bin] 错误 1

这是我的代码:

#include <string>
#include <iostream>
#include <assert.h>
#include <getopt.h>
#include "glog/logging.h"
#include "talk/base/thread.h"
#include "talk/base/physicalsocketserver.h"
#include "talk/base/socketaddress.h"
#include "talk/base/cryptstring.h"
#include "talk/base/ssladapter.h"
#include "talk/xmpp/jid.h"
#include "talk/xmpp/xmppclient.h"
#include "talk/xmpp/xmppclientsettings.h"
#include "talk/examples/login/xmpppump.h"
#include "talk/examples/login/xmppauth.h"
#include "talk/examples/login/xmppthread.h"

using namespace std;

int readCommandLineArguments(int argc, char **argv);
int getUserName(string *username);
int getPassword(string *password);

buzz::Jid serverJid;
string username;
string password;
string auth_cookie;


int main(int argc, char **argv)
 int status = 0;

 // use: GLOG_log_dir="log" ./gtalk_bot.bin
 google::InitGoogleLogging(argv[0]);

 talk_base::PhysicalSocketServer pss;
 talk_base::AutoThread main_thread(&pss);

 // Get the information we'll need to sign in
 buzz::Jid jid;
 talk_base::InsecureCryptStringImpl pass;
 buzz::XmppClientSettings xcs;
 XmppPump pump;
 //XmppHandler xhandler;

 status = readCommandLineArguments(argc, argv);

 if(username.empty())
  // get the user name if there's none in the command line argument
  status = getUserName(&username);
 
 jid = buzz::Jid(username);
 assert(jid.IsValid() || jid.node() != "");

 if(!username.empty() && password.empty())
  // If username is provided, but the password isn't, ask for one.
  status = getPassword(&password);
 
 pass.password() = password;

 // Turn on SSL
 talk_base::InitializeSSL();

 xcs.set_user(jid.node());
 xcs.set_resource("one_chat_bot"); //TODO: need to investigate what this is
 xcs.set_host(jid.domain());
 xcs.set_use_tls(true);
 xcs.set_pass(talk_base::CryptString(pass));
 xcs.set_server(talk_base::SocketAddress("talk.google.com", 5222));

 //xhandler.DoLogin(xcs, new XmppSocket(true), NULL);
// xhandler.DoLogin(xcs, new XmppSocket(true), NULL);
 main_thread.Run();
// xhandler.DoDisconnect();

 //delete objects here

 return 0;




int readCommandLineArguments(int argc, char **argv)
 int input = 0;
 int rc = 0;
 int options_index = 0;

 static struct option long_options[] = 
  "username", required_argument, 0, 'u',
  "password", required_argument, 0, 'p',
  0, 0, 0, 0
 ;

 while((input = getopt_long(argc, argv, "u:p:", long_options, &options_index)) != -1 && rc == 0)
  switch(input)
   case 'u':
    if(optarg)
     username = optarg;
    
    break;
   case 'p':
    if(optarg)
     password = optarg;
    
    break;
   case '?':
   default:
    rc = 1;
    break;
  
 

 return rc;




int getUserName(string *username)
 int rc = 0;

 cout << "google username: ";
 cin >> *username;

 return rc;



int getPassword(string *password)
 int rc = 0;

 cout << "password: ";
 cin >> *password;

 return rc;

这是我的目录结构。有三个 libjingle 文件夹,因为我正在试验和尝试不同的东西,看看我是否可以解决编译问题。除了将 expat-2.0.1/ 和 srtp/ 文件夹复制到 libjingle/talk/third_party/ 文件夹之外,libjingle 文件夹没有变化。 libjingle-0.5.1/ 目录结构与位于此处的 svn 主干几乎相同:

http://code.google.com/p/libjingle/source/browse/trunk/#trunk

除了我的 libjingle-0.5.1 文件夹已经编译好了。

gtalk_bot$ ls * 垃圾箱: 日志 包括: 库: 杂项: expat-2.0.1 glog-0.3.1.tar.gz libjingle-0.4.0.tar.gz libjingle-0.5.1 libjingle-0.5.tar.gz srtp swtoolkit expat-2.0.1.tar.gz libjingle-0.4.0 libjingle-0.5 libjingle-0.5.1.zip scons-2.0.1.tar.gz srtp-1.4.4.tgz swtoolkit.0.9.1.zip 对象: main.o XmppHandler.o 源代码: main.cc main.o Makefile SConstruct XmppHandler.cc XmppHandler.h XmppSocket.cc XmppSocket.h 测试:

这是 libjingle 的构建目录:

gtalk_bot/misc/libjingle-0.5.1/talk/build/dbg$ ls * 库: libexpat.a libjingle.a libsrtp.a libxmpphelp.a 对象: 基本调用示例 libexpat.a libjingle.a libsrtp.a libxmpphelp.a login p2p relayserver session stunserver third_party xmllite xmpp 分期: 调用登录中继服务器 stunserver

【问题讨论】:

如果您能提供给我们目录结构将会很有帮助 好的,我添加了目录结构。希望它会有所帮助。请务必检查 libjingle SVN 主干链接以检查目录结构以及头文件和源文件所在的位置。 【参考方案1】:

非常感谢 libjingle 团队解决了我的问题。显然,静态库排序很重要。我只需要重新排序库即可:

libxmpphelp.a  libjingle.a libexpat.a libsrtp.a

参见“man ld”:

链接器将仅搜索存档 一次,在它所在的位置 在命令行中指定。如果 存档定义了一个符号,它是 在某些对象中未定义 出现在存档之前 命令行,链接器将包括 适当的文件(S)从 档案。但是,未定义的符号 在稍后出现的对象中 命令行不会导致链接器 再次搜索存档。

现在,我可以编译我的应用程序了。希望其他人会发现这很有用。

【讨论】:

另外,您可能想将 -frtti 添加到 CCFlags。为我工作。 @Randall: ld 有 --start-group 和 --end-group 选项,当两个库相互依赖时,解决这些问题的痛苦会稍微减轻一些。

以上是关于libjingle的XmppPump编译问题的主要内容,如果未能解决你的问题,请参考以下文章

编译libjingle的问题

为 Mac OS X 编译 libjingle/gtk+-2.0 的问题

添加新文件后的铬编译

WebRTC iOS平台的基本实现

问一个ANSYS Fluent的UDF编译问题

WebRTC 如何使用 libjingle?