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