libgnutlsxx link problems
Boyan Kasarov
bkasarov at gmail.com
Mon Oct 5 15:42:32 CEST 2009
Hello,
I am having problems linking against libgnutlsxx.
The test program I used:
( NOTE It requires the helper functions from
http://www.gnu.org/software/gnutls/manual/gnutls.html#Helper-function-for-TCP-connections wrapped in extern "C" )
#include <iostream>
#include <stdexcept>
#include <gnutls/gnutls.h>
#include <gnutls/gnutlsxx.h>
#include <cstring> /* for strlen */
/* A very basic TLS client, with SRP authentication.
* written by Eduardo Villanueva Che, changed by Boyan Kasarov.
*/
#define MAX_BUF 1024
#define SA struct sockaddr
#define CAFILE "ca.pem"
#define USERNAME "username"
#define PASSWORD "password"
#define MSG "GET / HTTP/1.0\r\n\r\n"
extern "C"
{
int tcp_connect(void);
void tcp_close(int sd);
}
int main(void)
{
int sd = -1;
gnutls_global_init();
try
{
/* Allow connections to servers that have OpenPGP keys as well.
*/
gnutls::client_session session;
/* X509 stuff */
gnutls::certificate_credentials credentials;
/* SRP stuff */
gnutls::srp_client_credentials srp_credentials;
/* sets the trusted cas file
*/
credentials.set_x509_trust_file(CAFILE, GNUTLS_X509_FMT_PEM);
/* enter username and passowrd
*/
srp_credentials.set_credentials(USERNAME, PASSWORD);
/* put the x509 credentials to the current session
*/
session.set_credentials(credentials);
/* put the srp credentials to the current session
*/
session.set_credentials(srp_credentials);
/* Use default priorities */
session.set_priority ("NORMAL:+SRP:+SRP-RSA:+SRP-DSS:-DHE-RSA",
NULL);
/* connect to the peer
*/
sd = tcp_connect();
session.set_transport_ptr((gnutls_transport_ptr_t) sd);
/* Perform the TLS handshake
*/
int ret = session.handshake();
if (ret < 0)
{
// gnutls_perror(ret);
throw std::runtime_error("Handshake failed");
}
else
{
std::cout << "- Handshake was completed" << std::endl;
}
session.send(MSG, strlen(MSG));
char buffer[MAX_BUF + 1];
ret = session.recv(buffer, MAX_BUF);
if (ret == 0)
{
throw std::runtime_error("Peer has closed the TLS
connection");
}
else if (ret < 0)
{
throw std::runtime_error(gnutls_strerror(ret));
}
std::cout << "- Received " << ret << " bytes:" << std::endl;
std::cout.write(buffer, ret);
std::cout << std::endl;
session.bye(GNUTLS_SHUT_RDWR);
}
catch (gnutls::exception &ex)
{
std::cerr << "Exception caught: " << ex.what() << std::endl;
}
if (sd != -1)
tcp_close(sd);
gnutls_global_deinit();
return 0;
}
The problem I have is this:
derex at laptop ~/workspace/gnutls-test $ g++ ./test.cpp -lgnutlsxx
/tmp/cccjLXmv.o: In function `main':
test.cpp:(.text+0x15f): undefined reference to
`gnutls::srp_client_credentials::srp_client_credentials()'
test.cpp:(.text+0x188): undefined reference to
`gnutls::srp_client_credentials::set_credentials(char const*, char
const*)'
test.cpp:(.text+0x721): undefined reference to
`gnutls::srp_client_credentials::~srp_client_credentials()'
test.cpp:(.text+0x74b): undefined reference to
`gnutls::srp_client_credentials::~srp_client_credentials()'
/tmp/cccjLXmv.o:(.gcc_except_table+0xac): undefined reference to
`typeinfo for gnutls::exception'
collect2: ld returned 1 exit status
This errors appears if I use versions from 2.8.3 upto 2.9.4 (snapshot
20091004 from http://daily.josefsson.org/gnutls/ ) , I couldn't find
where gnutls source is , I didn't test versions before 2.8.3
The way I see it the link problem consists of 2 problems:
**** SRP related classes don't get build because of missing ENABLE_SRP
preprocessor flag ( even if srp is enabled from configure ). It can be
fixed by including config.h in lib/gnutlsxx.cpp, here is patch :
diff --git a/lib/gnutlsxx.cpp b/lib/gnutlsxx.cpp
index 83453f0..cdca728 100644
--- a/lib/gnutlsxx.cpp
+++ b/lib/gnutlsxx.cpp
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <gnutls/gnutlsxx.h>
namespace gnutls
**** The second problem is missing typeinfo for some classes, including
gnutls::exception in the example. I used this hack to fix it:
diff --git a/lib/libgnutlsxx.map b/lib/libgnutlsxx.map
index f049df4..62f6c12 100644
--- a/lib/libgnutlsxx.map
+++ b/lib/libgnutlsxx.map
@@ -24,7 +24,11 @@ GNUTLS_1_6
{
global:
extern "C++" {
- gnutls*;
+ gnutls::*;
};
+
+ # export typeinfo names and structures
+ _ZTI*;
+
local: *;
};
However I think some solution like explained at this url -
http://gcc.gnu.org/wiki/Visibility could be implemented for the C++
bindings.
Boyan Kasarov
More information about the Gnutls-devel
mailing list