]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - win/configure.cpp
bb8cacd0d90527e18b56a441b0a25b4990bee811
[user/henk/code/inspircd.git] / win / configure.cpp
1 /*       +------------------------------------+\r
2  *       | Inspire Internet Relay Chat Daemon |\r
3  *       +------------------------------------+\r
4  *\r
5  *  InspIRCd: (C) 2002-2007 InspIRCd Development Team\r
6  * See: http://www.inspircd.org/wiki/index.php/Credits\r
7  *\r
8  * This program is free but copyrighted software; see\r
9  *            the file COPYING for details.\r
10  *\r
11  * ---------------------------------------------------\r
12  */\r
13 \r
14 #define _CRT_SECURE_NO_DEPRECATE\r
15 \r
16 #include <windows.h>\r
17 #include <stdio.h>\r
18 #include <string>\r
19 #include <time.h>\r
20 #include "colours.h"\r
21 \r
22 using namespace std;\r
23 void Run();\r
24 void Banner();\r
25 void WriteCompileModules();\r
26 void WriteCompileCommands();\r
27 \r
28 /* detects if we are running windows xp or higher (5.1) */\r
29 bool iswinxp()\r
30 {\r
31         OSVERSIONINFO vi;\r
32         vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
33         GetVersionEx(&vi);\r
34         if(vi.dwMajorVersion >= 5)\r
35                 return true;\r
36         \r
37         return false;\r
38 }\r
39 \r
40 int get_int_option(const char * text, int def)\r
41 {\r
42         static char buffer[500];\r
43         int ret;\r
44         printf_c("%s\n[\033[1;32m%u\033[0m] -> ", text, def);\r
45         fgets(buffer, 500, stdin);\r
46         if(sscanf(buffer, "%u", &ret) != 1)\r
47                 ret = def;\r
48 \r
49         printf("\n");\r
50         return ret;\r
51 }\r
52 \r
53 bool get_bool_option(const char * text, bool def)\r
54 {\r
55         static char buffer[500];\r
56         char ret[100];\r
57         printf_c("%s [\033[1;32m%c\033[0m] -> ", text, def ? 'y' : 'n');\r
58         fgets(buffer, 500, stdin);\r
59         if(sscanf(buffer, "%s", ret) != 1)\r
60                 strcpy(ret, def ? "y" : "n");\r
61 \r
62         printf("\n");\r
63         return !strncmp(ret, "y", 1);\r
64 }\r
65 \r
66 void get_string_option(const char * text, char * def, char * buf)\r
67 {\r
68         static char buffer[500];\r
69         printf_c("%s\n[\033[1;32m%s\033[0m] -> ", text, def);\r
70         fgets(buffer, 500, stdin);\r
71         if(sscanf(buffer, "%s", buf) != 1)\r
72                 strcpy(buf, def);\r
73 \r
74         printf("\n");\r
75 }\r
76 \r
77 // escapes a string for use in a c++ file\r
78 bool escape_string(char * str, size_t size)\r
79 {\r
80         size_t len = strlen(str);\r
81         char * d_str = (char*)malloc(len * 2);\r
82     \r
83         size_t i = 0;\r
84         size_t j = 0;\r
85 \r
86         for(; i < len; ++i)\r
87         {\r
88                 if(str[i] == '\\')\r
89                 {\r
90                         d_str[j++] = '\\';\r
91                         d_str[j++] = '\\';\r
92                 }\r
93                 else\r
94                 {\r
95                         d_str[j++] = str[i];\r
96                 }\r
97         }\r
98 \r
99         d_str[j++] = 0;\r
100 \r
101     if(j > size)\r
102         {\r
103                 free(d_str);\r
104                 return false;\r
105         }\r
106 \r
107         strcpy(str, d_str);\r
108         free(d_str);\r
109         return true;\r
110 }\r
111 \r
112 /* gets the svn revision */\r
113 int get_svn_revision(char * buffer, size_t len)\r
114 {\r
115         /* again.. I am lazy :p cbf to pipe output of svn info to us, so i'll just read the file */\r
116         /*\r
117         8\r
118 \r
119         dir\r
120         7033\r
121         */\r
122         char buf[1000];\r
123         FILE * f = fopen("..\\.svn\\entries", "r");\r
124         if(!f) goto bad_rev;\r
125     \r
126         if(!fgets(buf, 1000, f)) goto bad_rev;\r
127         if(!fgets(buf, 1000, f)) goto bad_rev;\r
128         if(!fgets(buf, 1000, f)) goto bad_rev;\r
129         if(!fgets(buf, 1000, f)) goto bad_rev;\r
130         int rev = atoi(buf);\r
131         if(rev == 0) goto bad_rev;\r
132         sprintf(buffer, "%u", rev);\r
133         fclose(f);\r
134         return rev;\r
135         \r
136 bad_rev:\r
137         strcpy(buffer, "non-svn");\r
138         if(f) fclose(f);\r
139         return 0;\r
140 }\r
141 \r
142 int __stdcall WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN int nShowCmd )\r
143 {\r
144         FILE * j = fopen("inspircd_config.h", "r");\r
145         if (j)\r
146         {\r
147                 if (MessageBox(0, "inspircd_config.h already exists. Remove it and build from clean?", "Configure program", MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2) != IDYES)\r
148                 {\r
149                         fclose(j);\r
150                         exit(0);\r
151                 }\r
152         }\r
153 \r
154         AllocConsole();\r
155 \r
156         // pipe standard handles to this console\r
157         freopen("CONIN$", "r", stdin);\r
158         freopen("CONOUT$", "w", stdout);\r
159         freopen("CONOUT$", "w", stderr);\r
160 \r
161         Banner();\r
162         Run();\r
163         WriteCompileCommands();\r
164         WriteCompileModules();\r
165         FreeConsole();\r
166         return 0;\r
167 }\r
168 \r
169 void Banner()\r
170 {\r
171         printf_c("\nWelcome to the \033[1mInspIRCd\033[0m Configuration program! (\033[1minteractive mode\033[0m)\n"\r
172                          "\033[1mPackage maintainers: Type ./configure --help for non-interactive help\033[0m\n\n");\r
173         printf_c("*** If you are unsure of any of these values, leave it blank for    ***\n"\r
174                          "*** standard settings that will work, and your server will run      ***\n"\r
175                          "*** using them. Please consult your IRC network admin if in doubt.  ***\n\n"\r
176                          "Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter\n"\r
177                          "a new value. Please note: You will \033[1mHAVE\033[0m to read the docs\n"\r
178                          "dir, otherwise you won't have a config file!\n\n");\r
179 \r
180 }\r
181 \r
182 void Run()\r
183 {\r
184         int max_fd = 1024;\r
185         bool use_iocp = false;\r
186         bool support_ip6links = false;\r
187         char mod_path[MAX_PATH];\r
188         char config_file[MAX_PATH];\r
189         char library_dir[MAX_PATH];\r
190         char base_path[MAX_PATH];\r
191         char bin_dir[MAX_PATH];\r
192         char revision_text[MAX_PATH];\r
193 \r
194         int max_clients = 1024;\r
195         int nicklen = 31;\r
196         int chanlen = 64;\r
197         int modechanges = 20;\r
198         int identlen = 12;\r
199         int quitlen = 255;\r
200         int topiclen = 500;\r
201         int kicklen = 255;\r
202         int rllen = 128;\r
203         int awaylen = 200;\r
204         int revision = get_svn_revision(revision_text, MAX_PATH);\r
205         char version[514];\r
206 \r
207         // grab version\r
208         FILE * fI = fopen("..\\src\\version.sh", "r");\r
209         if(fI)\r
210         {\r
211                 fgets(version, 514, fI);\r
212                 fgets(version, 514, fI);\r
213                 char * p2 = version;\r
214                 while(*p2 != '\"')\r
215                         ++p2;\r
216                 ++p2;\r
217                 strcpy(version, p2);\r
218                 p2 = version;\r
219                 while(*p2 != '\"')\r
220                         ++p2;\r
221                 *p2 = 0;\r
222                 fclose(fI);\r
223         }\r
224         else\r
225                 strcpy(version, "InspIRCD-Unknown");\r
226         printf_c("Your operating system is: \033[1;32mwindows \033[0m\n");\r
227         printf_c("InspIRCd revision ID: \033[1;32m%s \033[0m\n\n", revision ? revision_text : "(Non-SVN build)");\r
228 \r
229         max_fd = get_int_option("What is the maximum file descriptor count you would like to allow?", 1024);\r
230 \r
231         // detect windows\r
232         if(iswinxp())\r
233         {\r
234                 printf_c("You are running Windows 2000 or above, and IOCP support is most likely available.\n"\r
235                              "This removes the socket number limitation of select and is much more efficent.\n"\r
236                                  "If you are unsure, answer yes.\n\n");\r
237 \r
238                 use_iocp = get_bool_option("Do you want to use the IOCP implementation?", true);\r
239         }\r
240 \r
241         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)", \r
242                 true);\r
243         \r
244         printf_c("\033[1mAll paths are relative to the binary directory.\033[0m\n");\r
245         get_string_option("In what directory do you wish to install the InspIRCd base?", "..", base_path);\r
246         get_string_option("In what directory are the configuration files?", "../conf", config_file);\r
247         get_string_option("In what directory are the modules to be compiled to?", "../modules", mod_path);\r
248         get_string_option("In what directory is the IRCd binary to be placed?", ".", bin_dir);\r
249         get_string_option("In what directory are the IRCd libraries to be placed?", "../lib", library_dir);\r
250 \r
251         printf_c("The following questions will ask you for various figures relating\n"\r
252                 "To your IRCd install. Please note that these should usually be left\n"\r
253                 "as defaults unless you have a real reason to change them. If they\n"\r
254                 "changed, then the values must be identical on all servers on your\n"\r
255                 "network, or malfunctions and/or crashes may occur, with the exception\n"\r
256                 "of the 'maximum number of clients' setting which may be different on\n"\r
257                 "different servers on the network.\n\n");\r
258 \r
259     \r
260         max_clients = get_int_option("Please enter the maximum number of clients at any one time?", 1024);\r
261         nicklen = get_int_option("Please enter the maximum length of nicknames?", 31);\r
262         chanlen = get_int_option("Please enter the maximum length of channel names?", 64);\r
263         modechanges = get_int_option("Please enter the maximum number of mode changes in one line?", 20);\r
264         identlen = get_int_option("Please enter the maximum length of an ident (username)?", 12);\r
265         quitlen = get_int_option("Please enter the maximum length of a quit message?", 255);\r
266         topiclen = get_int_option("Please enter the maximum length of a channel topic?", 307);\r
267         kicklen = get_int_option("Please enter the maximum length of a kick message?", 255);\r
268         rllen = get_int_option("Please enter the maximum length of a GECOS (real name)?", 128);\r
269         awaylen = get_int_option("Please enter the maximum length of an away message?", 200);\r
270 \r
271         printf_c("\n\033[1;32mPre-build configuration is complete!\n\n");       sc(TNORMAL);\r
272 \r
273         // dump all the options back out\r
274         printf_c("\033[0mBase install path:\033[1;32m        %s\n", base_path);\r
275         printf_c("\033[0mConfig path:\033[1;32m              %s\n", config_file);\r
276         printf_c("\033[0mModule path:\033[1;32m              %s\n", mod_path);\r
277         printf_c("\033[0mLibrary path:\033[1;32m             %s\n", library_dir);\r
278         printf_c("\033[0mSocket Engine:\033[1;32m            %s\n", use_iocp ? "iocp" : "select");\r
279         printf_c("\033[0mMax file descriptors:\033[1;32m     %u\n", max_fd);\r
280         printf_c("\033[0mMax connections:\033[1;32m          %u\n", max_clients);\r
281         printf_c("\033[0mMax nickname length:\033[1;32m      %u\n", nicklen);\r
282         printf_c("\033[0mMax channel length:\033[1;32m       %u\n", chanlen);\r
283         printf_c("\033[0mMax mode length:\033[1;32m          %u\n", modechanges);\r
284         printf_c("\033[0mMax ident length:\033[1;32m         %u\n", identlen);\r
285         printf_c("\033[0mMax quit length:\033[1;32m          %u\n", quitlen);\r
286         printf_c("\033[0mMax topic length:\033[1;32m         %u\n", topiclen);\r
287         printf_c("\033[0mMax kick length:\033[1;32m          %u\n", kicklen);\r
288         printf_c("\033[0mMax name length:\033[1;32m          %u\n", rllen);\r
289         printf_c("\033[0mMax away length:\033[1;32m          %u\n", awaylen);\r
290         printf("\n"); sc(TNORMAL);\r
291         if(get_bool_option("Are these settings correct?", true) == false)\r
292         {\r
293                 Run();\r
294                 return;\r
295         }\r
296         printf("\n");\r
297 \r
298         // escape the pathes\r
299         escape_string(config_file, MAX_PATH);\r
300         escape_string(mod_path, MAX_PATH);\r
301         escape_string(library_dir, MAX_PATH);\r
302 \r
303         printf("\nWriting inspircd_config.h...");\r
304         FILE * f = fopen("inspircd_config.h", "w");\r
305         fprintf(f, "/* Auto generated by configure, do not modify! */\n");\r
306         fprintf(f, "#ifndef __CONFIGURATION_AUTO__\n");\r
307         fprintf(f, "#define __CONFIGURATION_AUTO__\n\n");\r
308         if(use_iocp)\r
309                 fprintf(f, "#define CONFIG_USE_IOCP 1\n\n");\r
310 \r
311         fprintf(f, "#define CONFIG_FILE \"%s/inspircd.conf\"\n", config_file);\r
312         fprintf(f, "#define MOD_PATH \"%s\"\n", mod_path);\r
313         fprintf(f, "#define MAX_DESCRIPTORS %u\n", max_fd);\r
314         fprintf(f, "#define MAXCLIENTS %u\n", max_clients);\r
315         fprintf(f, "#define MAXCLIENTS_S \"%u\"\n", max_clients);\r
316         fprintf(f, "#define SOMAXCONN_S \"128\"\n");\r
317         fprintf(f, "#define NICKMAX %u\n", nicklen+1);\r
318         fprintf(f, "#define CHANMAX %u\n", chanlen+1);\r
319         fprintf(f, "#define MAXMODES %u\n", modechanges);\r
320         fprintf(f, "#define IDENTMAX %u\n", identlen);\r
321         fprintf(f, "#define MAXQUIT %u\n", quitlen);\r
322         fprintf(f, "#define MAXTOPIC %u\n", topiclen);\r
323         fprintf(f, "#define MAXKICK %u\n", kicklen);\r
324         fprintf(f, "#define MAXGECOS %u\n", rllen);\r
325         fprintf(f, "#define MAXAWAY %u\n", awaylen);\r
326         fprintf(f, "#define LIBRARYDIR \"%s\"\n", library_dir);\r
327         fprintf(f, "#define VERSION \"%s\"\n", version);\r
328         fprintf(f, "#define REVISION \"%s\"\n", revision_text);\r
329         if(support_ip6links)\r
330                 fprintf(f, "#define SUPPORT_IP6LINKS 1\n");\r
331 \r
332         OSVERSIONINFO vi;\r
333         vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
334         GetVersionEx(&vi);\r
335         fprintf(f, "#define SYSTEM \"Windows %u.%u.%u %s\"\n", vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, vi.szCSDVersion);\r
336         fprintf(f, "#define MAXBUF 514\n");\r
337 \r
338         fprintf(f, "\n#include \"inspircd_win32wrapper.h\"\n\n");\r
339         fprintf(f, "#endif\n\n");\r
340         fclose(f);\r
341 \r
342         sc(TGREEN); printf(" done\n"); sc(TNORMAL);\r
343         printf("Writing inspircd_se_config.h...");\r
344 \r
345         f = fopen("inspircd_se_config.h", "w");\r
346         fprintf(f, "/* Auto generated by configure, do not modify or commit to svn! */\n");\r
347         fprintf(f, "#ifndef __CONFIGURATION_SOCKETENGINE__\n");\r
348         fprintf(f, "#define __CONFIGURATION_SOCKETENGINE__\n\n");\r
349         fprintf(f, "#include \"socketengine_%s.h\"\n\n", use_iocp ? "iocp" : "select");\r
350         fprintf(f, "#endif\n\n");\r
351         fclose(f);\r
352 \r
353         sc(TGREEN); printf(" done\n"); sc(TNORMAL);\r
354         printf("Writing command and module compilation scripts...");\r
355         WriteCompileCommands();\r
356         WriteCompileModules();\r
357         sc(TGREEN); printf(" done\n"); sc(TNORMAL);\r
358 \r
359         printf("\nconfigure is done.. exiting!\n");\r
360 }\r
361 \r
362 void WriteCompileCommands()\r
363 {\r
364         char commands[300][100];\r
365         int command_count = 0;\r
366         printf("\n  Finding Command Sources...\n");\r
367         WIN32_FIND_DATA fd;\r
368         HANDLE fh = FindFirstFile("..\\src\\cmd_*.cpp", &fd);\r
369         if(fh == INVALID_HANDLE_VALUE)\r
370                 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");\r
371         else\r
372         {\r
373                 sc(TGREEN);\r
374                 do \r
375                 {\r
376                         strcpy(commands[command_count], fd.cFileName);\r
377                         commands[command_count][strlen(fd.cFileName) - 4] = 0;\r
378                         printf("    %s\n", commands[command_count]);\r
379                         ++command_count;\r
380                 } while(FindNextFile(fh, &fd));\r
381                 sc(TNORMAL);\r
382         }\r
383     \r
384         // Write our spiffy new makefile :D\r
385         // I am such a lazy fucker :P\r
386         FILE * f = fopen("..\\src\\commands.mak", "w");\r
387 \r
388         time_t t = time(NULL);\r
389         fprintf(f, "# Generated at %s\n", ctime(&t));\r
390         fprintf(f, "all: makedir ");\r
391 \r
392         // dump modules.. first time :)\r
393         for(int i = 0; i < command_count; ++i)\r
394                 fprintf(f, "%s.so ", commands[i]);\r
395 \r
396         fprintf(f, "\n.cpp.obj:\n");\r
397 #ifdef _DEBUG\r
398         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 /MTd /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");\r
399         CreateDirectory("..\\src\\debug", NULL);\r
400         CreateDirectory("..\\bin\\debug\\bin", NULL);\r
401         CreateDirectory("..\\bin\\debug\\lib", NULL);\r
402         CreateDirectory("..\\bin\\debug\\modules", NULL);\r
403 #else\r
404         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 /MT /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");\r
405         CreateDirectory("..\\src\\release", NULL);\r
406         CreateDirectory("..\\bin\\release\\bin", NULL);\r
407         CreateDirectory("..\\bin\\release\\lib", NULL);\r
408         CreateDirectory("..\\bin\\release\\modules", NULL);\r
409 #endif\r
410 \r
411         fprintf(f, "makedir:\n  if not exist debug mkdir debug\n\n");\r
412         \r
413         // dump modules.. again the second and last time :)\r
414         for(int i = 0; i < command_count; ++i)\r
415                 fprintf(f, "%s.so : %s.obj\n", commands[i], commands[i]);\r
416 \r
417         fprintf(f, "\n");\r
418         fclose(f);\r
419 }\r
420 \r
421 void WriteCompileModules()\r
422 {\r
423         char modules[300][100];\r
424         int module_count = 0;\r
425 \r
426         printf("Finding Modules...\n");\r
427         WIN32_FIND_DATA fd;\r
428         HANDLE fh = FindFirstFile("..\\src\\modules\\m_*.cpp", &fd);\r
429         if(fh == INVALID_HANDLE_VALUE)\r
430                 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");\r
431         else\r
432         {\r
433                 sc(TGREEN);\r
434                 do \r
435                 {\r
436                         strcpy(modules[module_count], fd.cFileName);\r
437                         modules[module_count][strlen(fd.cFileName) - 4] = 0;\r
438                         printf("  %s\n", modules[module_count]);\r
439                         ++module_count;\r
440                 } while(FindNextFile(fh, &fd));\r
441                 sc(TNORMAL);\r
442         }\r
443 \r
444         // Write our spiffy new makefile :D\r
445         // I am such a lazy fucker :P\r
446         FILE * f = fopen("..\\src\\modules\\modules.mak", "w");\r
447 \r
448         time_t t = time(NULL);\r
449         fprintf(f, "# Generated at %s\n", ctime(&t));\r
450         fprintf(f, "all: makedir ");\r
451 \r
452         // dump modules.. first time :)\r
453         for(int i = 0; i < module_count; ++i)\r
454                 fprintf(f, "%s.so ", modules[i]);\r
455 \r
456         fprintf(f, "\n.cpp.obj:\n");\r
457 #ifdef _DEBUG\r
458         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 /MTd /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");\r
459         CreateDirectory("..\\src\\modules\\debug", NULL);\r
460 #else\r
461         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 /MT /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");\r
462         CreateDirectory("..\\src\\modules\\release", NULL);\r
463 #endif\r
464         \r
465         fprintf(f, "makedir:\n  if not exist debug mkdir debug\n\n");\r
466 \r
467         // dump modules.. again the second and last time :)\r
468         for(int i = 0; i < module_count; ++i)\r
469                 fprintf(f, "%s.so : %s.obj\n", modules[i], modules[i]);\r
470 \r
471         fprintf(f, "\n");\r
472         fclose(f);\r
473 }\r