]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - win/configure.cpp
Experimental WSAPoll (thanks for not just using poll(), guys) support for Windows...
[user/henk/code/inspircd.git] / win / configure.cpp
1 /*         +------------------------------------+
2  *         | Inspire Internet Relay Chat Daemon |
3  *         +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *                      the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #define _CRT_SECURE_NO_DEPRECATE
15
16 #define CONFIGURE_BUILD
17 #define WIN32_LEAN_AND_MEAN
18 #include <windows.h>
19 #include <stdio.h>
20 #include <string>
21 #include <time.h>
22 #include "inspircd_win32wrapper.h"
23 #include "colours.h"
24
25 using namespace std;
26 void Run();
27 void Banner();
28 void WriteCompileModules();
29 void WriteCompileCommands();
30 void Rebase();
31 void CopyExtras();
32
33 /* detects if we are running windows xp or higher (5.1) */
34 bool iswinxp()
35 {
36         OSVERSIONINFO vi;
37         vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
38         GetVersionEx(&vi);
39         if(vi.dwMajorVersion >= 5)
40                 return true;
41         
42         return false;
43 }
44
45 int get_int_option(const char * text, int def)
46 {
47         static char buffer[500];
48         int ret;
49         printf_c("%s\n[\033[1;32m%u\033[0m] -> ", text, def);
50         fgets(buffer, 500, stdin);
51         if(sscanf(buffer, "%u", &ret) != 1)
52                 ret = def;
53
54         printf("\n");
55         return ret;
56 }
57
58 bool get_bool_option(const char * text, bool def)
59 {
60         static char buffer[500];
61         char ret[100];
62         printf_c("%s [\033[1;32m%c\033[0m] -> ", text, def ? 'y' : 'n');
63         fgets(buffer, 500, stdin);
64         if(sscanf(buffer, "%s", ret) != 1)
65                 strcpy(ret, def ? "y" : "n");
66
67         printf("\n");
68         return !strncmp(ret, "y", 1);
69 }
70
71 void get_string_option(const char * text, char * def, char * buf)
72 {
73         static char buffer[500];
74         if (*def)
75                 printf_c("%s\n[\033[1;32m%s\033[0m] -> ", text, def);
76         else
77                 printf_c("%s\n[] -> ", text);
78         fgets(buffer, 500, stdin);
79         if(sscanf(buffer, "%s", buf) != 1)
80                 strcpy(buf, def);
81
82         printf("\n");
83 }
84
85 // escapes a string for use in a c++ file
86 bool escape_string(char * str, size_t size)
87 {
88         size_t len = strlen(str);
89         char * d_str = (char*)malloc(len * 2);
90         
91         size_t i = 0;
92         size_t j = 0;
93
94         for(; i < len; ++i)
95         {
96                 if(str[i] == '\\')
97                 {
98                         d_str[j++] = '\\';
99                         d_str[j++] = '\\';
100                 }
101                 else
102                 {
103                         d_str[j++] = str[i];
104                 }
105         }
106
107         d_str[j++] = 0;
108
109         if(j > size)
110         {
111                 free(d_str);
112                 return false;
113         }
114
115         strcpy(str, d_str);
116         free(d_str);
117         return true;
118 }
119
120 /* gets the svn revision */
121 int get_svn_revision(char * buffer, size_t len)
122 {
123         /* again.. I am lazy :p cbf to pipe output of svn info to us, so i'll just read the file */
124         /*
125         8
126
127         dir
128         7033
129         */
130         char buf[1000];
131         int rev = 0;
132         
133         FILE * f = fopen("..\\.svn\\entries", "r");
134         if (f)
135         {
136                 for (int q = 0; q < 4; ++q)
137                         fgets(buf, 1000, f);
138
139                 rev = atoi(buf);
140                 sprintf(buffer, "%u", rev);
141                 fclose(f);
142         }
143         
144         return rev;
145 }
146
147 int __stdcall WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN int nShowCmd )
148 {
149         if (!strcmp(lpCmdLine, "/rebase"))
150         {
151                 Rebase();
152                 return 0;
153         }
154         FILE * j = fopen("inspircd_config.h", "r");
155         if (j)
156         {
157                 if (MessageBox(0, "inspircd_config.h already exists. Remove it and build from clean?", "Configure program", MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2) != IDYES)
158                 {
159                         fclose(j);
160                         exit(0);
161                 }
162         }
163
164         AllocConsole();
165
166         // pipe standard handles to this console
167         freopen("CONIN$", "r", stdin);
168         freopen("CONOUT$", "w", stdout);
169         freopen("CONOUT$", "w", stderr);
170
171         Banner();
172         Run();
173         FreeConsole();
174         return 0;
175 }
176
177 void Banner()
178 {
179         printf_c("\nWelcome to the \033[1mInspIRCd\033[0m Configuration program! (\033[1minteractive mode\033[0m)\n"
180                          "\033[1mPackage maintainers: Type ./configure --help for non-interactive help\033[0m\n\n");
181         printf_c("*** If you are unsure of any of these values, leave it blank for      ***\n"
182                          "*** standard settings that will work, and your server will run          ***\n"
183                          "*** using them. Please consult your IRC network admin if in doubt.  ***\n\n"
184                          "Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter\n"
185                          "a new value. Please note: You will \033[1mHAVE\033[0m to read the docs\n"
186                          "dir, otherwise you won't have a config file!\n\n");
187
188 }
189
190 void Run()
191 {
192         bool use_iocp = false;
193         bool support_ip6links = true;
194         bool use_openssl = false;
195         bool ipv6 = true;
196         char mod_path[MAX_PATH];
197         char config_file[MAX_PATH];
198         char library_dir[MAX_PATH];
199         char base_path[MAX_PATH];
200         char bin_dir[MAX_PATH];
201         char revision_text[MAX_PATH];
202         char openssl_inc_path[MAX_PATH];
203         char openssl_lib_path[MAX_PATH];
204         int revision = get_svn_revision(revision_text, MAX_PATH);
205         char version[514];
206
207         // grab version
208         FILE * fI = fopen("..\\src\\version.sh", "r");
209         if(fI)
210         {
211                 fgets(version, 514, fI);
212                 fgets(version, 514, fI);
213                 char * p2 = version;
214                 while(*p2 != '\"')
215                         ++p2;
216                 ++p2;
217                 strcpy(version, p2);
218                 p2 = version;
219                 while(*p2 != '\"')
220                         ++p2;
221                 *p2 = 0;
222                 fclose(fI);
223         }
224         else
225                 strcpy(version, "InspIRCD-Unknown");
226 #ifdef WIN64
227         printf_c("Your operating system is: \033[1;32mwindows_x64 \033[0m\n");
228 #else
229         printf_c("Your operating system is: \033[1;32mwindows_x32 \033[0m\n");
230 #endif
231         printf_c("InspIRCd revision ID: \033[1;32m%s \033[0m\n\n", revision ? revision_text : "(Non-SVN build)");
232
233         // detect windows
234         if(iswinxp())
235         {
236                 printf_c("You are running Windows 2000 or above, and IOCP support is most likely available.\n"
237                                  "Thisis much more efficent but is currently EXPERIMENTAL and UNSUPPORTED.\n"
238                                  "If you are unsure, answer no.\n\n");
239
240                 use_iocp = get_bool_option("Do you want to use the IOCP implementation?", false);
241         }
242
243         ipv6 = get_bool_option("Do you want to enable IPv6?", false);
244
245         if (!ipv6)
246                 support_ip6links = get_bool_option("\nYou have chosen to build an \033[1;32mIPV4-only\033[0m server.\nWould you like to enable support for linking to IPV6-enabled InspIRCd servers?\nIf you are using a recent operating system and are unsure, answer yes.\nIf you answer 'no' here, your InspIRCd server will be unable\nto parse IPV6 addresses (e.g. for CIDR bans)", true);
247         else
248                 support_ip6links = true;
249         
250         printf_c("\033[1mAll paths are relative to the binary directory.\033[0m\n");
251         get_string_option("In what directory do you wish to install the InspIRCd base?", "..", base_path);
252         get_string_option("In what directory are the configuration files?", "../conf", config_file);
253         get_string_option("In what directory are the modules to be compiled to?", "../modules", mod_path);
254         get_string_option("In what directory is the IRCd binary to be placed?", ".", bin_dir);
255         get_string_option("In what directory are the IRCd libraries to be placed?", "../lib", library_dir);
256
257         // NOTE: this may seem hackish (generating a batch build script), but it assures the user knows
258         // what they're doing, and we don't have to mess with copying files and changing around modules.mak
259         // for the extra libraries. --fez
260         // in case it exists, remove old m_ssl_openssl.cpp
261         remove("..\\src\\modules\\m_ssl_openssl.cpp");
262         printf_c("You can compile InspIRCd modules that add OpenSSL or GnuTLS support for SSL functionality.\n"
263                 "To do so you will need the appropriate link libraries and header files on your system.\n");
264         use_openssl = get_bool_option("Would you like to compile the IRCd with OpenSSL support?", false);
265         if (use_openssl)
266         {
267                 get_string_option("Please enter the full path to your OpenSSL include directory\n"
268                         "(e.g., C:\\openssl\\include, but NOT the openssl subdirectory under include\\)\n"
269                         "(also, path should not end in '\\')",
270                         "C:\\openssl\\include", openssl_inc_path);
271
272                 // NOTE: if inspircd ever changes so that it compiles with /MT instead of the /MTd switch, then
273                 // the dependency on libeay32mtd.lib and ssleay32mtd.lib will change to just libeay32.lib and
274                 // ssleay32.lib. --fez
275
276                 get_string_option("Please enter the full path to your OpenSSL library directory\n"
277                         "(e.g., C:\\openssl\\lib, which should contain libeay32mtd.lib and ssleay32mtd.lib)",
278                         "C:\\openssl\\lib", openssl_lib_path);
279
280                 // write batch file
281                 FILE *fp = fopen("compile_openssl.bat", "w");
282                 fprintf(fp, "@echo off\n");
283                 fprintf(fp, "echo This batch script compiles m_ssl_openssl for InspIRCd.\n");
284                 fprintf(fp, "echo NOTE: this batch file should be invoked from the Visual Studio Command Prompt (vsvars32.bat)\n");
285                 fprintf(fp, "set OPENSSL_INC_PATH=\"%s\"\n", openssl_inc_path);
286                 fprintf(fp, "set OPENSSL_LIB_PATH=\"%s\"\n", openssl_lib_path);
287                 fprintf(fp, "set COMPILE=cl /nologo -Dssize_t=long /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/modules\" /I \"../../win\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /EHsc /Gm /MD /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W2 /Wp64 /Zi /TP /I %%OPENSSL_INC_PATH%% m_ssl_openssl.cpp ..\\..\\win\\inspircd_memory_functions.cpp %%OPENSSL_INC_PATH%%\\openssl\\applink.c /link /LIBPATH:%%OPENSSL_LIB_PATH%% ..\\..\\bin\\release\\bin\\inspircd.lib ws2_32.lib /OUT:\"..\\..\\bin\\release\\modules\\m_ssl_openssl.so\" /PDB:\"..\\..\\bin\\release\\modules\\m_ssl_openssl.pdb\" /IMPLIB:\"..\\..\\bin\\release\\modules\\m_ssl_openssl.lib\"\n");
288                 fprintf(fp, "cd ..\\src\\modules\n");
289                 fprintf(fp, "copy extra\\m_ssl_openssl.cpp .\n");
290                 fprintf(fp, "echo \t%%COMPILE%%\n");
291                 fprintf(fp, "%%COMPILE%%\n");
292                 fprintf(fp, "cd ..\\..\\win\n");
293                 fprintf(fp, "echo done... now check for errors.\n");
294                 fclose(fp);
295
296                 printf_c("\033[1;32m!!!NOTICE!!! The file 'compile_openssl.bat' has been written to your 'win' directory.  Launch it\n"
297                         "!!! from the Visual Studio Command Prompt !!! to compile the m_ssl_openssl module.\n"
298                         "Wait until after compiling inspircd to run it.\n"
299                         "Also, ssleay32.dll and libeay32.dll will be required for the IRCd to run.\033[0m\n");
300         }
301
302         printf_c("\n\033[1;32mPre-build configuration is complete!\n\n");       sc(TNORMAL);
303
304         CopyExtras();
305
306         // dump all the options back out
307         printf_c("\033[0mBase install path:\033[1;32m        %s\n", base_path);
308         printf_c("\033[0mConfig path:\033[1;32m              %s\n", config_file);
309         printf_c("\033[0mModule path:\033[1;32m              %s\n", mod_path);
310         printf_c("\033[0mLibrary path:\033[1;32m             %s\n", library_dir);
311         printf_c("\033[0mSocket Engine:\033[1;32m            %s\n", use_iocp ? "iocp" : "select");
312
313         printf("\n"); sc(TNORMAL);
314         if(get_bool_option("Are these settings correct?", true) == false)
315         {
316                 Run();
317                 return;
318         }
319         printf("\n");
320
321         // escape the pathes
322         escape_string(config_file, MAX_PATH);
323         escape_string(mod_path, MAX_PATH);
324         escape_string(library_dir, MAX_PATH);
325
326         printf("\nWriting inspircd_config.h...");
327         FILE * f = fopen("inspircd_config.h", "w");
328         fprintf(f, "/* Auto generated by configure, do not modify! */\n");
329         fprintf(f, "#ifndef __CONFIGURATION_AUTO__\n");
330         fprintf(f, "#define __CONFIGURATION_AUTO__\n\n");
331         if(use_iocp)
332                 fprintf(f, "#define CONFIG_USE_IOCP 1\n\n");
333         if (ipv6)
334                 fprintf(f, "#define IPV6 1\n\n");
335
336         fprintf(f, "#define CONFIG_FILE \"%s/inspircd.conf\"\n", config_file);
337         fprintf(f, "#define MOD_PATH \"%s\"\n", mod_path);
338         fprintf(f, "#define SOMAXCONN_S \"128\"\n");
339         fprintf(f, "#define LIBRARYDIR \"%s\"\n", library_dir);
340         fprintf(f, "#define VERSION \"%s\"\n", version);
341         fprintf(f, "#define REVISION \"%s\"\n", revision_text);
342         if(support_ip6links)
343                 fprintf(f, "#define SUPPORT_IP6LINKS 1\n");
344
345         OSVERSIONINFO vi;
346         vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
347         GetVersionEx(&vi);
348 #ifdef WIN64
349         fprintf(f, "#define SYSTEM \"Windows_x64 %u.%u.%u %s\"\n", vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, vi.szCSDVersion);
350 #else
351         fprintf(f, "#define SYSTEM \"Windows_x32 %u.%u.%u %s\"\n", vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, vi.szCSDVersion);
352 #endif
353         fprintf(f, "#define MAXBUF 514\n");
354
355         fprintf(f, "\n#include \"inspircd_win32wrapper.h\"");
356         fprintf(f, "\n#include \"inspircd_namedpipe.h\"");
357         fprintf(f, "\n#include \"threadengines/threadengine_win32.h\"\n\n");
358         fprintf(f, "#endif\n\n");
359         fclose(f);
360
361         sc(TGREEN); printf(" done\n"); sc(TNORMAL);
362         printf("Writing inspircd_se_config.h...");
363
364         f = fopen("inspircd_se_config.h", "w");
365         fprintf(f, "/* Auto generated by configure, do not modify or commit to svn! */\n");
366         fprintf(f, "#ifndef __CONFIGURATION_SOCKETENGINE__\n");
367         fprintf(f, "#define __CONFIGURATION_SOCKETENGINE__\n\n");
368         fprintf(f, "#include \"socketengines/socketengine_%s.h\"\n\n", use_iocp ? "iocp" : "select");
369         fprintf(f, "#endif\n\n");
370         fclose(f);
371
372         sc(TGREEN); printf(" done\n"); sc(TNORMAL);
373         printf("Writing command and module compilation scripts...");
374         WriteCompileCommands();
375         WriteCompileModules();
376         sc(TGREEN); printf(" done\n"); sc(TNORMAL);
377
378         printf("\nconfigure is done.. exiting!\n");
379 }
380
381 /* Keeps files from modules/extra up to date if theyre copied into modules/ */
382 void CopyExtras()
383 {
384         char dest[65535];
385         char src[65535];
386
387         printf("\nUpdating extra modules in src/modules...\n");
388
389         WIN32_FIND_DATA fd;
390         HANDLE fh = FindFirstFile("..\\src\\modules\\extra\\*.*", &fd);
391
392         if(fh == INVALID_HANDLE_VALUE)
393                 return;
394
395         do
396         {
397                 strcpy(dest, "..\\src\\modules\\");
398                 strcat(dest, fd.cFileName);
399                 strcpy(src, "..\\src\\modules\\extra\\");
400                 strcat(src, fd.cFileName);
401                 FILE* x = fopen(dest, "r");
402                 if (x)
403                 {
404                         fclose(x);
405                         CopyFile(src, dest, false);
406                         sc(TGREEN); printf("    %s", fd.cFileName); sc(TNORMAL);
407                         printf("...\n");
408                 }
409         }
410         while (FindNextFile(fh, &fd));
411
412         FindClose(fh);
413
414         printf("\n\n");
415 }
416
417
418 void Rebase()
419 {
420         char dest[65535];
421         char command[65535];
422
423         *dest = 0;
424
425         WIN32_FIND_DATA fd;
426 #ifdef _DEBUG
427         HANDLE fh = FindFirstFile("..\\bin\\debug\\lib\\*.so", &fd);
428 #else
429         HANDLE fh = FindFirstFile("..\\bin\\release\\lib\\*.so", &fd);
430 #endif
431         if(fh == INVALID_HANDLE_VALUE)
432                 return;
433
434         do
435         {
436 #ifdef _DEBUG
437                 strcat(dest, " ..\\bin\\debug\\lib\\");
438 #else
439                 strcat(dest, " ..\\bin\\release\\lib\\");
440 #endif
441                 strcat(dest, fd.cFileName);
442         }
443         while (FindNextFile(fh, &fd));
444
445         FindClose(fh);
446
447         sprintf(command, "rebase.exe -v -b 10000000 -c baseaddr_commands.txt %s", dest);
448         printf("%s\n", command);
449         system(command);
450
451 #ifdef _DEBUG
452         fh = FindFirstFile("..\\bin\\debug\\modules\\*.so", &fd);
453 #else
454         fh = FindFirstFile("..\\bin\\release\\modules\\*.so", &fd);
455 #endif
456         if(fh == INVALID_HANDLE_VALUE)
457                 return;
458
459         *dest = 0;
460
461         do
462         {
463 #ifdef _DEBUG
464                 strcat(dest, " ..\\bin\\debug\\modules\\");
465 #else
466                 strcat(dest, " ..\\bin\\release\\modules\\");
467 #endif
468                 strcat(dest, fd.cFileName);
469         }
470         while (FindNextFile(fh, &fd));
471
472         sprintf(command, "rebase.exe -v -b 11000000 -c baseaddr_modules.txt %s", dest);
473         printf("%s\n", command);
474         system(command);
475
476         FindClose(fh);
477
478 }
479
480 void WriteCompileCommands()
481 {
482         char commands[300][100];
483         int command_count = 0;
484         printf("\n  Finding Command Sources...\n");
485         WIN32_FIND_DATA fd;
486         HANDLE fh = FindFirstFile("..\\src\\commands\\cmd_*.cpp", &fd);
487         if(fh == INVALID_HANDLE_VALUE)
488                 printf_c("\033[1;32m  No command sources could be found! This \033[1m*could*\033[1;32m be a bad thing.. :P\033[0m");
489         else
490         {
491                 sc(TGREEN);
492                 do 
493                 {
494                         strcpy(commands[command_count], fd.cFileName);
495                         commands[command_count][strlen(fd.cFileName) - 4] = 0;
496                         printf("        %s\n", commands[command_count]);
497                         ++command_count;
498                 } while(FindNextFile(fh, &fd));
499                 sc(TNORMAL);
500         }
501         
502         // Write our spiffy new makefile :D
503         // I am such a lazy fucker :P
504         FILE * f = fopen("..\\src\\commands\\commands.mak", "w");
505
506         time_t t = time(NULL);
507         fprintf(f, "# Generated at %s\n", ctime(&t));
508         fprintf(f, "all: makedir ");
509
510         // dump modules.. first time :)
511         for(int i = 0; i < command_count; ++i)
512                 fprintf(f, "%s.so ", commands[i]);
513
514         fprintf(f, "\n.cpp.obj:\n");
515 #ifdef WIN64
516         // /MACHINE:X64
517         #ifdef _DEBUG
518                 fprintf(f, "  cl /nologo /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/commands\" /I \"../../win\" /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /Gm /EHsc /Gm /RTC1 /MDd /Fo\"Debug/\" /Fd\"Debug/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\debug_x64\\bin\\inspircd.lib /OUT:\"..\\..\\bin\\debug_x64\\lib\\$*.so\" /PDB:\"..\\..\\bin\\debug_x64\\lib\\$*.pdb\" /MACHINE:X64 /IMPLIB:\"..\\..\\bin\\debug_x64\\lib\\$*.lib\"\n\n");
519                 CreateDirectory("..\\src\\debug", NULL);
520                 CreateDirectory("..\\bin\\debug\\bin", NULL);
521                 CreateDirectory("..\\bin\\debug\\lib", NULL);
522                 CreateDirectory("..\\bin\\debug\\modules", NULL);
523         #else
524                 fprintf(f, "  cl /nologo /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/commands\" /I \"../../win\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /EHsc /Gm /GL /MD /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\release_x64\\bin\\inspircd.lib /OUT:\"..\\..\\bin\\release_x64\\lib\\$*.so\" /PDB:\"..\\..\\bin\\release_x64\\lib\\$*.pdb\" /MACHINE:X64 /IMPLIB:\"..\\..\\bin\\release_x64\\lib\\$*.lib\"\n\n");
525                 CreateDirectory("..\\src\\release", NULL);
526                 CreateDirectory("..\\bin\\release\\bin", NULL);
527                 CreateDirectory("..\\bin\\release\\lib", NULL);
528                 CreateDirectory("..\\bin\\release\\modules", NULL);
529         #endif
530 #else
531         #ifdef _DEBUG
532                 fprintf(f, "  cl /nologo /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/commands\" /I \"../../win\" /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /Gm /EHsc /Gm /RTC1 /MDd /Fo\"Debug/\" /Fd\"Debug/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\debug\\bin\\inspircd.lib /OUT:\"..\\..\\bin\\debug\\lib\\$*.so\" /PDB:\"..\\..\\bin\\debug\\lib\\$*.pdb\" /IMPLIB:\"..\\..\\bin\\debug\\lib\\$*.lib\"\n\n");
533                 CreateDirectory("..\\src\\debug", NULL);
534                 CreateDirectory("..\\bin\\debug\\bin", NULL);
535                 CreateDirectory("..\\bin\\debug\\lib", NULL);
536                 CreateDirectory("..\\bin\\debug\\modules", NULL);
537         #else
538                 fprintf(f, "  cl /nologo /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/commands\" /I \"../../win\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /EHsc /Gm /GL /MD /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\release\\bin\\inspircd.lib /OUT:\"..\\..\\bin\\release\\lib\\$*.so\" /PDB:\"..\\..\\bin\\release\\lib\\$*.pdb\" /IMPLIB:\"..\\..\\bin\\release\\lib\\$*.lib\"\n\n");
539                 CreateDirectory("..\\src\\release", NULL);
540                 CreateDirectory("..\\bin\\release\\bin", NULL);
541                 CreateDirectory("..\\bin\\release\\lib", NULL);
542                 CreateDirectory("..\\bin\\release\\modules", NULL);
543         #endif
544 #endif
545
546 #ifdef _DEBUG
547         fprintf(f, "makedir:\n  if not exist debug mkdir debug\n  if not exist ..\\..\\bin\\debug\\lib mkdir ..\\..\\bin\\debug\\lib\n\n");
548 #else
549         fprintf(f, "makedir:\n  if not exist release mkdir release\n  if not exist ..\\..\\bin\\release\\lib mkdir ..\\..\\bin\\release\\lib\n\n");
550 #endif
551         
552         // dump modules.. again the second and last time :)
553         for(int i = 0; i < command_count; ++i)
554                 fprintf(f, "%s.so : %s.obj\n", commands[i], commands[i]);
555
556         fprintf(f, "\n");
557         fclose(f);
558 }
559
560 void WriteCompileModules()
561 {
562         char modules[300][100];
563         int module_count = 0;
564
565         printf("Finding Modules...\n");
566         WIN32_FIND_DATA fd;
567         HANDLE fh = FindFirstFile("..\\src\\modules\\m_*.cpp", &fd);
568         if(fh == INVALID_HANDLE_VALUE)
569                 printf_c("\033[1;32m  No module sources could be found! This \033[1m*could*\033[1;32m be a bad thing.. :P\033[0m");
570         else
571         {
572                 sc(TGREEN);
573                 do 
574                 {
575                         strcpy(modules[module_count], fd.cFileName);
576                         modules[module_count][strlen(fd.cFileName) - 4] = 0;
577                         printf("  %s\n", modules[module_count]);
578                         ++module_count;
579                 } while(FindNextFile(fh, &fd));
580                 sc(TNORMAL);
581         }
582
583         // Write our spiffy new makefile :D
584         // I am such a lazy fucker :P
585         FILE * f = fopen("..\\src\\modules\\modules.mak", "w");
586
587         time_t t = time(NULL);
588         fprintf(f, "# Generated at %s\n", ctime(&t));
589         fprintf(f, "all: makedir ");
590
591         // dump modules.. first time :)
592         for(int i = 0; i < module_count; ++i)
593                 fprintf(f, "%s.so ", modules[i]);
594
595         fprintf(f, "\n.cpp.obj:\n");
596 #ifdef WIN64
597         // /MACHINE:X64
598         #ifdef _DEBUG
599                 fprintf(f, "  cl /nologo /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/modules\" /I \"../../win\" /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /Gm /EHsc /Gm /RTC1 /MDd /Fo\"Debug/\" /Fd\"Debug/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\debug_x64\\bin\\inspircd.lib ws2_32.lib /OUT:\"..\\..\\bin\\debug_x64\\modules\\$*.so\" /PDB:\"..\\..\\bin\\debug_x64\\modules\\$*.pdb\" /MACHINE:X64 /IMPLIB:\"..\\..\\bin\\debug_x64\\modules\\$*.lib\"\n\n");
600                 CreateDirectory("..\\src\\modules\\debug_x64", NULL);
601         #else
602                 fprintf(f, "  cl /nologo /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/modules\" /I \"../../win\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /EHsc /Gm /GL /MD /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\release_x64\\bin\\inspircd.lib ws2_32.lib /OUT:\"..\\..\\bin\\release_x64\\modules\\$*.so\" /PDB:\"..\\..\\bin\\release_x64\\modules\\$*.pdb\" /MACHINE:X64 /IMPLIB:\"..\\..\\bin\\release_x64\\modules\\$*.lib\"\n\n");
603                 CreateDirectory("..\\src\\modules\\release_x64", NULL);
604         #endif
605 #else
606         #ifdef _DEBUG
607                 fprintf(f, "  cl /nologo -Dssize_t=long /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/modules\" /I \"../../win\" /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /Gm /EHsc /Gm /RTC1 /MDd /Fo\"Debug/\" /Fd\"Debug/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\debug\\bin\\inspircd.lib ws2_32.lib /OUT:\"..\\..\\bin\\debug\\modules\\$*.so\" /PDB:\"..\\..\\bin\\debug\\modules\\$*.pdb\" /IMPLIB:\"..\\..\\bin\\debug\\modules\\$*.lib\"\n\n");
608                 CreateDirectory("..\\src\\modules\\debug", NULL);
609                 CreateDirectory("..\\src\\modules\\debug\\lib", NULL);
610                 CreateDirectory("..\\src\\modules\\debug\\modules", NULL);
611                 CreateDirectory("..\\src\\modules\\debug\\bin", NULL);
612         #else
613                 fprintf(f, "  cl /nologo -Dssize_t=long /LD /Od /I \".\" /I \"../../include\" /I \"../../include/modes\" /I \"../../include/modules\" /I \"../../win\" /D \"WIN32\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"DLL_BUILD\" /EHsc /Gm /GL /MD /Fo\"Release/\" /Fd\"Release/vc70.pdb\" /W2 /Wp64 /Zi /TP $*.cpp ..\\..\\win\\inspircd_memory_functions.cpp /link ..\\..\\bin\\release\\bin\\inspircd.lib ws2_32.lib /OUT:\"..\\..\\bin\\release\\modules\\$*.so\" /PDB:\"..\\..\\bin\\release\\modules\\$*.pdb\" /IMPLIB:\"..\\..\\bin\\release\\modules\\$*.lib\"\n\n");
614                 CreateDirectory("..\\src\\modules\\release", NULL);
615                 CreateDirectory("..\\src\\modules\\release\\lib", NULL);
616                 CreateDirectory("..\\src\\modules\\release\\modules", NULL);
617                 CreateDirectory("..\\src\\modules\\release\\bin", NULL);
618         #endif
619 #endif
620         
621 #ifdef _DEBUG
622         fprintf(f, "makedir:\n  if not exist debug mkdir debug\n  if not exist ..\\..\\bin\\debug\\modules mkdir ..\\..\\bin\\debug\\modules\n\n");
623 #else
624         fprintf(f, "makedir:\n  if not exist release mkdir release\n  if not exist ..\\..\\bin\\release\\modules mkdir ..\\..\\bin\\release\\modules\n\n");
625 #endif
626
627         // dump modules.. again the second and last time :)
628         for(int i = 0; i < module_count; ++i)
629                 fprintf(f, "%s.so : %s.obj\n", modules[i], modules[i]);
630
631         fprintf(f, "\n");
632         fclose(f);
633 }