From: Axel B. <th...@th...> - 2004-08-04 16:50:14
|
Hi List, I still try to compile gnuplot on windows with the ms .net vc compiler. and I have succeeded almost completely, the only thing remaining is a linker issue. But now to my proceeding: preliminary steps: 0. get gnuplot cvs :-) 1. get pdflib/zlib/libpng in precompiled versions and put them where they have to be 2. get libgd precompiled for windows 3. run the "mkvcbinaries.bat" (or so) script of gd to create libs usable with ms vc 4. copy the config.nt and makefile.nt in the src directory NOW COMES WHAT I DID MODIFY AND THE REASONS WHY 1. -- in gd.trm in ../term (from the source directory) apply the following diff file: ------------- --- term/gd.trm 2 Aug 2004 18:36:43 -0000 1.46 +++ term/gd.trm 4 Aug 2004 16:40:59 -0000 @@ -140,19 +140,24 @@ #include "gd.h" +#include "gdfonts.h" +#include "gdfontt.h" +#include "gdfontmb.h" +#include "gdfontl.h" +#include "gdfontg.h" static void PNG_PointX __PROTO((unsigned int, unsigned int)); static void PNG_PointPlus __PROTO((unsigned int, unsigned int)); static void PNG_Triangle(unsigned int x, unsigned int y, int direction, - void (*draw_func)(gdImagePtr, gdPointPtr, int, int)); + void (__stdcall *draw_func)(gdImagePtr, gdPointPtr, int, int)); static void PNG_Diamond(unsigned int x, unsigned int y, - void (*draw_func)(gdImagePtr, gdPointPtr, int, int)); + void (__stdcall *draw_func)(gdImagePtr, gdPointPtr, int, int)); -extern gdFontPtr gdFontSmall; /* 6x12 */ -extern gdFontPtr gdFontLarge; /* 8x16 */ -extern gdFontPtr gdFontMediumBold; /* 7x13 */ -extern gdFontPtr gdFontGiant; /* 9x15 */ -extern gdFontPtr gdFontTiny; /* 5x8 */ +//extern gdFontPtr gdFontGetSmall(); /* 6x12 */ +//extern gdFontPtr gdFontGetLarge(); /* 8x16 */ +//extern gdFontPtr gdFontGetMediumBold(); /* 7x13 */ +//extern gdFontPtr gdFontGetGiant(); /* 9x15 */ +//extern gdFontPtr gdFontGetTiny(); /* 5x8 */ #define GREG_XMAX 640 @@ -165,7 +170,7 @@ static int PNG_ps = 3; /* This will be the default font */ -# define gdfont gdFontMediumBold +# define gdfont gdFontGetMediumBold() # define PNG_VCHAR 13 # define PNG_HCHAR 7 @@ -399,7 +404,7 @@ PNG_Triangle( unsigned int x, unsigned int y, int direction, - void (*draw_func)(gdImagePtr, gdPointPtr, int, int)) + void (__stdcall *draw_func)(gdImagePtr, gdPointPtr, int, int)) { int delta = (int)((1.33 * (double)PNG_ps) + 0.5); int delta_ = (int)((0.67 * (double)PNG_ps) + 0.5); @@ -419,7 +424,7 @@ static void PNG_Diamond( unsigned int x, unsigned int y, - void (*draw_func)(gdImagePtr, gdPointPtr, int, int)) + void (__stdcall *draw_func)(gdImagePtr, gdPointPtr, int, int)) { gdPoint points[5]; points[0].x = x; @@ -505,35 +510,35 @@ ; /* nothing to do */ #endif UNSET_TTF_FONT; - png_state.default_font=gdFontTiny; + png_state.default_font=gdFontGetTiny(); term->v_char = png_state.default_font->h; term->h_char = png_state.default_font->w; ++c_token; break; case PNG_SMALL: UNSET_TTF_FONT; - png_state.default_font = gdFontSmall; + png_state.default_font = gdFontGetSmall(); term->v_char = png_state.default_font->h; term->h_char = png_state.default_font->w; ++c_token; break; case PNG_MEDIUM: UNSET_TTF_FONT; - png_state.default_font = gdFontMediumBold; + png_state.default_font = gdFontGetMediumBold(); term->v_char = png_state.default_font->h; term->h_char = png_state.default_font->w; ++c_token; break; case PNG_LARGE: UNSET_TTF_FONT; - png_state.default_font = gdFontLarge; + png_state.default_font = gdFontGetLarge(); term->v_char = png_state.default_font->h; term->h_char = png_state.default_font->w; ++c_token; break; case PNG_GIANT: UNSET_TTF_FONT; - png_state.default_font=gdFontGiant; + png_state.default_font=gdFontGetGiant(); term->v_char = png_state.default_font->h; term->h_char = png_state.default_font->w; ++c_token; @@ -1351,15 +1356,15 @@ sscanf (&(fontname[sep+1]),"%d",&size); if (!strcmp(name,"small")) - font = gdFontSmall; + font = gdFontGetSmall(); else if (!strcmp(name,"medium")) - font = gdFontMediumBold; + font = gdFontGetMediumBold(); else if (!strcmp(name,"large")) - font = gdFontLarge; + font = gdFontGetLarge(); else if (!strcmp(name,"giant")) - font = gdFontGiant; + font = gdFontGetGiant(); else if (!strcmp(name,"tiny")) - font = gdFontTiny; + font = gdFontGetTiny(); else if (*name) { /* New ttf font */ strncpy(png_state.ttffont, name, sizeof(png_state.ttffont)); ------------- what it does? several things. first: notice the line with the function pointer "draw_func"? the msvc compiler (every windows compiler??) uses by default the __cdecl calling convention, BUT the functions in gd.h are defined __declspec(dllimport) __stdcall, which is not pointer compatible. so we have to change the function pointer to be (__stdcall * draw_func) instead of void (* draw_func). (naming conventions do affect naming of the compiled functions in the lib/binary/dll, and sometimes even value passing etc., so this is not trivial. second: I replaced every reference to gdFontTiny/Small/MediumBold/Large/Giant with gdFontGet<size>(), because the lib is not really good in exporting the data pointers, and compilation breaks at that point. The references of the data pointers I just got rid of. and - which is very important, and I don't know why gnuplot does not do this - the gdFontX as well as the gdFontGetX functions are all in their own include header file, which gnuplot does not include - whyever. I included them by hand (otherwise - you might guess - compilation breaks :-) 2. -- in gd.h I changed line 18 (ver 2.0.28 I think) from being #define BGD_DECLARE(rt) __declspec(dllimport) rt _stdcall to #define BGD_DECLARE(rt) rt _stdcall this also affects naming conventions: the __imp__functions are generated by __declspec(dllexport) and are usually found in dll's. gd wants them defined like that, but the *LIB* created by the tools used here does only export the functions without the __imp__, thus linking breaks if we keep that, so kick it. (check with "objdump /exports bgd.lib" if you like :-) 3. -- add in config.h the lines #define HAVE_GD_PNG #define HAVE_GD_GIF #define HAVE_GD_JPEG to use GD :-). Adjust the makefile to find the paths to the inclues and the lib. I assume you know how to do that ;-) 4. -- now a "nmake" in the source directory should do the trick. BUT the application will crash if you try to use the gd functions - why? because the precompiled version of libgd *HAS TO BE LINKED AGAINST MULTITHREADED DLL LIBS* of ms. and the makefile links against /MT (multithreaded libs, without dll). now change the CFLAGS line and replace /MT with /MD. now I have a problem: with /MT it compiles, with /MD it does not. I get a "function redefinition" in io.h, but no previous declared prototype, whyever. so if anyone has found this helpful or has a solution to this - youre welcome to write some feedback :-)) greetings, axel. p.s.: IF ANYONE KNOWS A BETTER / FASTER / EASIER METHOD TO COMPILE THAT WITH WINDOWS ----- TEEEEELLLL MEEEEEEEEE!!!!! ... that had to be said :-) p.p.s.: if I succeed in doing this I am willing to put up the precompiled - and patched - version of gnuplot on my webspace for everyone to download, if someone is interested. |