Wednesday, 2 September 2009

getting around the "undefined reference to getaddrinfo" issue

>> main.cpp:(.text+0x18b): undefined reference to `getaddrinfo@16'
>> collect2: ld returned 1 exit status

After spending some time looking into winsock2 and *trying* to put together some code I've come across the message above when trying to compile the app.
After some trial and error I finally found out the reason why this message wouldn't go away. Apparently there are two things that have to be taken into account here.

1. Redefine your Windows version
According to msdn(1), some functions are only available to specific windows versions and therefore one must explicitly tell the compiler that the program is being compiled for that particular version. As it turns out, this is the case of the getaddrinfo() function.
By taking a quick look at the tcp/ip specific extensions for Winsock2 header file (ws2tcpip.h) it's easy to see this OS version dependency in the function declaration:

(...)
#if (_WIN32_WINNT >= 0x0501)
void WSAAPI freeaddrinfo (struct addrinfo*);
int WSAAPI getaddrinfo (const char*,const char*,const struct addrinfo*,struct addrinfo**);
int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,char*,DWORD,int);
#else
(...)

In order to tell the compiler your windows version you can set the constant called _WIN32_WINNT to the hex code of that version.
Since the getaddrinfo() is available to Windows XP onwards, it is sufficient to use that windows version code as the value of the constant mentioned above. Add the following line before the inclusion of the headers.

#define _WIN32_WINNT 0x0501


Bear in mind that since you're telling the compiler that you're using Windows XP here, you will not be able to make use of functions that are only available to versions prior to the one you have defined (Windows XP).


2. Link, Link, Link
Easy to forget, but you must remember to link the library that implements the getaddrinfo() to your application otherwise the compiler cannot resolve the function.
The library in question is the "Ws2_32.Lib" which, in my case, came along with the Windows SDK. Once you have the full path of the URL, you can link it by using the following command:

c:\apps\g++ main.cpp "c:\xxxxxxxxxx\xxx\" -o main.exe

NB: I am disregarding here any other library that you may have to link to your app.

By following the two steps above you should be able to run your app fine.
Just remember that these steps may vary depending on the version of your compiler and the libraries you've got installed.