dependancies getting old and compiling errors with Dev-C++

I am trying to compilie gserver-v2, taken from svn with Dev++ 4.9.9.2.
I have to make my own project file, and specify include directories.

First problem seen seems internal to the compiler
https://sourceforge.net/projects/dev-cpp/forums/forum/48211/topic/5354224/index/page/1

Second problem was a bunch of invalid conversion errors in bzip2 (bzip.c I think).
I removed those by downloading bzip2-1.0.6. (latest)

Then I began to have some redefinition errors with miniupnpc.
I tried to get rid of them by downloading latest version: 1.7.
But then, I now get some errors because there is now a new argument:
CUPNP.cpp:20 device_list = upnpDiscover(2000, 0, 0, 0);
60 C:\Documents and Settings\Paul\Desktop\graal_reborn\gserver-v2\trunk\dependencies\miniupnpc-1.7\miniupnpc.h too few arguments to function `UPNPDev* upnpDiscover(int, const char*, const char*, int, int, int*)’

CUPNP.cpp:64 int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.text(), port.text(), addr.text(), “Graal GServer”, “TCP”, 0);
124 C:\Documents and Settings\Paul\Desktop\graal_reborn\gserver-v2\trunk\dependencies\miniupnpc-1.7\upnpcommands.h too few arguments to function `int UPNP_AddPortMapping(const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*, const char*)’

And also, there seems to be some confusion between #include *<minimap/something> and #include
Example CUPNP.h have:
#include “miniupnpc/miniwget.h”
#include “miniupnpc/miniupnpc.h”
#include “miniupnpc/upnpcommands.h”
which I changed to "miniupnpc-1.7/miniwget.h … etc.

but I believe (may be this is stupid) it would be better if it was:
#include <miniwget.h>
#inculde <miniupnpc.h>
that way, I would only have to replace include directories for includes: from dependencies/miniupnpc-1.7 to dependencies/miniupnpc-1.8 when it will go out.

I’m pretty sure there’s preprocessor defines to enable and disable those features and likewise the dependency. You don’t have to build it with those features if you don’t want to, at least until you release a build for the community. The you should ensure they’re in place.

Well, finally the errors did came back, at least for bzip2.
Probably I tought the errors were gone, because the order of the files in the project made them appears later.
Dev-C++ seems to insist to treat conversion ‘errors’ as errors, rather than simply warnings.

But, yeah, I’ll have a closer look to see if bzip2, zlib, and UPNP are optional in compiling gserver-2.
But I am more thinking to get MinGW C++ module, for now.

I doubt bzip2 and zlib are. UPNP probably is, though.

Nope, upnp is required. I’ll update the dependencies. It may take me a little while, though. (@work)

hum… I downloaded Mingw C++ on MSYS and tried with the unmodified version:

Used: premake4 --no-boost gmake

$ make clean
Cleaning gserver2

Paul@PAUL-3E74F5E72E /c/Documents and Settings/Paul/Desktop/graal_reborn/gserver
-v2/trunk/build
$ make
==== Building gserver2 (debug) ====
Creating obj/Debug
CEncryption.cpp
CFileQueue.cpp
CFileSystem.cpp
CLog.cpp
CPluginManager.cpp
CSettings.cpp
CSocket.cpp
In file included from …/…/server/include/CString.h:6:0,
from …/…/server/include/CLog.h:6,
from …/…/server/src/CSocket.cpp:82:
c:\mingw\bin\…/lib/gcc/mingw32/4.6.2/include/c++/cstdio:166:11: error: ‘::snpri
ntf’ has not been declared
c:\mingw\bin\…/lib/gcc/mingw32/4.6.2/include/c++/cstdio:176:22: error: ‘__gnu_c
xx::snprintf’ has not been declared
…/…/server/src/CSocket.cpp: In member function ‘int CSocket::init(const char*,
const char*, int)’:
…/…/server/src/CSocket.cpp:309:47: error: ‘getaddrinfo’ was not declared in th
is scope
…/…/server/src/CSocket.cpp:313:47: error: ‘getaddrinfo’ was not declared in th
is scope
…/…/server/src/CSocket.cpp: In member function ‘const char* CSocket::getRemote
Ip()’:
…/…/server/src/CSocket.cpp:767:130: error: ‘getnameinfo’ was not declared in t
his scope
…/…/server/src/CSocket.cpp: In member function ‘const char* CSocket::getRemote
Port()’:
…/…/server/src/CSocket.cpp:780:128: error: ‘getnameinfo’ was not declared in t
his scope
…/…/server/src/CSocket.cpp: In member function ‘const char* CSocket::getLocalI
p()’:
…/…/server/src/CSocket.cpp:805:44: error: ‘getaddrinfo’ was not declared in th
is scope
…/…/server/src/CSocket.cpp:811:65: error: ‘getnameinfo’ was not declared in th
is scope
…/…/server/src/CSocket.cpp: In function ‘const char* errorMessage(int)’:
…/…/server/src/CSocket.cpp:947:33: error: ‘snprintf’ was not declared in this
scope
make[1]: *** [obj/Debug/CSocket.o] Error 1
make: *** [gserver2] Error 2

Paul@PAUL-3E74F5E72E /c/Documents and Settings/Paul/Desktop/graal_reborn/gserver
-v2/trunk/build

$ g++ --version
g++.exe (GCC) 4.6.2
Copyright © 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Now, I begin to tell myself that MAYBE Dev-C++ is using MinGW C++… and that problems that I have seen with Dev-C++ might stay with MinGW C++. Maybe this depends more on the version of the compiler than others.

Okay. I updated to the latest versions of zlib, bz2, and miniupnp. Sorry about the wait. Forgot over the Father’s Day weekend.

Let me know if you are still getting compiling errors. If not, I’m going to mark this as resolved.

Well, I still get those errors. Not took much time to investigate those yet.
Which make me think using Visual Studio would surely be easier.

Paul@PAUL-3E74F5E72E /c/graal_reborn/gserver-v2/trunk/build
$ premake4 --no-boost gmake
Building configurations…
Running action ‘gmake’…
Generating Makefile…
Generating projects/Makefile…
Done.

Paul@PAUL-3E74F5E72E /c/graal_reborn/gserver-v2/trunk/build
$ make
==== Building gserver2 (debug) ====
Creating obj/Debug
CEncryption.cpp
CFileQueue.cpp
CFileSystem.cpp
CLog.cpp
CPluginManager.cpp
CSettings.cpp
CSocket.cpp
In file included from …/…/server/include/CString.h:6:0,
from …/…/server/include/CLog.h:6,
from …/…/server/src/CSocket.cpp:82:
c:\mingw\bin\…/lib/gcc/mingw32/4.6.2/include/c++/cstdio:166:11: error: ‘::snprintf’ has not been declared
c:\mingw\bin\…/lib/gcc/mingw32/4.6.2/include/c++/cstdio:176:22: error: ‘__gnu_cxx::snprintf’ has not been declared
…/…/server/src/CSocket.cpp: In member function ‘int CSocket::init(const char*, const char*, int)’:
…/…/server/src/CSocket.cpp:309:47: error: ‘getaddrinfo’ was not declared in this scope
…/…/server/src/CSocket.cpp:313:47: error: ‘getaddrinfo’ was not declared in this scope
…/…/server/src/CSocket.cpp: In member function ‘const char* CSocket::getRemoteIp()’:
…/…/server/src/CSocket.cpp:767:130: error: ‘getnameinfo’ was not declared in this scope
…/…/server/src/CSocket.cpp: In member function ‘const char* CSocket::getRemotePort()’:
…/…/server/src/CSocket.cpp:780:128: error: ‘getnameinfo’ was not declared in this scope
…/…/server/src/CSocket.cpp: In member function ‘const char* CSocket::getLocalIp()’:
…/…/server/src/CSocket.cpp:805:44: error: ‘getaddrinfo’ was not declared in this scope
…/…/server/src/CSocket.cpp:811:65: error: ‘getnameinfo’ was not declared in this scope
…/…/server/src/CSocket.cpp: In function ‘const char* errorMessage(int)’:
…/…/server/src/CSocket.cpp:947:33: error: ‘snprintf’ was not declared in this scope
make[1]: *** [obj/Debug/CSocket.o] Error 1
make: *** [gserver2] Error 2

Paul@PAUL-3E74F5E72E /c/graal_reborn/gserver-v2/trunk/build
$

Okay. I believe I fixed the socket errors. Can you test something for me to see if it fixes the snprintf errors?
Go into the server/source folder and open up CSocket.cpp
At the top, you should see this:

#if defined(_WIN32) || defined(_WIN64)
	#ifdef _MSC_VER
		#define strncasecmp _strnicmp
		#define snprintf _snprintf
	#endif
#endif

Remove the #ifdef _MSC_VER line and one of the #endif lines.
See if that fixes your snprintf issues.

Indeed, the others than snprintf are gone! Good!
No, I don’t see this #ifdef _MSC_VER .
I am at revision 1149, which is latest.

I did read somewhere, that the error was linked to recursively #include, and that each file should #include what it needs, rather than #including a common file that #include the library files.

Here the current messages:
$ make
==== Building gserver2 (debug) ====
CSocket.cpp
In file included from …/…/server/include/CString.h:6:0,
from …/…/server/include/CLog.h:6,
from …/…/server/src/CSocket.cpp:71:
c:\mingw\bin\…/lib/gcc/mingw32/4.6.2/include/c++/cstdio:166:11: error: ‘::snprintf’ has not been declared
c:\mingw\bin\…/lib/gcc/mingw32/4.6.2/include/c++/cstdio:176:22: error: __gnu_cxx::snprintf’ has not been declared
…/…/server/src/CSocket.cpp: In function ‘const char* errorMessage(int)’:
…/…/server/src/CSocket.cpp:936:33: error: ‘snprintf’ was not declared in this scope
make[1]: *** [obj/Debug/CSocket.o] Error 1
make: *** [gserver2] Error 2

Paul@PAUL-3E74F5E72E /c/graal_reborn/gserver-v2/trunk/build
$

It’s there: http://code.google.com/p/gs2emu/source/browse/gserver-v2/trunk/server/src/CString.cpp#4

Ah! That’s CString.cpp, not CSocket.cpp.
Commenting out the #ifdef _MSC_VER did not change anything.

Paul@PAUL-3E74F5E72E /c/graal_reborn/gserver-v2/trunk/build
$ head …/server/src/CString.cpp
#include “IDebug.h”
#include “CString.h”

#if defined(_WIN32) || defined(_WIN64)
// ifdef _MSC_VER
#define strncasecmp _strnicmp
#define snprintf _snprintf
// endif
#endif

$ make clean
Cleaning gserver2

Paul@PAUL-3E74F5E72E /c/graal_reborn/gserver-v2/trunk/build
$ make
==== Building gserver2 (debug) ====
Creating obj/Debug
CEncryption.cpp
CFileQueue.cpp
CFileSystem.cpp
CLog.cpp
CPluginManager.cpp
CSettings.cpp
CSocket.cpp
In file included from …/…/server/include/CString.h:6:0,
from …/…/server/include/CLog.h:6,
from …/…/server/src/CSocket.cpp:71:
c:\mingw\bin\…/lib/gcc/mingw32/4.6.2/include/c++/cstdio:166:11: error: ‘::snprintf’ has not been declared
c:\mingw\bin\…/lib/gcc/mingw32/4.6.2/include/c++/cstdio:176:22: error: ‘__gnu_cxx::snprintf’ has not been declared
…/…/server/src/CSocket.cpp: In function ‘const char* errorMessage(int)’:
…/…/server/src/CSocket.cpp:936:33: error: ‘snprintf’ was not declared in this scope
make[1]: *** [obj/Debug/CSocket.o] Error 1
make: *** [gserver2] Error 2

Try adding this to the top of CString.cpp before the #include’s:

#define _GLIBCXX_USE_C99_DYNAMIC 1

With the following patch, I do not have compiling errors anymore.
But I do have linking errors, and one warning.

Index: trunk/server/include/CString.h

— trunk/server/include/CString.h (revision 1149)
+++ trunk/server/include/CString.h (working copy)
@@ -1,3 +1,4 @@
+#define _GLIBCXX_USE_C99_DYNAMIC 1
#ifndef CSTRING_H
#define CSTRING_H

Index: trunk/server/src/CSocket.cpp

— trunk/server/src/CSocket.cpp (revision 1149)
+++ trunk/server/src/CSocket.cpp (working copy)
@@ -933,7 +933,11 @@
default:
{
static char buf[32];

  •   	snprintf(buf, 32, "%d", error);
    
  •   	#ifdef __GNUC__
    
  •   	  __gnu_cxx::snprintf(buf, 32, "%d", error);
    
  •        #else
    
  •          snprintf(buf, 32, "%d", error);
    
  •        #endif              
      	return buf;
      }
    
    }

The warning is:
TPlayerNC.cpp
…/…/server/src/TPlayerNC.cpp: In member function ‘bool TPlayer::msgPLI_NC_QUERY(CString&)’:
…/…/server/src/TPlayerNC.cpp:368:141: warning: converting ‘false’ to pointer type for argument 4 of ‘void TServer::sendPacketToLevel(CString, TMap*, TLevel*,TPlayer*, bool) const’ [-Wconversion-null]

And the linker errors are:
Linking gserver2
Warning: resolving _getaddrinfo by linking to _getaddrinfo@16
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups
Warning: resolving _getnameinfo by linking to _getnameinfo@28
obj/Debug/connecthostport.o: In function connecthostport': c:\\graal_reborn\\gserver-v2\\trunk\\build\\projects/../../dependencies/miniupnpc/connecthostport.c:227: undefined reference tofreeaddrinfo’
obj/Debug/miniupnpc.o: In function upnpDiscover': c:\\graal_reborn\\gserver-v2\\trunk\\build\\projects/../../dependencies miniupnpc/min iupnpc.c:619: undefined reference tofreeaddrinfo’
collect2: ld returned 1 exit status
make[1]: *** […/…/bin/gserver2_d.exe] Error 1
make: *** [gserver2] Error 2

Trying to build on Linux

I installed Linux [Mageia-rc 2] on my box, and decided to try to compile unmodified gserver-v2 revision 1149.
As this come with g++ and gcc 4.6.3 with most development libraries [I thought boost were amongst them] I was not expecting problems.

First, I had to download premake4 for Linux at: http://industriousone.com/premake/download wich was a very short file with just the executable in a .tar.gz file.
Which I unziped in my /home/paul/graal_reborn/gserver-v2/trunk/build

Next, after ‘premake4 gmake’, I tried make:
==== Building gserver2 (debug) ====
Creating obj/Debug
CEncryption.cpp
TServer.cpp
…/…/server/src/TServer.cpp:3:29: fatal error: boost/thread.hpp: No such file or directory
compilation terminated.
make[1]: *** [obj/Debug/TServer.o] Error 1
make: *** [gserver2] Error 2

So I did ‘premake4 --no-boost gmake’ and got on make:
==== Building gserver2 (debug) ====
TServer.cpp
TLevelLink.cpp
CSocket.cpp
TLevelChest.cpp
CUPNP.cpp
TAccount.cpp
TLevelItem.cpp
IUtil.cpp
CLog.cpp
TLevelBaddy.cpp
TWeapon.cpp
TMap.cpp
TPlayerRC.cpp
TServerList.cpp
TLevelBoardChange.cpp
CTranslationManager.cpp
TPlayerLogin.cpp
CPluginManager.cpp
TLevelSign.cpp
TPlayerProps.cpp
CSettings.cpp
CWordFilter.cpp
TLevel.cpp
CString.cpp
main.cpp
TPlayerNC.cpp
…/…/server/src/TPlayerNC.cpp: In member function ‘bool TPlayer::msgPLI_NC_QUERY(CString&)’:
…/…/server/src/TPlayerNC.cpp:368:141: warning: converting ‘false’ to pointer type for argument 4 of ‘void TServer::sendPacketToLevel(CString, TMap*, TLevel*, TPlayer*, bool) const’ [-Wconversion-null]
md5.cpp
CFileSystem.cpp
TLevelHorse.cpp
CFileQueue.cpp
TPlayer.cpp
TNPC.cpp
gzlib.c
compress.c
crc32.c
trees.c
inflate.c
inffast.c
adler32.c
deflate.c
zutil.c
gzwrite.c
gzclose.c
uncompr.c
gzread.c
infback.c
inftrees.c
blocksort.c
bzlib.c
randtable.c
huffman.c
crctable.c
bz2compress.c
decompress.c
miniupnpc.c
…/…/dependencies/miniupnpc/miniupnpc.c: In function ‘upnpDiscover’:
…/…/dependencies/miniupnpc/miniupnpc.c:515:21: error: storage size of ‘reqn’ isn’t known
…/…/dependencies/miniupnpc/miniupnpc.c:516:29: error: invalid application of ‘sizeof’ to incomplete type ‘struct ip_mreqn’
…/…/dependencies/miniupnpc/miniupnpc.c:609:15: error: ‘NI_MAXHOST’ undeclared (first use in this function)
…/…/dependencies/miniupnpc/miniupnpc.c:609:15: note: each undeclared identifier is reported only once for each function it appears in
…/…/dependencies/miniupnpc/miniupnpc.c:609:33: error: ‘NI_MAXSERV’ undeclared (first use in this function)
make[1]: *** [obj/Debug/miniupnpc.o] Error 1
make: *** [gserver2] Error 2
[paul@localhost build]$

Not sure what to think for now.

Well, the boost error is because you don’t have the boost dev packages installed. The miniupnpc error seems to be new. I’ll try and fix that later on tonight if I remember.

Not sure, but I found these 2 links, that sugest a patch for Cygwin to solve storage size of ‘reqn’ is unknown:
http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=1130
found on https://trac.transmissionbt.com/ticket/4891

Not sure, but I begin to suspect that Linux need to be added to the disable HAS_IP_MREQN too, on the project which I believe is not:
according to https://github.com/miniupnp/miniupnp/commits/master/miniupnpc/miniupnpc.c

As suggested on http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=3012#3012
I added these two lines at the beginining of miniupnpc.c:
#define _BSD_SOURCE
#define _POSIX_C_SOURCE 1

Although I believe only the first is needed. It is also a bit weird to me to add on Linux.
With those the project compile and links fine.
But it does segfaults here in vfprintf:
(gdb) run
Starting program: /home/paul/graal_reborn/gserver-v2/trunk/bin/gserver2_d
[09:11 AM] Graal Reborn GServer version (null)
[09:11 AM] Programmed by Joey and Nalin.

[09:11 AM] :: Loading servers.txt… success

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff73019d8 in vfprintf () from /lib64/libc.so.6
(gdb) bt
#0 0x00007ffff73019d8 in vfprintf () from /lib64/libc.so.6
#1 0x000000000042bf58 in CLog::out (this=0x739c60, format=…)
at …/…/server/src/CLog.cpp:92
#2 0x0000000000480c20 in main (argc=1, argv=0x7fffffffdd68)
at …/…/server/src/main.cpp:106
(gdb) q

Ok, first rather than the ugly:
#define _GLIBCXX_USE_C99_DYNAMIC 1
to have snprintf be declared, the following is probably much more appropriate:
#define _BSD_SOURCE

This is explained here in man snprintf:
SYNOPSIS
#include <stdio.h>

   int printf(const char *format, ...);
   int fprintf(FILE *stream, const char *format, ...);
   int sprintf(char *str, const char *format, ...);
   int snprintf(char *str, size_t size, const char *format, ...);

   #include <stdarg.h>

   int vprintf(const char *format, va_list ap);
   int vfprintf(FILE *stream, const char *format, va_list ap);
   int vsprintf(char *str, const char *format, va_list ap);
   int vsnprintf(char *str, size_t size, const char *format, va_list ap);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

   snprintf(), vsnprintf():
       _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L;
       or cc -std=c99

So for snprintf to be declared, you need to define one of those, and I guess _BSD_SOURCE is fine… on Linux too!

Now, for the segfaults in vfprintf, I found the reason and a fix.
In short, CLog::out is using vprintf like functions at two place, one for the logging file, and the second time for the console.
But vprintf functions internaly call va_arg on each arguments, so the second time it was called for the console, the va_arg was at the end of the arguments.

Here is my fixed version:
void CLog::out(const CString format, …)
{
va_list s_format_v;

#ifndef NO_BOOST
boost::recursive_mutex::scoped_lock lock(*m_write);
#endif

// Assemble and print the timestamp.
char timestr[60];
time_t curtime = time(0);
strftime(timestr, sizeof(timestr), "%I:%M %p", localtime(&curtime));
printf("[%s] ", timestr);

// Log output to file.
if (true == enabled && 0 != file)
{
	// Save the timestamp to the file.
	strftime(timestr, sizeof(timestr), "%a %b %d %X %Y", localtime(&curtime));
	fprintf(file, "[%s] ", timestr);

	// Write the message to the file.
	va_start(s_format_v, format);
	vfprintf(file, format.text(), s_format_v);
	va_end(s_format_v);
	fflush(file);
}

// Display message.
va_start(s_format_v, format);
vprintf(format.text(), s_format_v);
va_end(s_format_v);

}

Now I finally get:
[09:17 AM] [default] Initializing player listen socket.
[09:17 AM] [default] Starting UPnP discovery thread.
Sending M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
MAN: “ssdp:discover”
MX: 2

Sending M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
ST: urn:schemas-upnp-org:service:WANIPConnection:1
MAN: “ssdp:discover”
MX: 2

Sending M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
ST: urn:schemas-upnp-org:service:WANPPPConnection:1
MAN: “ssdp:discover”
MX: 2

Sending M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
ST: upnp:rootdevice
MAN: “ssdp:discover”
MX: 2

[09:17 AM] [default] ** [UPnP] No devices found.
[09:17 AM] [default] Initializing serverlist socket.
[09:18 AM] [default] :: listserver - Connected.
[09:18 AM] [default] ** [WARNING] Socket returned 127.0.0.1 for its local ip! Not sending local ip to serverlist.
[09:18 AM] :: Program started

Well, as I am under 56k, and I think I kept the 127.0.0.1 in the configuration file, I guess this is Ok.