]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - configure
Fix resolving of security ips to allow for ipv4 resolution when built for ipv6
[user/henk/code/inspircd.git] / configure
1 #!/usr/bin/perl
2
3 # InspIRCd Configuration Script
4 #
5 # Copyright 2002-2007 The ChatSpike Development Team
6 # <brain@chatspike.net>
7 # <Craig@chatspike.net>
8 #
9 # [14:21] Brain: <matrix impression> i know perl-fu!
10 #
11 # $Id$
12 #
13 ########################################
14
15
16 require 5.6.0;
17 use Socket;
18 use Cwd;
19 use Getopt::Long;
20
21 # Utility functions for our buildsystem
22 use make::utilities;
23 use make::configure;
24
25 GetOptions (
26         'enable-gnutls' => \$opt_use_gnutls,
27         'rebuild' => \$opt_rebuild,
28         'enable-openssl' => \$opt_use_openssl,
29         'disable-interactive' => \$opt_nointeractive,
30         'with-nick-length=i' => \$opt_nick_length,
31         'with-channel-length=i' => \$opt_chan_length,
32         'with-max-channels=i' => \$opt_maxchans,
33         'with-max-oper-channels=i' => \$opt_opermaxchans,
34         'with-max-clients=i' => \$opt_maxclients,
35         'enable-epoll' => \$opt_epoll,
36         'enable-kqueue' => \$opt_kqueue,
37         'disable-epoll' => \$opt_noepoll,
38         'disable-kqueue' => \$opt_nokqueue,
39         'enable-ipv6' => \$opt_ipv6,
40         'enable-remote-ipv6' => \$opt_ipv6links,
41         'disable-remote-ipv6' => \$opt_noipv6links,
42         'with-cc=s' => \$opt_cc,
43         'with-ident-length=i' => \$opt_ident,
44         'with-quit-length=i' => \$opt_quit,
45         'with-topic-length=i' => \$opt_topic,
46         'with-kick-length=i' => \$opt_kick,
47         'with-gecos-length=i' => \$opt_gecos,
48         'with-away-length=i' => \$opt_away,
49         'with-max-modes=i' => \$opt_modes,
50         'prefix=s' => \$opt_base_dir,
51         'config-dir=s' => \$opt_config_dir,
52         'module-dir=s' => \$opt_module_dir,
53         'binary-dir=s' => \$opt_binary_dir,
54         'library-dir=s' => \$opt_library_dir,
55         'disable-debuginfo' => sub { $opt_disable_debug = 1 },
56         'help'  => sub { showhelp(); },
57         'modupdate' => sub { modupdate(); },
58         'update' => sub { update(); },
59         'svnupdate' => sub { svnupdate(); },
60         'clean' => sub { clean(); },
61 );
62
63 my $non_interactive = (
64         (defined $opt_library_dir) ||
65         (defined $opt_base_dir) ||
66         (defined $opt_config_dir) ||
67         (defined $opt_module_dir) ||
68         (defined $opt_base_dir) ||
69         (defined $opt_binary_dir) ||
70         (defined $opt_nointeractive) ||
71         (defined $opt_away) ||
72         (defined $opt_gecos) ||
73         (defined $opt_kick) ||
74         (defined $opt_maxclients) ||
75         (defined $opt_modes) ||
76         (defined $opt_topic) ||
77         (defined $opt_quit) ||
78         (defined $opt_ident) ||
79         (defined $opt_cc) ||
80         (defined $opt_ipv6) ||
81         (defined $opt_ipv6links) ||
82         (defined $opt_noipv6links) ||
83         (defined $opt_kqueue) ||
84         (defined $opt_epoll) ||
85         (defined $opt_maxchans) ||
86         (defined $opt_opermaxchans) ||
87         (defined $opt_chan_length) ||
88         (defined $opt_nick_length) ||
89         (defined $opt_use_openssl) ||
90         (defined $opt_nokqueue) ||
91         (defined $opt_noepoll) ||
92         (defined $opt_use_gnutls)
93 );
94 my $interactive = !$non_interactive;
95
96
97 chomp($topdir = getcwd());
98 $this = resolve_directory($topdir);                                             # PWD, Regardless.
99 @modlist = ();                                                          # Declare for Module List..
100 %config = ();                                                           # Initiate Configuration Hash..
101 $config{ME}              = resolve_directory($topdir);                  # Present Working Directory
102
103 $config{BASE_DIR}          = $config{ME};
104
105 if (defined $opt_base_dir)
106 {
107         $config{BASE_DIR} = $opt_base_dir;
108 }
109
110 $config{CONFIG_DIR}      = resolve_directory($config{BASE_DIR}."/conf");                # Configuration Directory
111 $config{MODULE_DIR}      = resolve_directory($config{BASE_DIR}."/modules");             # Modules Directory
112 $config{BINARY_DIR}      = resolve_directory($config{BASE_DIR}."/bin");         # Binary Directory
113 $config{LIBRARY_DIR}    = resolve_directory($config{BASE_DIR}."/lib");          # Library Directory
114
115 if (defined $opt_config_dir)
116 {
117         $config{CONFIG_DIR} = $opt_config_dir;
118 }
119 if (defined $opt_module_dir)
120 {
121         $config{MODULE_DIR} = $opt_module_dir;
122 }
123 if (defined $opt_binary_dir)
124 {
125         $config{BINARY_DIR} = $opt_binary_dir;
126 }
127 if (defined $opt_library_dir)
128 {
129         $config{LIBRARY_DIR} = $opt_library_dir;
130 }
131 chomp($config{HAS_GNUTLS}   = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
132 chomp($config{HAS_OPENSSL}  = `openssl version 2>/dev/null`);                   # Openssl version
133 $config{USE_GNUTLS}         = "n";
134 if (defined $opt_use_gnutls)
135 {
136         $config{USE_GNUTLS} = "y";                                              # Use gnutls.
137 }
138 $config{USE_OPENSSL}    = "n";                                          # Use openssl.
139 if (defined $opt_use_openssl)
140 {
141         $config{USE_OPENSSL} = "y";
142 }
143
144 # no, let's not change these.
145 $config{OPTIMITEMP}      = "0";                                 # Default Optimisation Value
146 if (!defined $opt_disable_debug)
147 {
148         $config{OPTIMISATI}      = "-g1";                               # Optimisation Flag
149 }
150 else
151 {
152         $config{OPTIMISATI}      = "-O2";                                       # DEBUGGING OFF!
153 }
154
155 $config{NICK_LENGT}      = "31";                                        # Default Nick Length
156 if (defined $opt_nick_length)
157 {
158         $config{NICK_LENGT} = $opt_nick_length;
159 }
160 $config{CHAN_LENGT}      = "64";                                        # Default Channel Name Length
161 if (defined $opt_chan_length)
162 {
163         $config{CHAN_LENGT} = $opt_chan_length;
164 }
165 $config{MAX_CHANNE}      = "20";                                        # Default Max. Channels per user
166 if (defined $opt_maxchans)
167 {
168         $config{MAX_CHANNE} = $opt_maxchans;
169 }
170 $config{MAX_OPERCH}      = "60";                                                # Default Max. Channels per oper
171 if (defined $opt_opermaxchans)
172 {
173         $config{MAX_OPERCH} = $opt_opermaxchans;
174 }
175 $config{MAXI_MODES}      = "20";                                        # Default Max. Number of Modes set at once.
176 if (defined $opt_modes)
177 {
178         $config{MAXI_MODES} = $opt_modes;
179 }
180 $config{HAS_STRLCPY}    = "false";                                      # strlcpy Check.
181 $config{HAS_STDINT}      = "false";                                             # stdint.h check
182 $config{USE_KQUEUE}      = "y";                                         # kqueue enabled
183 if (defined $opt_kqueue)
184 {
185         $config{USE_KQUEUE} = "y";
186 }
187 if (defined $opt_nokqueue)
188 {
189         $config{USE_KQUEUE} = "n";
190 }
191 $config{USE_EPOLL}        = "y";                                                # epoll enabled
192 if (defined $opt_epoll)
193 {
194         $config{USE_EPOLL} = "y";
195 }
196 if (defined $opt_noepoll)
197 {
198         $config{USE_EPOLL} = "n";
199 }
200 $config{IPV6}          = "n";                                           # IPv6 support (experimental)
201 if (defined $opt_ipv6)
202 {
203         $config{IPV6} = "y";
204 }
205 $config{SUPPORT_IP6LINKS}   = "y";                                              # IPv4 supporting IPv6 links (experimental)
206 if (defined $opt_ipv6links)
207 {
208         $config{SUPPORT_IP6LINKS} = "y";
209 }
210 if (defined $opt_noipv6links)
211 {
212         $config{SUPPORT_IP6LINKS} = "n";
213 }
214 $config{STATIC_LINK}        = "no";                                             # are doing static modules?
215 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`);                   # FD Limit
216 chomp($config{MAX_DESCRIPTORS} = `sh -c \"ulimit -n\"`);                        # Hard FD Limit
217 chomp($config{GCCVER}       = `g++ -dumpversion | cut -c 1`);                   # Major GCC Version
218 $config{_SOMAXCONN} = SOMAXCONN;                                                # Max connections in accept queue
219 $config{OSNAME}             = $^O;                                      # Operating System Name
220 $config{IS_DARWIN}          = "NO";                                             # Is OSX?
221 if ($config{OSNAME} =~ /darwin/i)
222 {
223         $config{IS_DARWIN} = "YES";
224 }
225 $config{CC}                 = "g++";                                            # C++ compiler
226 if (defined $opt_cc)
227 {
228         $config{CC} = $opt_cc;
229 }
230 $exec = $config{CC} . " -dumpversion | cut -c 1";
231 chomp($config{GCCVER}       = `$exec`);                                         # Major GCC Version
232 $config{MAKEORDER}          = "ircd mods";                                      # build order
233 $config{STATICLIBS}      = "";                                          # library archive path
234 $config{MAX_IDENT}        = "12";                                               # max ident size
235 $config{MAX_QUIT}          = "255";                                             # max quit message size
236 $config{MAX_TOPIC}        = "307";                                              # max topic size
237 $config{MAX_KICK}          = "255";                                             # max kick message size
238 $config{MAX_GECOS}        = "128";                                              # max GECOS size
239 $config{MAX_AWAY}          = "200";                                             # max AWAY size
240 if (defined $opt_ident)
241 {
242         $config{MAX_IDENT} = $opt_ident;
243 }
244 if (defined $opt_quit)
245 {
246         $config{MAX_QUIT} = $opt_quit;
247 }
248 if (defined $opt_topic)
249 {
250         $config{MAX_TOPIC} = $opt_topic;
251 }
252 if (defined $opt_kick)
253 {
254         $config{MAX_KICK} = $opt_kick;
255 }
256 if (defined $opt_gecos)
257 {
258         $config{MAX_GECOS} = $opt_gecos;
259 }
260 if (defined $opt_away)
261 {
262         $config{MAX_AWAY} = $opt_away;
263 }
264
265 $config{HAS_OPENSSL} =~ /OpenSSL ([-[:digit:].]+)([a-z])?(\-[a-z][0-9])? (\w{3}|[0-9]+) (\w{3}|[0-9]+) [0-9]{4}/;
266 $config{HAS_OPENSSL} = $1;
267
268 if ($config{GCCVER} eq "") {
269         print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
270         exit;
271 }
272
273 # Minihack! Convert Cygwin to 'Cyg-Static' so i can
274 # Keep my dynamic module experiments here for later
275 # consideration!
276
277 if ($config{OSNAME} =~ /CYGWIN/i)
278 {
279         $config{OSNAME} = "CYG-STATIC";
280 }
281
282 if (!$config{MAX_CLIENT_T}) { 
283         $config{MAX_CLIENT_T} = 1024;                            # Set a reasonable 'Default'
284         $fd_scan_fail = "true";                                # Used Later
285 }
286
287 # Get and Set some important vars..
288 getmodules();
289
290 sub clean
291 {
292         system("rm -rf .config.cache");
293 }
294
295 sub update
296 {
297         eval {
298                 chomp($topdir = getcwd());
299                 $this = resolve_directory($topdir);                                          # PWD, Regardless.
300                 getmodules();
301                 # Does the cache file exist?
302                 if (!getcache()) {
303                         # No, No it doesn't.. *BASH*
304                         print "You have not run ./configure before. Please do this before trying to run the update script.\n";
305                         exit 0;
306                 } else {
307                         # We've Loaded the cache file and all our variables..
308                         print "Updating Files..\n";
309                         getosflags();
310                         if ($opt_disable_debug == 1)
311                         {
312                                 print "Disabling debug information (-g).\n";
313                                 $config{OPTIMISATI} = "";
314                                 getosflags();
315                         }
316                         $has_epoll = $config{HAS_EPOLL};
317                         $has_kqueue = $config{HAS_KQUEUE};
318                         writefiles(1);
319                         makecache();
320                         print "Complete.\n";
321                         exit;
322                 }
323         };
324         if ($@)
325         {
326                 print "Configure update failed: $@\n";
327         }
328         exit;
329 }
330
331 sub modupdate
332 {
333         eval {
334                 chomp($topdir = getcwd());
335                 $this = resolve_directory($topdir);                                          # PWD, Regardless.
336                 getmodules();
337                 # Does the cache file exist?
338                 if (!getcache()) {
339                         # No, No it doesn't.. *BASH*
340                         print "You have not run ./configure before. Please do this before trying to run the update script.\n";
341                         exit 0;
342                 } else {
343                         # We've Loaded the cache file and all our variables..
344                         print "Updating Files..\n";
345                         getosflags();
346                         $has_epoll = $config{HAS_EPOLL};
347                         $has_kqueue = $config{HAS_KQUEUE};
348                         writefiles(0);
349                         makecache();
350                         print "Complete.\n";
351                         exit;
352                 }
353         };
354         if ($@)
355         {
356                 print "Module update failed: $@\n";
357         }
358         exit;
359 }
360
361
362
363 sub svnupdate
364 {
365         my $fail = 0;
366         open(FH,"<.svn/entries") or $fail = 1;
367         if ($fail) {
368                 print "This is not an SVN copy of InspIRCd.\n";
369                 exit;
370         }
371         else
372         {
373                 close(FH);
374         }
375         system("svn update");
376         system("perl configure -update");
377         if (defined $opt_rebuild) {
378                 system("make install");
379         }
380         exit;
381 }
382
383 print "Running non-interactive configure...\n" unless $interactive;
384 print "Checking for cache from previous configure... ";
385 print ((getcache() eq "true") ? "found\n" : "not found\n");
386 print "Checking operating system version... ";
387 print getosflags() . "\n";
388
389 if (defined $opt_maxclients)
390 {
391         $config{MAX_CLIENT} = $opt_maxclients;
392 }
393
394 if (!$config{MAX_CLIENT}) { 
395         # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
396         # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
397         # higher than the found value" :))
398         $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
399 }
400
401 printf "Checking if stdint.h exists... ";
402 $config{HAS_STDINT} = "true";
403 my $fail = 0;
404 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
405 if ($config{HAS_STDINT} eq "true") {
406         close(STDINT);
407 }
408 print "yes\n" if $config{HAS_STDINT} eq "true";
409 print "no\n" if $config{HAS_STDINT} eq "false";
410
411
412 printf "Checking if strlcpy exists... ";
413 # Perform the strlcpy() test..
414 $config{HAS_STRLCPY} = "false";
415 my $fail = 0;
416 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
417 if (!$fail) {
418         while (chomp($line = <STRLCPY>)) {
419                 # try and find the delcaration of:
420                 # size_t strlcpy(...)
421                 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
422                         $config{HAS_STRLCPY} = "true";
423                 }
424         }
425         close(STRLCPY);
426 }
427 print "yes\n" if $config{HAS_STRLCPY} eq "true";
428 print "no\n" if $config{HAS_STRLCPY} eq "false";
429
430
431 printf "Checking if kqueue exists... ";
432 $has_kqueue = 0;
433 $fail = 0;
434 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
435 if (!$fail) {
436         while (chomp($line = <KQUEUE>)) {
437                 # try and find the delcaration of:
438                 # int kqueue(void);
439                 if ($line =~ /int(\0x9|\s)+kqueue/) {
440                         $has_kqueue = 1;
441                 }
442         }
443         close(KQUEUE);
444 }
445 print "yes\n" if $has_kqueue == 1;
446 print "no\n" if $has_kqueue == 0;
447
448 printf "Checking if epoll exists... ";
449 $has_epoll = 0;
450 $fail = 0;
451 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
452 if (!$fail) {
453         $has_epoll = 1;
454         close(EPOLL);
455 }
456 if ($has_epoll) {
457         my $kernel = `uname -r`;
458         chomp($kernel);
459         if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
460                 $has_epoll = 0;
461         }
462 }
463 print "yes\n" if $has_epoll == 1;
464 print "no\n" if $has_epoll == 0;
465
466 if (($config{OSNAME} =~ /CYGWIN/) || ($config{OSNAME} eq "CYG-STATIC")) {
467         $config{HAS_STRLCPY} = "true";
468 }
469
470 $config{HAS_EPOLL} = $has_epoll;
471 $config{HAS_KQUEUE} = $has_kqueue; 
472
473 printf "Checking for libgnutls... ";
474 if (($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS} >= 1.2) || ($config{HAS_GNUTLS} eq "y"))) {
475         print "yes\n";
476         $config{HAS_GNUTLS} = "y";
477 } else {
478         print "no\n";
479         $config{HAS_GNUTLS} = "n";
480 }
481
482 printf "Checking for openssl... ";
483 if (($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL} >= 0.8) || ($config{HAS_OPENSSL} eq "y"))) {
484         print "yes\n";
485         $config{HAS_OPENSSL} = "y";
486 } else {
487         print "no\n";
488         $config{HAS_OPENSSL} = "n";
489 }
490
491 ################################################################################
492 #                         BEGIN INTERACTIVE PART                              #
493 ################################################################################
494
495 # Clear the Screen..
496 if ($interactive)
497 {
498         system("clear");
499         $wholeos = $^O;
500
501         my $rev = getrevision();
502         # Display Introduction Message..
503         print "
504 Welcome to the \033[1mInspIRCd\033[0m Configuration program! (\033[1minteractive mode\033[0m)
505 \033[1mPackage maintainers: Type ./configure --help for non-interactive help\033[0m
506
507 *** If you are unsure of any of these values, leave it blank for    ***
508 *** standard settings that will work, and your server will run      ***
509 *** using them. Please consult your IRC network admin if in doubt.  ***
510
511 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
512 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
513 dir, otherwise you won't have a config file!
514
515 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos)
516 Maximum file descriptors: \033[1;32m$config{MAX_CLIENT_T}\033[0m
517 Your InspIRCd revision ID is \033[1;32mr$rev\033[0m";
518         if ($rev eq "r0") {
519                 print " (Non-SVN build)";
520         }
521         print ".\n\n";
522
523         $config{CHANGE_COMPILER} = "n";
524         print "I have detected the following compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
525
526         while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
527                 print "\033[1;32mIMPORTANT!\033[0m A GCC 2.x compiler has been detected, and
528 should NOT be used. You should probably specify a newer compiler.\n\n";
529                 yesno(CHANGE_COMPILER,"Do you want to change the compiler?");
530                 if ($config{CHANGE_COMPILER} =~ /y/i) {
531                         print "What command do you want to use to invoke your compiler?\n";
532                         print "[\033[1;32m$config{CC}\033[0m] -> ";
533                         chomp($config{CC} = <STDIN>);
534                         if ($config{CC} eq "") {
535                                 $config{CC} = "g++";
536                         }
537                         chomp($foo = `$config{CC} -dumpversion | cut -c 1`);
538                         if ($foo ne "") {
539                                 chomp($config{GCCVER}       = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
540                                 print "Queried compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
541                                 if ($config{GCCVER} < 3) {
542                                         print "\033[1;32mGCC 2.x WILL NOT WORK!\033[0m. Let's try that again, shall we?\n";
543                                 }
544                         }
545                         else {
546                                 print "\033[1;32mWARNING!\033[0m Could not execute the compiler you specified. You may want to try again.\n";
547                         }
548                 }
549         }
550
551         print "\n";
552
553         # Directory Settings..
554         my $tmpbase = $config{BASE_DIR};
555         dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
556         if ($tmpbase ne $config{BASE_DIR}) {
557                 $config{CONFIG_DIR}      = resolve_directory($config{BASE_DIR}."/conf");           # Configuration Dir
558                 $config{MODULE_DIR}      = resolve_directory($config{BASE_DIR}."/modules");     # Modules Directory
559                 $config{BINARY_DIR}      = resolve_directory($config{BASE_DIR}."/bin");     # Binary Directory
560                 $config{LIBRARY_DIR}    = resolve_directory($config{BASE_DIR}."/lib");      # Library Directory
561         }
562
563         dir_check("are the configuration files", "CONFIG_DIR");
564         dir_check("are the modules to be compiled to", "MODULE_DIR");
565         dir_check("is the IRCd binary to be placed", "BINARY_DIR");
566         dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
567
568         if ($has_kqueue) {
569                 yesno(USE_KQUEUE,"You are running a BSD operating system, and kqueue\nwas detected. Would you like to enable kqueue support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable kqueue?");
570                 print "\n";
571         }
572         if ($has_epoll) {
573                 yesno(USE_EPOLL,"You are running a Linux 2.6+ operating system, and epoll\nwas detected. Would you like to enable epoll support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable epoll?");
574                 print "\n";
575         }
576         $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y"));
577         if (!$chose_hiperf) {
578                 print "No high-performance socket engines are available, or you chose\n";
579                 print "not to enable one. Defaulting to select() engine.\n\n";
580         }
581
582         yesno(IPV6,"Would you like to build InspIRCd with IPv6 support?");
583         print "\n";
584
585         if ($config{IPV6} eq "y") {
586                 print "You have chosen to build an \033[1;32mIPV6-only\033[0m server.\nTo accept IPV4 users, you must use the '::ffff:' notation of addresses.\n\n";
587                 $config{SUPPORT_IP6LINKS} = "y";
588         } else {
589                 yesno(SUPPORT_IP6LINKS,"You have chosen to build an \033[1;32mIPV4-only\033[0m server.\nWould you like to enable support for linking to IPV6-enabled\nInspIRCd servers which are using '::ffff:' notation?\nIf you are using a recent operating\nsystem and are unsure, answer yes.");
590                 print "\n";
591         }
592
593         if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
594                 print "I have detected both GnuTLS and OpenSSL on your system.\n";
595                 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
596                 print "instead, you should enable the OpenSSL module yourself\n";
597                 print "by copying it from src/modules/extra to src/modules.\n\n";
598         }
599
600         if ($config{HAS_GNUTLS} eq "y") {
601                 yesno(USE_GNUTLS, "Would you like to enable SSL Support?");
602                 if ($config{USE_GNUTLS} eq "y") {
603                         print "\nUsing GnuTLS SSL module.\n";
604                 }
605         } elsif ($config{HAS_OPENSSL} eq "y") {
606                         yesno(USE_OPENSSL, "Would you like to enable SSL Support?");
607         if ($config{USE_OPENSSL} eq "y") {
608                         print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
609                 }
610         }
611
612         print "\nThe following questions will ask you for various figures relating\n";
613         print "To your IRCd install. Please note that these should usually be left\n";
614         print "as defaults unless you have a real reason to change them. If they\n";
615         print "changed, then the values must be identical on all servers on your\n";
616         print "network, or malfunctions and/or crashes may occur, with the exception\n";
617         print "of the 'maximum number of clients' setting which may be different on\n";
618         print "different servers on the network.\n\n";
619
620         # File Descriptor Settings..
621         promptnumeric("number of clients at any one time", "MAX_CLIENT_T");
622         $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
623         $config{MAX_DESCRIPTORS} = $config{MAX_CLIENT_T};
624
625         promptnumeric("length of nicknames", "NICK_LENGT");
626         promptnumeric("length of channel names", "CHAN_LENGT");
627         promptnumeric("number of channels a normal user may join at any one time", "MAX_CHANNE");
628         promptnumeric("number of channels an oper may join at any one time", "MAX_OPERCH");
629         promptnumeric("number of mode changes in one line", "MAXI_MODES");
630         promptnumeric("length of an ident (username)", "MAX_IDENT");
631         promptnumeric("length of a quit message", "MAX_QUIT");
632         promptnumeric("length of a channel topic", "MAX_TOPIC");
633         promptnumeric("length of a kick message", "MAX_KICK");
634         promptnumeric("length of a GECOS (real name)", "MAX_GECOS");
635         promptnumeric("length of an away message", "MAX_AWAY");
636 }
637
638 dumphash();
639
640 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
641 {
642         print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
643         exit(0);
644 }
645 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
646 {
647         print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
648         exit(0);
649 }
650
651 if ($config{USE_GNUTLS} eq "y") {
652         $failed = 0;
653         open(TMP, "<src/modules/m_ssl_gnutls.cpp") or $failed = 1;
654         close(TMP);
655         if ($failed) {
656                 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
657                 chdir("src/modules");
658                 system("ln -s extra/m_ssl_gnutls.cpp");
659                 chdir("../..");
660         }
661         getmodules();
662         if ($interactive)
663         {
664                 $failed = 0;
665                 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
666                 close(TMP);
667                 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
668                 close(TMP);
669                 if ($failed) {
670                         print "SSL Certificates Not found, Generating.. \n\n
671 *************************************************************
672 * Generating the Private Key may take some time, go grab a  *
673 * Coffee. Even better, to generate some more entropy if it  *
674 * is taking a while, open another console and type du / a   *
675 * few times and get that HD going :) Then answer the    *
676 * Questions which follow. If you are unsure, just hit enter *
677 *************************************************************\n\n";
678                         system("certtool --generate-privkey --outfile key.pem");
679                         system("certtool --generate-self-signed --load-privkey key.pem --outfile cert.pem");
680                         print "\nCertificate generation complete, copying to config directory... ";
681                         system("mv key.pem $config{CONFIG_DIR}/key.pem");
682                         system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
683                         print "Done.\n\n";
684                 } else {
685                         print "SSL Certificates found, skipping.\n\n"
686                 }
687         }
688         else
689         {
690                 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
691         }
692 } elsif ($config{USE_OPENSSL} eq "y") {
693         $failed = 0;
694         open(TMP, "<src/modules/m_ssl_openssl.cpp") or $failed = 1;
695         close(TMP);
696         if ($failed) {
697                 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
698                 chdir("src/modules");
699                 system("ln -s extra/m_ssl_openssl.cpp");
700                 chdir("../..");
701         }
702         getmodules();
703         $failed = 0;
704         if ($interactive)
705         {
706                 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
707                 close(TMP);
708                 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
709                 close(TMP);
710                 if ($failed) {
711                         print "SSL Certificates Not found, Generating.. \n\n
712 *************************************************************
713 * Generating the certificates may take some time, go grab a *
714 * coffee, or something.                              *
715 *************************************************************\n\n";
716                         system("openssl req -x509 -nodes -newkey rsa:1024 -keyout key.pem -out cert.pem");
717                         system("openssl dhparam -out dhparams.pem 1024");
718                         print "\nCertificate generation complete, copying to config directory... ";
719                         system("mv key.pem $config{CONFIG_DIR}/key.pem");
720                         system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
721                         system("mv dhparams.pem $config{CONFIG_DIR}/dhparams.pem");
722                         print "Done.\n\n";
723                 } else {
724                         print "SSL Certificates found, skipping.\n\n"
725                 }
726         }
727         else
728         {
729                 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
730         }
731 }
732 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
733         print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
734 }
735
736 getosflags();
737 writefiles(1);
738 makecache();
739
740 print "\n\n";
741 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
742 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
743         print "Please remember that to enable \033[1;32mSSL support\033[0m you must\n";
744         print "load the required modules in your config. This configure process\n";
745         print "has just prepared these modules to be compiled for you, and has not\n";
746         print "configured them to be compiled into the core of the ircd.\n";
747 }
748 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
749 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
750         print "\033[1;32mWARNING!\033[0m You are running OpenBSD but you are using the base gcc package\nrather than eg++. This compile will most likely fail, but i'm letting you\ngo ahead with it anyway, just in case i'm wrong :-)\n";
751 }
752
753 if ($config{GCCVER} < "3") {
754         print <<FOO2;
755 \033[1;32mWARNING!\033[0m You are attempting to compile InspIRCd on GCC 2.x!
756 GCC 2.x series compilers only had partial (read as broken) C++ support, and
757 your compile will most likely fail horribly! If you have any problems, do NOT
758 report them to the bugtracker or forums without first upgrading your compiler
759 to a newer 3.x or 4.x (or whatever is available currently) version.
760 FOO2
761 }
762
763 ################################################################################
764 #                             HELPER FUNCTIONS                          #
765 ################################################################################
766 sub getcache {
767         # Retrieves the .config.cache file, and loads values into the main config hash.
768         open(CACHE, ".config.cache") or return undef;
769         while (<CACHE>) {
770                 chomp;
771                 # Ignore Blank lines, and comments..
772                 next if /^\s*$/;
773                 next if /^\s*#/;
774                 my ($key, $value) = split("=", $_, 2);
775                 $value =~ /^\"(.*)\"$/;
776                 # Do something with data here!
777                 $config{$key} = $1;
778         }
779         close(CONFIG);
780         return "true";
781 }
782
783 sub makecache {
784         # Dump the contents of %config
785         print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
786         open(FILEHANDLE, ">.config.cache");
787         foreach $key (keys %config) {
788                 print FILEHANDLE "$key=\"$config{$key}\"\n";
789         }
790         close(FILEHANDLE);
791 }
792
793 sub dir_check {
794         my ($desc, $hash_key) = @_;
795         my $complete = 0;
796         while (!$complete) {
797                 print "In what directory $desc?\n";
798                 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
799                 chomp($var = <STDIN>);
800                 if ($var eq "") {
801                         $var = $config{$hash_key};
802                 }
803                 if ($var =~ /^\~\/(.+)$/) {
804                         # Convert it to a full path..
805                         $var = resolve_directory($ENV{HOME} . "/" . $1);
806                 }
807                 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
808                 {
809                         # Assume relative Path was given.. fill in the rest.
810                         $var = $this . "/$var";
811                 }
812                 
813                 $var = resolve_directory($var); 
814                 if (! -e $var) {
815                         print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
816                         chomp($tmp = <STDIN>);
817                         if (($tmp eq "") || ($tmp =~ /^y/i)) {
818                                 # Attempt to Create the Dir..
819                                 
820                                 system("mkdir -p \"$var\" >> /dev/null 2>&1");
821                                 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
822                                 if ($chk != 0) {
823                                         print "Unable to create directory. ($var)\n\n";
824                                         # Restart Loop..
825                                         next;
826                                 }
827                         } else {
828                                 # They said they don't want to create, and we can't install there.
829                                 print "\n\n";
830                                 next;
831                         }
832                 } else {
833                         if (!is_dir($var)) {
834                                 # Target exists, but is not a directory.
835                                 print "File $var exists, but is not a directory.\n\n";
836                                 next;
837                         }
838                 }
839                 # Either Dir Exists, or was created fine.
840                 $config{$hash_key} = $var;
841                 $complete = 1;
842                 print "\n";
843         }
844 }
845
846 sub getosflags {
847
848         $config{LDLIBS} = "-lstdc++";
849         $config{FLAGS}  = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual $config{OPTIMISATI}";
850         $config{DEVELOPER} = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual -g";
851         $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared";
852         $config{MAKEPROG} = "make";
853
854         if ($config{OSNAME} =~ /darwin/i) {
855                 $config{FLAGS}  = "-DDARWIN -frtti -fPIC -Wall -Woverloaded-virtual $config{OPTIMISATI}";
856                 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
857                 $config{LDLIBS} = "-ldl -lstdc++";
858         }
859
860         if ($config{OSNAME} =~ /OpenBSD/i) {
861                 $config{MAKEPROG} = "gmake";
862                 chomp($foo = `eg++ -dumpversion | cut -c 1`);
863                 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
864                 # if theyre not running this, configure lets the build continue but they probably wont manage to
865                 # compile as this standard version is 2.95.3!
866                 if ($foo ne "") {
867                         $config{CC} = "eg++";
868                         chomp($config{GCCVER}       = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
869                 }
870                 return "OpenBSD";
871         }
872
873         if ($config{OSNAME} =~ /Linux/i) {
874                 $config{LDLIBS} = "-ldl -lstdc++";
875                 $config{FLAGS}  = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual $config{OPTIMISATI}";
876                 $config{FLAGS}  .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
877                 $config{MAKEPROG} = "make";
878                 if ($config{OSNAME} =~ /CYGWIN/) {
879                         $config{FLAGS}  = "-fno-strict-aliasing -Wall -Woverloaded-virtual $config{OPTIMISATI}";
880                         $config{LDLIBS} = "";
881                         $config{MAKEPROG} = "/usr/bin/make";
882                         $config{MAKEORDER} = "ircd mods";
883                         return "Cygwin";
884                 } elsif ($config{OSNAME} eq "CYG-STATIC") {
885                         $config{FLAGS} = "-fno-strict-aliasing -Wall -Woverloaded-virtual $config{OPTIMISATI}";
886                         $config{LDLIBS} = "";
887                         $config{MAKEPROG} = "/usr/bin/make";
888                         $config{MAKEORDER} = "mods ircd";
889                         $config{STATICLIBS} = "modules/mods.a";
890                         $config{STATIC_LINK} = "yes";
891                         return "Cygwin-Static";
892                 }
893                 $config{FLAGS}  .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
894         }
895         
896         if ($config{OSNAME} =~ /SunOS/i)
897         {
898                 # solaris/sunos needs these
899                 # socket = bsd sockets api
900                 # nsl = dns stuff
901                 # rt = POSIX realtime extensions
902                 # resolv = inet_aton only (why isnt this in nsl?!)
903                 $config{MAKEPROG} = "gmake";
904                 $config{LDLIBS} = $config{LDLIBS} . " -lsocket -lnsl -lrt -lresolv";
905                 return "Solaris";
906         }
907         
908         if($config{OSNAME} =~ /MINGW32/i)
909         {
910                 # All code is position-independent on windows
911                 $config{FLAGS} =~ s/-fPIC //;
912                 return "MinGW";
913         }
914
915         return $config{OSNAME};
916 }
917
918 sub writefiles {
919         my($writeheader) = @_;
920         # First File.. inspircd_config.h
921         chomp(my $incos = `uname -n -s -r`);
922         chomp($version = `sh src/version.sh`);
923         chomp(my $revision2 = getrevision());
924         if ($writeheader == 1)
925         {
926                 print "Writing \033[1;32minspircd_config.h\033[0m\n";
927                 open(FILEHANDLE, ">include/inspircd_config.h");
928                 my $NL = $config{NICK_LENGT}+1;
929                 my $CL = $config{CHAN_LENGT}+1;
930                 print FILEHANDLE <<EOF;
931 /* Auto generated by configure, do not modify! */
932 #ifndef __CONFIGURATION_AUTO__
933 #define __CONFIGURATION_AUTO__
934
935 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
936 #define MOD_PATH "$config{MODULE_DIR}"
937 #define VERSION "$version"
938 #define REVISION "$revision2"
939 #define MAXCLIENTS $config{MAX_CLIENT}
940 #define MAXCLIENTS_S "$config{MAX_CLIENT}"
941 #define SOMAXCONN_S "$config{_SOMAXCONN}"
942 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
943 #define NICKMAX $NL
944 #define CHANMAX $CL
945 #define MAXCHANS $config{MAX_CHANNE}
946 #define OPERMAXCHANS $config{MAX_OPERCH}
947 #define MAXMODES $config{MAXI_MODES}
948 #define IDENTMAX $config{MAX_IDENT}
949 #define MAXQUIT $config{MAX_QUIT}
950 #define MAXTOPIC $config{MAX_TOPIC}
951 #define MAXKICK $config{MAX_KICK}
952 #define MAXGECOS $config{MAX_GECOS}
953 #define MAXAWAY $config{MAX_AWAY}
954 #define OPTIMISATION $config{OPTIMITEMP}
955 #define LIBRARYDIR "$config{LIBRARY_DIR}"
956 #define SYSTEM "$incos"
957 #define MAXBUF 514
958 EOF
959                 if ($config{OSNAME} =~ /SunOS/i) {
960                         print FILEHANDLE "#define IS_SOLARIS\n";
961                 }
962                 if ($config{OSNAME} =~ /CYGWIN/i) {
963                         print FILEHANDLE "#define IS_CYGWIN\n";
964                         print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE        1024\n#endif\n";
965                 }
966                 if ($config{OSNAME} =~ /MINGW32/i) {
967                         print FILEHANDLE "#define IS_MINGW\n";
968                 }
969                 if ($config{OSNAME} =~ /CYG-STATIC/i) {
970                         print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE    1024\n#endif\n";
971                 }
972                 if ($config{STATIC_LINK} eq "yes") {
973                         print FILEHANDLE "#define STATIC_LINK\n";
974                 }
975                 if ($config{GCCVER} >= 3) {
976                         print FILEHANDLE "#define GCC3\n";
977                 }
978                 if ($config{HAS_STRLCPY} eq "true") {
979                         print FILEHANDLE "#define HAS_STRLCPY\n";
980                 }
981                 if ($config{HAS_STDINT} eq "true") {
982                         print FILEHANDLE "#define HAS_STDINT\n";
983                 }
984                 if ($config{IPV6} =~ /y/i) {
985                         print FILEHANDLE "#define IPV6\n";
986                 }
987                 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
988                         print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
989                 }
990                 my $use_hiperf = 0;
991                 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
992                         print FILEHANDLE "#define USE_KQUEUE\n";
993                         $se = "socketengine_kqueue";
994                         $use_hiperf = 1;
995                 }
996                 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
997                         print FILEHANDLE "#define USE_EPOLL\n";
998                         $se = "socketengine_epoll";
999                         $use_hiperf = 1;
1000                 }
1001                 # user didn't choose either epoll or select for their OS.
1002                 # default them to USE_SELECT (ewwy puke puke)
1003                 if (!$use_hiperf) {
1004                         print FILEHANDLE "#define USE_SELECT\n";
1005                         $se = "socketengine_select";
1006                 }
1007                 print FILEHANDLE "\n#endif\n";
1008                 close(FILEHANDLE);
1009         }
1010
1011         if ($writeheader)
1012         {
1013                 open(FILEHANDLE, ">include/inspircd_se_config.h");
1014                 print FILEHANDLE <<EOF;
1015 /* Auto generated by configure, do not modify or commit to svn! */
1016 #ifndef __CONFIGURATION_SOCKETENGINE__
1017 #define __CONFIGURATION_SOCKETENGINE__
1018
1019 #include "$se.h"
1020
1021 #endif
1022 EOF
1023                 close(FILEHANDLE);
1024         }
1025
1026
1027         # Create a Modules List..
1028         my $modules = "";
1029         foreach $i (@modlist)
1030         {
1031                 if ($config{STATIC_LINK} eq "yes") {
1032                         $modules .= "m_".$i.".o ";
1033                 }
1034                 else {
1035                         $modules .= "m_".$i.".so ";
1036                 }
1037         }
1038         chomp($modules);   # Remove Redundant whitespace..
1039
1040         opendir(DIRHANDLE, "src/modules");
1041         foreach $name (sort readdir(DIRHANDLE)) {
1042                 if ($name =~ /^m_(.+?)$/) {
1043                         if (opendir(MDIRHANDLE, "src/modules/$name") != 0) {
1044                                 closedir(MDIRHANDLE);
1045                                 $modules .= "$name.so ";
1046                         }
1047                 }
1048         }
1049         closedir(DIRHANDLE);
1050
1051
1052         # Write all .in files.
1053         my $tmp = "";
1054         my $file = "";
1055         my $exe = "inspircd";
1056
1057         if ($config{OSNAME} =~ /CYGWIN/i) {
1058                 $exe = "inspircd.exe";
1059         }
1060
1061         opendir(DIRHANDLE, $this);
1062
1063         # Do this once here, and cache it in the .*.inc files,
1064         # rather than attempting to read src/version.sh from
1065         # compiled code -- we might not have the source to hand.
1066         # Fix for bug#177 by Brain.
1067
1068         chomp(my $version = `sh ./src/version.sh`);
1069         chomp(my $revision = getrevision());
1070         $version = "$version(r$revision)";
1071
1072         my $LIBEXT = "so";
1073         if ($config{IS_DARWIN} eq "YES")
1074         {
1075                 $LIBEXT = "dylib";
1076         }
1077         # We can actually parse any file starting with . and ending with .inc,
1078         # but right now we only parse .inspircd.inc to form './inspircd'
1079
1080         foreach $name (sort readdir(DIRHANDLE)) {
1081                 if ($name =~ /^\.(.+)\.inc$/) {
1082                         $file = $1;
1083                         # All .name.inc files need parsing!
1084                         $tmp = "";
1085                         open(FILEHANDLE, ".$file.inc");
1086                         while (<FILEHANDLE>) {
1087                                 $tmp .= $_;
1088                         }
1089                         close(FILEHANDLE);
1090
1091                         $tmp =~ s/\@CC\@/$config{CC}/;
1092                         $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
1093                         $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
1094                         $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/;
1095                         $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
1096                         $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/;
1097                         $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
1098                         $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
1099                         $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
1100                         $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
1101                         $tmp =~ s/\@LIBRARY_EXT\@/$LIBEXT/;
1102                         $tmp =~ s/\@MODULES\@/$modules/;
1103                         $tmp =~ s/\@EXECUTABLE\@/$exe/;
1104                         $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/;
1105                         $tmp =~ s/\@STATICLIBS\@/$config{STATICLIBS}/;
1106                         $tmp =~ s/\@VERSION\@/$version/;
1107
1108                         print "Writing \033[1;32m$file\033[0m\n";
1109                         open(FILEHANDLE, ">$file");
1110                         print FILEHANDLE $tmp;
1111                 }
1112         }
1113         closedir(DIRHANDLE);
1114
1115         # Make inspircd executable!
1116         chmod 0744, 'inspircd';
1117
1118         if ($config{STATIC_LINK} eq "yes") {
1119                 print "Writing static-build \033[1;32msrc/Makefile\033[0m\n";
1120                 write_static_makefile();
1121                 write_static_modules_makefile();
1122         } elsif ($config{OSNAME} =~ /CYGWIN/i) {
1123                 print "Writing cygwin-build \033[1;32msrc/Makefile\033[0m\n";
1124                 write_static_makefile();
1125                 write_dynamic_modules_makefile();
1126         } else {
1127                 print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n";
1128                 write_dynamic_makefile();
1129                 write_dynamic_modules_makefile();
1130         }
1131 }
1132
1133 sub write_static_modules_makefile {
1134         # Modules Makefile..
1135         print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1136         open(FILEHANDLE, ">src/modules/Makefile");
1137
1138         ###
1139         # Module Makefile Header
1140         ###
1141         print FILEHANDLE <<EOF;
1142 # (C) ChatSpike development team
1143 # Makefile by <Craig\@ChatSpike.net>
1144 # Many Thanks to Andrew Church <achurch\@achurch.org>
1145 #    for assisting with making this work right.
1146 #
1147 # Automatically Generated by ./configure to add a modules
1148 # please run ./configure --update
1149
1150 all: \$(MODULES)
1151
1152 EOF
1153         ###
1154         # End Module Makefile Header
1155         ###
1156
1157         # Create a Modules List..
1158         my $modules = "";
1159         my $cmflags = "";
1160         my $liflags = "";
1161
1162         open(MODLIST,">include/modlist.h");
1163
1164         ###
1165         # Include File Header
1166         ###
1167         print MODLIST <<HEADER;
1168 // Generated automatically by configure. DO NOT EDIT!
1169
1170 #ifndef __SYMBOLS__H_CONFIGURED__
1171 #define __SYMBOLS__H_CONFIGURED__
1172
1173 HEADER
1174         ###
1175         # End Include File Header
1176         ###
1177
1178         # Place Module List into Include
1179         foreach $i (@modlist) {
1180                 if ($i !~ /_static$/) {
1181                         print MODLIST "extern \"C\" void * $i\_init (void);\n";
1182                 }
1183         }
1184         print MODLIST "\nstruct {const char *name; initfunc *value; } modsyms[] = {\n";
1185
1186         ###
1187         # Build Module Crap
1188         ###
1189         foreach $i (@modlist)
1190         {
1191                 if ($i !~ /_static$/) {
1192                         $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1193                         $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1194                         $deps = getdependencies("src/modules/m_".$i.".cpp");
1195
1196                         #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1197
1198                         ###
1199                         # Write Entry to the Makefile
1200                         ###
1201                         print FILEHANDLE <<EOCHEESE;
1202 m_$i.o: .m_$i\_static.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h $deps
1203         \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c .m_$i\_static.cpp
1204         mv .m_$i\_static.o ../m_$i.o
1205
1206 EOCHEESE
1207                         ###
1208                         # End Write Entry to the MakeFile
1209                         ###
1210                         print "Configuring module [\033[1;32mm_$i.so\033[0m] for static linking... ";
1211                         open(MODULE,"<src/modules/m_".$i.".cpp") or die("Could not open m_".$i.".cpp");
1212                         open(MUNGED,">src/modules/.m_".$i."_static.cpp") or die("Could not create .m_".$i."_static.cpp");
1213                         while (chomp($a = <MODULE>)) { 
1214                                 $a =~ s/init_module/$i\_init/g;
1215                                 print MUNGED "$a\n";
1216                         }
1217                         close(MODULE);
1218                         close(MUNGED);
1219                         print MODLIST <<EOENT;
1220 {"m_$i.so",\&$i\_init},
1221 EOENT
1222                         print "done\n";
1223                 }
1224         }
1225
1226         print MODLIST "{0}};\n\n#endif\n";
1227         close(MODLIST);
1228 }
1229
1230 sub write_dynamic_modules_makefile {
1231         # Modules Makefile..
1232         print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1233         open(FILEHANDLE, ">src/modules/Makefile");
1234         my $extra = "";
1235
1236         if ($config{OSNAME} =~ /CYGWIN/i) {
1237                 $extra = "../inspircd.dll.a";
1238         }
1239
1240 ###
1241 # Module Makefile Header
1242 ###
1243         print FILEHANDLE <<EOF;
1244 # (C) ChatSpike development team
1245 # Makefile by <Craig\@ChatSpike.net>
1246 # Many Thanks to Andrew Church <achurch\@achurch.org>
1247 #    for assisting with making this work right.
1248 #
1249 # Automatically Generated by ./configure to add a modules
1250 # please run ./configure -update or ./configure -modupdate
1251
1252 all: \$(MODULES)
1253
1254 EOF
1255         ###
1256         # End Module Makefile Header
1257         ###
1258
1259         # Create a Modules List..
1260         my $modules = "";
1261         my $cmflags = "";
1262         my $liflags = "";
1263         my $crud = "";
1264
1265         foreach $i (@modlist) {
1266                 ###
1267                 # Write Entry to the MakeFile
1268                 ###
1269                 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1270                 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1271                 $deps = getdependencies("src/modules/m_".$i.".cpp");
1272         
1273                 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1274         
1275                 print FILEHANDLE <<EOCHEESE;
1276 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h ../../include/inspircd_config.h ../../include/inspircd.h ../../include/configreader.h $deps
1277         \$(CC) -pipe -I../../include \$(FLAGS) $cmflags -export-dynamic -c m_$i.cpp
1278 EOCHEESE
1279
1280 if ($config{OSNAME} =~ /darwin/) {
1281                 print FILEHANDLE <<EOCHEESE;
1282         \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) -bundle $liflags -o m_$i.so m_$i.o $extra
1283
1284 EOCHEESE
1285 } else {
1286                 print FILEHANDLE <<EOCHEESE;
1287         \$(CC) -pipe \$(FLAGS) -shared $liflags -o m_$i.so m_$i.o $extra
1288
1289 EOCHEESE
1290 }
1291                 $crud = $crud . "       install -m \$(INSTMODE) m_$i.so \$(MODPATH)\n";
1292 ###
1293                 # End Write Entry to the MakeFile
1294                 ###
1295         }
1296
1297         opendir(DIRHANDLE, "src/modules");
1298         foreach $name (sort readdir(DIRHANDLE)) {
1299                 if ($name =~ /^m_(.+?)$/) {
1300                         $crapola = "";
1301                         $crap3 = "";
1302                         # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1303                         if (opendir(MDIRHANDLE, "src/modules/$name") != 0) {
1304                                 print "Composing Makefile rules for directory \033[1;32m$name\033[0m... ";
1305                                 my $i = 0;
1306                                 print FILEHANDLE "$name.so: ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h ../../include/inspircd_config.h ../../include/inspircd.h ../../include/configreader.h"; 
1307                                 foreach $fname (sort readdir(MDIRHANDLE)) {
1308                                         if ($fname =~ /\.cpp$/) {
1309                                                 $cmflags = getcompilerflags("src/modules/$name/$fname");
1310                                                 $liflags = getlinkerflags("src/modules/$name/$fname");
1311                                                 $deps = getdependencies("src/modules/$name/$fname");
1312                                                 $oname = $fname;
1313                                                 $oname =~ s/\.cpp$/.o/g;
1314                                                 print FILEHANDLE " $name/$oname";
1315                                                 $crapola = $crapola .  "$name/$oname: $name/$fname ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h ../../include/inspircd_config.h ../../include/inspircd.h ../../include/configreader.h $deps\n";
1316                                                 $crapola = $crapola .  "        \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $name/$oname -c $name/$fname\n\n";
1317                                                 $crap3 = $crap3 . " $name/$oname";
1318                                                 $i++;
1319                                         }
1320                                 }
1321                                 print "(\033[1;32m$i files found\033[0m)\n";
1322                                 if ($config{IS_DARWIN} eq "YES") {
1323                                         print FILEHANDLE "\n    \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) -bundle -o $name.so $crap3\n"; 
1324                                 } else {
1325                                         print FILEHANDLE "\n    \$(CC) -pipe \$(FLAGS) -shared $liflags -o $name.so $crap3\n";
1326                                 }
1327                                 print FILEHANDLE "\n$crapola\n";
1328                                 closedir(MDIRHANDLE);
1329                                 $crud = $crud . "       install -m \$(INSTMODE) $name.so \$(MODPATH)\n";
1330                         }
1331                 }
1332         }
1333         closedir(DIRHANDLE);
1334
1335         print FILEHANDLE "modinst:\n    \@echo \"Installing modules...\"\n" . $crud;
1336 }
1337
1338
1339 sub write_static_makefile {
1340         open(FH,">src/Makefile") or die("Could not write src/Makefile!");
1341         my $i = 0;
1342         my @cmdlist = ();
1343         opendir(DIRHANDLE, "src");
1344         foreach $name (sort readdir(DIRHANDLE)) {
1345                 if ($name =~ /^cmd_(.+)\.cpp$/) {
1346                         $cmdlist[$i++] = $1;
1347                 }
1348         }
1349         closedir(DIRHANDLE);
1350         my $cmdobjs = "";
1351         my $srcobjs = "";
1352         foreach my $cmd (@cmdlist) {
1353                 $cmdobjs = $cmdobjs . "cmd_$cmd.o ";
1354                 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1355         }
1356         print FH <<EOM;
1357 # Insp Makefile :p
1358 #
1359 # (C) ChatSpike development team
1360 # Makefile by <Craig\@ChatSpike.net>
1361 # Makefile version 2 (statically linked core) by <brain\@inspircd.org>
1362 #
1363
1364 CC = im a cheezeball
1365
1366 CXXFLAGS = -I../include \${FLAGS}
1367 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1368 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1369
1370 EOM
1371
1372 $se = "socketengine_select";
1373 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1374         $se = "socketengine_kqueue";
1375 }       
1376 elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1377         $se = "socketengine_epoll";
1378 }
1379
1380         ###
1381         # This next section is for cygwin dynamic module builds.
1382         # Basically, what we do, is build the inspircd core as a library
1383         # then the main executable uses that. the library is capable of
1384         # loading / unloading the modules dynamically :)
1385         # Massive thanks to the guys on #cygwin @ irc.freenode.net for helping
1386         # make this work :)
1387         ###
1388
1389         if ($config{OSNAME} =~ /CYGWIN/i) {
1390                 print FH <<EOM;
1391 all: timer.o command_parse.o cull_list.o userprocess.o socketengine.o socket.o hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o snomasks.o inspircd.exe
1392
1393 inspircd.exe: inspircd.dll.a
1394         \$(CC) -o \$@ \$^
1395
1396 inspircd.dll inspircd.dll.a: inspircd.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o $cmdobjs  commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o hashcomp.o socket.o socketengine.o userprocess.o cull_list.o command_parse.o timer.o snomasks.o
1397         \$(CC) -shared -Wl,--out-implib=inspircd.dll.a -o inspircd.dll \$^
1398 EOM
1399         } else {
1400                 print FH <<EOM;
1401 all: timer.o command_parse.o cull_list.o userprocess.o socketengine.o socket.o hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o snomasks.o \$(MODULES) inspircd.exe
1402
1403 inspircd.exe: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/base.h
1404         \$(CC) -I../include \$(FLAGS) inspircd.cpp -o inspircd.exe \$(LDLIBS) channels.o mode.o xline.o inspstring.o dns.o base.o inspsocket.o configreader.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o hashcomp.o socket.o socketengine.o userprocess.o cull_list.o command_parse.o timer.o snomasks.o modes/modeclasses.a \$(MODULES)
1405 EOM
1406         }
1407
1408         print FH <<EOM;
1409
1410 cull_list.o: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h
1411         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1412
1413 snomasks.o: snomasks.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/channels.h
1414         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1415
1416 command_parse.o: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1417         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1418
1419 userprocess.o: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1420         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1421
1422 socketengine.o: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1423         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1424
1425 hashcomp.o: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1426         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1427
1428 helperfuncs.o: helperfuncs.cpp ../include/base.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1429         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1430
1431 channels.o: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1432         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1433
1434 mode.o: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(RELCPPFILES) modes/modeclasses.a
1435         \${MAKE} -C "modes" DIRNAME="src/modes" CC="\$(CC)" \$(MAKEARGS)
1436         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1437
1438 xline.o: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1439         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1440
1441 inspstring.o: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1442         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1443
1444 dns.o: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1445         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1446
1447 base.o: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1448         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1449
1450 configreader.o: configreader.cpp ../include/base.h ../include/configreader.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1451         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1452
1453 commands.o: commands.cpp ../include/base.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h $srcobjs
1454         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp $cmdobjs
1455
1456 dynamic.o: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1457         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1458
1459 users.o: users.cpp ../include/base.h ../include/users.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1460         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1461
1462 modules.o: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1463         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1464
1465 wildcard.o: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1466         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1467
1468 socket.o: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1469         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1470         
1471 inspsocket.o: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1472         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1473
1474 timer.o: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1475         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1476
1477 EOM
1478         foreach my $cmd (@cmdlist) {
1479                 print FH <<ITEM;
1480 cmd_$cmd.o: cmd_$cmd.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/commands/cmd_$cmd.h
1481         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1482 ITEM
1483         }
1484         close(FH);
1485 }
1486
1487 sub write_dynamic_makefile {
1488
1489         my $i = 0;
1490         my @cmdlist = ();
1491         opendir(DIRHANDLE, "src");
1492         foreach $name (sort readdir(DIRHANDLE)) {
1493                 if ($name =~ /^cmd_(.+)\.cpp$/) {
1494                         $cmdlist[$i++] = $1;
1495                 }
1496         }
1497         closedir(DIRHANDLE);
1498
1499         my $cmdobjs = "";
1500         my $srcobjs = "";
1501         foreach my $cmd (@cmdlist) {
1502                 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1503                 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1504         }
1505
1506         $se = "socketengine_select";
1507         if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1508                 $se = "socketengine_kqueue";
1509         }
1510         elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1511                 $se = "socketengine_epoll";
1512         }
1513
1514         open(FH,">src/Makefile") or die("Could not write src/Makefile");
1515         print FH <<EOM;
1516 # Insp Makefile :p
1517 #
1518 # (C) ChatSpike development team
1519 # Makefile by <Craig\@ChatSpike.net>
1520 # Makefile version 2 (dynamically linked core) by <brain\@inspircd.org>
1521 #
1522
1523 CC = im a cheezeball
1524
1525 CXXFLAGS = -I../include \${FLAGS}
1526 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1527 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1528
1529 EOM
1530
1531 if ($config{IS_DARWIN} eq "YES") {
1532         print FH <<EOM;
1533 all: libIRCDtimer.dylib libIRCDcull_list.dylib libIRCDuserprocess.dylib libIRCDsocketengine.dylib libIRCDsocket.dylib libIRCDhash.dylib libIRCDchannels.dylib libIRCDmode.dylib libIRCDxline.dylib libIRCDstring.dylib libIRCDasyncdns.dylib libIRCDbase.dylib libIRCDconfigreader.dylib libIRCDinspsocket.dylib libIRCDcommands.dylib libIRCDdynamic.dylib libIRCDusers.dylib libIRCDmodules.dylib libIRCDwildcard.dylib libIRCDhelper.dylib libIRCDcommand_parse.dylib libIRCDsnomasks.dylib inspircd
1534
1535 inspircd: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/socket.h $cmdobjs libIRCDtimer.dylib libIRCDcull_list.dylib libIRCDuserprocess.dylib libIRCDsocketengine.dylib libIRCDsocket.dylib libIRCDhash.dylib libIRCDchannels.dylib libIRCDmode.dylib libIRCDxline.dylib libIRCDstring.dylib libIRCDasyncdns.dylib libIRCDbase.dylib libIRCDconfigreader.dylib libIRCDinspsocket.dylib libIRCDsnomasks.dylib libIRCDcommands.dylib libIRCDdynamic.dylib libIRCDusers.dylib libIRCDmodules.dylib libIRCDwildcard.dylib libIRCDhelper.dylib libIRCDcommand_parse.dylib
1536         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd.cpp
1537         \$(CC) -pipe -dynamic -bind_at_load -L. -o inspircd \$(LDLIBS) inspircd.o libIRCDchannels.dylib libIRCDmode.dylib libIRCDxline.dylib libIRCDstring.dylib libIRCDasyncdns.dylib libIRCDbase.dylib libIRCDconfigreader.dylib libIRCDinspsocket.dylib libIRCDcommands.dylib libIRCDdynamic.dylib libIRCDusers.dylib libIRCDmodules.dylib libIRCDwildcard.dylib libIRCDhelper.dylib libIRCDhash.dylib libIRCDsocket.dylib libIRCDsocketengine.dylib libIRCDuserprocess.dylib libIRCDcull_list.dylib libIRCDcommand_parse.dylib libIRCDtimer.dylib libIRCDsnomasks.dylib
1538
1539 libIRCDsocketengine.dylib: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1540         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp
1541         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $se.cpp
1542         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDsocketengine.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDsocketengine.dylib socketengine.o $se.o
1543
1544 libIRCDsnomasks.dylib: snomasks.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/channels.h
1545         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1546         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDsnomasks.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDsnomasks.dylib snomasks.o
1547
1548 libIRCDcommand_parse.dylib: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1549         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1550         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDcommand_parse.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDcommand_parse.dylib command_parse.o
1551
1552 libIRCDcull_list.dylib: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h
1553         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1554         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDcull_list.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDcull_list.dylib cull_list.o
1555
1556 libIRCDuserprocess.dylib: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1557         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1558         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDuserprocess.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDuserprocess.dylib userprocess.o
1559
1560 libIRCDhash.dylib: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1561         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1562         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDhash.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDhash.dylib hashcomp.o
1563
1564 libIRCDhelper.dylib: helperfuncs.cpp ../include/base.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1565         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1566         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDhelper.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDhelper.dylib helperfuncs.o
1567
1568 libIRCDchannels.dylib: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1569         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1570         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDchannels.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDchannels.dylib channels.o
1571
1572 libIRCDmode.dylib: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(RELCPPFILES)
1573         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1574         \${MAKE} -C "modes" DIRNAME="src/modes" CC="\$(CC)" \$(MAKEARGS) CPPFILES="\$(CPPFILES)"
1575         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDmode.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDmode.dylib mode.o modes/modeclasses.a
1576
1577 libIRCDxline.dylib: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1578         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1579         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDxline.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDxline.dylib xline.o
1580
1581 libIRCDstring.dylib: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1582         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1583         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDstring.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDstring.dylib inspstring.o
1584
1585 libIRCDasyncdns.dylib: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1586         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1587         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDasyncdns.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDasyncdns.dylib dns.o
1588
1589 libIRCDbase.dylib: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1590         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1591         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDbase.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDbase.dylib base.o
1592
1593 libIRCDconfigreader.dylib: configreader.cpp ../include/base.h ../include/configreader.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1594         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1595         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDconfigreader.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDconfigreader.dylib configreader.o
1596
1597 libIRCDcommands.dylib: commands.cpp ../include/base.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1598         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
1599         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDcommands.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDcommands.dylib commands.o
1600
1601 libIRCDdynamic.dylib: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1602         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1603         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDdynamic.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDdynamic.dylib dynamic.o
1604
1605 libIRCDusers.dylib: users.cpp ../include/base.h ../include/users.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1606         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1607         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDusers.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDusers.dylib users.o
1608
1609 libIRCDmodules.dylib: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1610         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1611         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDmodules.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDmodules.dylib modules.o
1612
1613 libIRCDwildcard.dylib: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1614         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1615         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDwildcard.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDwildcard.dylib wildcard.o
1616
1617 libIRCDsocket.dylib: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1618         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1619         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDsocket.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDsocket.dylib socket.o
1620
1621 libIRCDinspsocket.dylib: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1622         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1623         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDinspsocket.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDinspsocket.dylib inspsocket.o
1624
1625 libIRCDtimer.dylib: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1626         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1627         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDtimer.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDtimer.dylib timer.o
1628
1629 EOM
1630
1631 } else {
1632
1633         print FH <<EOM;
1634 all: libIRCDtimer.so libIRCDcull_list.so libIRCDuserprocess.so libIRCDsocketengine.so libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so $cmdobjs libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDcommand_parse.so libIRCDsnomasks.so inspircd
1635
1636 inspircd: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/socket.h libIRCDtimer.so libIRCDcull_list.so libIRCDuserprocess.so libIRCDsocketengine.so libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so $cmdobjs libIRCDsnomasks.so libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDcommand_parse.so
1637         \$(CC) -pipe -I../include $extra -Wl,--rpath -Wl,$config{LIBRARY_DIR} \$(FLAGS) -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDhash.so libIRCDsocket.so libIRCDsocketengine.so libIRCDuserprocess.so libIRCDcull_list.so libIRCDcommand_parse.so libIRCDtimer.so libIRCDsnomasks.so
1638
1639 libIRCDsocketengine.so: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1640         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1641         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocketengine.so socketengine.o $se.o
1642
1643 libIRCDsnomasks.so: snomasks.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/channels.h
1644         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1645         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsnomasks.so snomasks.o
1646
1647 libIRCDcommand_parse.so: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1648         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1649         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommand_parse.so command_parse.o
1650
1651 libIRCDcull_list.so: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h
1652         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1653         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcull_list.so cull_list.o
1654
1655 libIRCDuserprocess.so: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1656         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1657         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDuserprocess.so userprocess.o
1658
1659 libIRCDhash.so: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1660         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1661         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhash.so hashcomp.o
1662
1663 libIRCDhelper.so: helperfuncs.cpp ../include/base.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1664         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1665         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhelper.so helperfuncs.o
1666
1667 libIRCDchannels.so: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1668         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1669         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDchannels.so channels.o
1670
1671 libIRCDmode.so: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(RELCPPFILES)
1672         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1673         \${MAKE} -C "modes" DIRNAME="src/modes" CC="\$(CC)" \$(MAKEARGS) CPPFILES="\$(CPPFILES)"
1674         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmode.so mode.o modes/modeclasses.a
1675
1676 libIRCDxline.so: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1677         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1678         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDxline.so xline.o
1679
1680 libIRCDstring.so: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1681         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1682         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDstring.so inspstring.o
1683
1684 libIRCDasyncdns.so: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1685         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1686         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDasyncdns.so dns.o
1687
1688 libIRCDbase.so: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1689         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1690         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDbase.so base.o
1691
1692 libIRCDconfigreader.so: configreader.cpp ../include/base.h ../include/configreader.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1693         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1694         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDconfigreader.so configreader.o
1695
1696 libIRCDcommands.so: commands.cpp ../include/base.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1697         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
1698         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommands.so commands.o
1699
1700 libIRCDdynamic.so: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1701         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1702         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDdynamic.so dynamic.o
1703
1704 libIRCDusers.so: users.cpp ../include/base.h ../include/users.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1705         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1706         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDusers.so users.o
1707
1708 libIRCDmodules.so: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1709         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1710         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmodules.so modules.o
1711
1712 libIRCDwildcard.so: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1713         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1714         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDwildcard.so wildcard.o
1715
1716 libIRCDsocket.so: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1717         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1718         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocket.so socket.o
1719
1720 libIRCDinspsocket.so: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1721         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1722         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDinspsocket.so inspsocket.o
1723
1724 libIRCDtimer.so: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1725         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1726         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDtimer.so timer.o
1727
1728 EOM
1729 }
1730         foreach my $cmd (@cmdlist) {
1731                 print FH <<ITEM;
1732 cmd_$cmd.so: cmd_$cmd.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/commands/cmd_$cmd.h
1733         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1734         \$(CC) -pipe $SHARED -o cmd_$cmd.so cmd_$cmd.o
1735
1736 ITEM
1737         }
1738         close(FH);
1739 }
1740