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