2010-11-16 23 views
2

Je viens de commencer à coder un bot de chat gtalk en utilisant libjingle. J'ai un problème pour obtenir le compilateur pour trouver la classe XmppClient appelée par la classe XmppPump. Le XmppClient est fourni par libjingle dans le fichier talk/xmpp/xmppclient.h, mais pour une raison quelconque, cela ne fonctionne pas pour moi et cela m'a frustré récemment. J'espère que vous serez en mesure de m'aider! J'utilise libjingle-0.5.1 et ma version du compilateur g ++ est 4.4.5. Mon système d'exploitation est Ubuntu 10.10, 32 bits.Problème de compilation XmppPump de libjingle

Voilà comment je suis en train de compiler mon code:

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

Voici le message d'erreur:

 
../misc/libjingle-0.5.1/talk/build/dbg/lib/libxmpphelp.a(xmpppump.o): In function `XmppPump::XmppPump(XmppPumpNotify*)': 
xmpppump.cc:(.text._ZN8XmppPumpC2EP14XmppPumpNotify+0x6e): undefined reference to `buzz::XmppClient::XmppClient(talk_base::TaskParent*)' 
../misc/libjingle-0.5.1/talk/build/dbg/lib/libxmpphelp.a(xmpppump.o): In function `XmppPump::XmppPump(XmppPumpNotify*)': 
xmpppump.cc:(.text._ZN8XmppPumpC1EP14XmppPumpNotify+0x6e): undefined reference to `buzz::XmppClient::XmppClient(talk_base::TaskParent*)' 
../misc/libjingle-0.5.1/talk/build/dbg/lib/libxmpphelp.a(xmpppump.o): In function `XmppPump::DoLogin(buzz::XmppClientSettings const&, buzz::AsyncSocket*, buzz::PreXmppAuth*)': 
xmpppump.cc:(.text._ZN8XmppPump7DoLoginERKN4buzz18XmppClientSettingsEPNS0_11AsyncSocketEPNS0_11PreXmppAuthE+0xa9): undefined reference to `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): In function `XmppPump::DoDisconnect()': 
xmpppump.cc:(.text._ZN8XmppPump12DoDisconnectEv+0x25): undefined reference to `buzz::XmppClient::Disconnect()' 
../misc/libjingle-0.5.1/talk/build/dbg/lib/libxmpphelp.a(xmpppump.o): In function `XmppPump::SendStanza(buzz::XmlElement const*)': 
xmpppump.cc:(.text._ZN8XmppPump10SendStanzaEPKN4buzz10XmlElementE+0x2c): undefined reference to `buzz::XmppClient::SendStanza(buzz::XmlElement const*)' 
collect2: ld returned 1 exit status 
make: *** [../bin/gtalk_bot.bin] Error 1 

Et voici mon code:

#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; 
} 

Voici mon structure de répertoire. Il y a trois dossiers libjingle car j'expérimentais et j'essayais différentes choses pour voir si je pouvais résoudre le problème de compilation. Les dossiers libjingle sont inchangés sauf que les dossiers expat-2.0.1/et srtp/sont copiés dans le dossier libjingle/talk/third_party /. La structure libjingle-0.5.1/est à peu près la même chose que le tronc svn situé ici:

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

Sauf que mon dossier libjingle-0.5.1 est déjà compilé.

 
gtalk_bot$ ls * 
bin: 
log 

include: 

lib: 

misc: 
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 

obj: 
main.o XmppHandler.o 

src: 
main.cc main.o Makefile SConstruct XmppHandler.cc XmppHandler.h XmppSocket.cc XmppSocket.h 

test: 

est ici le répertoire de construction du libjingle:

 
gtalk_bot/misc/libjingle-0.5.1/talk/build/dbg$ ls * 
lib: 
libexpat.a libjingle.a libsrtp.a libxmpphelp.a 

obj: 
base call examples libexpat.a libjingle.a libsrtp.a libxmpphelp.a login p2p relayserver session stunserver third_party xmllite xmpp 

staging: 
call login relayserver stunserver 
+0

Il sera utile si vous pouvez nous fournir la structure de répertoire – Alam

+0

Bon, j'ai ajouté la structure de répertoire. J'espère que ça va aider. Assurez-vous de vérifier le lien du tronc SVN de libjingle pour vérifier la structure du répertoire et l'emplacement des fichiers d'en-tête et de source. – nikeairj

Répondre

1

Un grand merci à l'équipe libjingle pour résoudre mon problème. Apparemment, l'ordre de bibliothèque statique est important. Je devais réorganiser les bibliothèques à:

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

« man ld »:

L'éditeur de liens recherche d'une archive uniquement fois, à l'endroit où il est spécifié sur la ligne de commande. Si l'archive définit un symbole qui a été non défini dans un objet qui a comparu devant l'archive sur la ligne de commande , l'éditeur de liens comprendra le fichier approprié (s) de l'archive . Toutefois, un symbole non défini dans un objet apparaissant plus tard sur la ligne de commande n'entraînera pas la recherche à nouveau dans l'archive par l'éditeur de liens .

Maintenant, je suis capable de compiler mon application. J'espère que quelqu'un d'autre trouvera cela utile.

+0

En outre, vous pouvez ajouter -frtti à CCFlags. A travaillé pour moi. – steipete

+0

@Randall: ld possède les options --start-group et --end-group qui rendent la résolution des épreuves moins douloureuse lorsque deux bibliothèques dépendent l'une de l'autre. – qdii