2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2007 The InspIRCd Development Team
6 # http://www.inspircd.org/wiki/index.php/Credits
8 # Licensed under GPL, please see the COPYING file
13 ###################################################
18 use warnings FATAL => qw(all);
22 $Data::Dumper::Sortkeys = 1;
23 $Data::Dumper::Useqq = 1;
30 # Utility functions for our buildsystem
34 use make::opensslcert;
36 ###############################################################################################
40 ###############################################################################################
42 # If you wish to ignore a dependency throughout the entire core, add it here.
45 "inspircd_win32wrapper.h", # windows has its own configure program
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.
51 our @immutabledeps = (
52 "inspircd_config.h", # auto re-generated by configure
56 ###############################################################################################
58 # NON-EDITABLE VARIABLES
60 ###############################################################################################
62 # List of commands that make up 'make install' and 'make deinstall'
64 our $install_list = "";
65 our $uninstall_list = "";
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.
73 # If you wish for a file to have special dependencies in the makefile, add an entry here.
74 # Auto populated by /* $ExtraDeps: */ instruction
76 our %specialdeps = ();
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
82 our %extrabuildlines = ();
84 # If you wish for a file to be linked against extra objects or arctives, insert them here.
85 # Auto populated by /* $ExtraObjects: */ instruction
87 our %extraobjects = ();
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
94 our %extrasources = ();
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,
103 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
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(); },
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) ||
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)
180 our $interactive = !$non_interactive;
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
188 $config{BASE_DIR} = $config{ME};
190 if (defined $opt_base_dir)
192 $config{BASE_DIR} = $opt_base_dir;
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
200 if (defined $opt_config_dir)
202 $config{CONFIG_DIR} = $opt_config_dir;
204 if (defined $opt_module_dir)
206 $config{MODULE_DIR} = $opt_module_dir;
208 if (defined $opt_binary_dir)
210 $config{BINARY_DIR} = $opt_binary_dir;
212 if (defined $opt_library_dir)
214 $config{LIBRARY_DIR} = $opt_library_dir;
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)
223 $config{USE_GNUTLS} = "y"; # Use gnutls.
225 $config{USE_OPENSSL} = "n"; # Use openssl.
226 if (defined $opt_use_openssl)
228 $config{USE_OPENSSL} = "y";
231 # no, let's not change these.
232 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
233 if (!defined $opt_disable_debug)
235 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
239 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
242 $config{NICK_LENGT} = "31"; # Default Nick Length
243 if (defined $opt_nick_length)
245 $config{NICK_LENGT} = $opt_nick_length;
247 $config{CHAN_LENGT} = "64"; # Default Channel Name Length
248 if (defined $opt_chan_length)
250 $config{CHAN_LENGT} = $opt_chan_length;
252 $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once.
253 if (defined $opt_modes)
255 $config{MAXI_MODES} = $opt_modes;
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)
262 $config{USE_KQUEUE} = "y";
264 if (defined $opt_nokqueue)
266 $config{USE_KQUEUE} = "n";
268 $config{USE_EPOLL} = "y"; # epoll enabled
269 if (defined $opt_epoll)
271 $config{USE_EPOLL} = "y";
273 if (defined $opt_noepoll)
275 $config{USE_EPOLL} = "n";
277 $config{USE_PORTS} = "y"; # epoll enabled
278 if (defined $opt_ports)
280 $config{USE_PORTS} = "y";
282 if (defined $opt_noports)
284 $config{USE_PORTS} = "n";
286 $config{IPV6} = "n"; # IPv6 support (experimental)
287 if (defined $opt_ipv6)
291 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
292 if (defined $opt_ipv6links)
294 $config{SUPPORT_IP6LINKS} = "y";
296 if (defined $opt_noipv6links)
298 $config{SUPPORT_IP6LINKS} = "n";
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)
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.
316 $config{CC} = "g++"; # C++ compiler
319 $config{CC} = $opt_cc;
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)
333 $config{MAX_IDENT} = $opt_ident;
335 if (defined $opt_quit)
337 $config{MAX_QUIT} = $opt_quit;
339 if (defined $opt_topic)
341 $config{MAX_TOPIC} = $opt_topic;
343 if (defined $opt_kick)
345 $config{MAX_KICK} = $opt_kick;
347 if (defined $opt_gecos)
349 $config{MAX_GECOS} = $opt_gecos;
351 if (defined $opt_away)
353 $config{MAX_AWAY} = $opt_away;
356 $config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/;
357 $config{HAS_OPENSSL} = $1;
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";
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
370 # Get and Set some important vars..
375 unlink(".config.cache");
378 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
383 chomp($topdir = getcwd());
384 $this = resolve_directory($topdir); # PWD, Regardless.
386 # Does the cache file exist?
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";
392 # We've Loaded the cache file and all our variables..
393 print "Updating files...\n";
395 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
397 print "Disabling debug information (-g).\n";
398 $config{OPTIMISATI} = "";
401 $has_epoll = $config{HAS_EPOLL};
402 $has_ports = $config{HAS_PORTS};
403 $has_kqueue = $config{HAS_KQUEUE};
412 print "Configure update failed: $@\n";
420 chomp($topdir = getcwd());
421 $this = resolve_directory($topdir); # PWD, Regardless.
423 # Does the cache file exist?
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";
429 # We've Loaded the cache file and all our variables..
430 print "Updating files...\n";
432 $has_epoll = $config{HAS_EPOLL};
433 $has_ports = $config{HAS_PORTS};
434 $has_kqueue = $config{HAS_KQUEUE};
443 print "Module update failed: $@\n";
453 open(FH,"<.svn/entries") or $fail = 1;
455 print "This is not an SVN copy of InspIRCd.\n";
462 system("svn update");
463 system("perl configure -update");
464 if (defined $opt_rebuild) {
465 system("make install");
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";
476 if (defined $opt_maxclients)
478 $config{MAX_CLIENT} = $opt_maxclients;
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};
488 printf "Checking if stdint.h exists... ";
489 $config{HAS_STDINT} = "true";
491 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
492 if ($config{HAS_STDINT} eq "true") {
495 print "yes\n" if $config{HAS_STDINT} eq "true";
496 print "no\n" if $config{HAS_STDINT} eq "false";
498 printf "Checking if strlcpy exists... ";
499 # Perform the strlcpy() test..
500 $config{HAS_STRLCPY} = "false";
502 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
504 while (defined(my $line = <STRLCPY>)) {
506 # try and find the delcaration of:
507 # size_t strlcpy(...)
508 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
509 $config{HAS_STRLCPY} = "true";
514 print "yes\n" if $config{HAS_STRLCPY} eq "true";
515 print "no\n" if $config{HAS_STRLCPY} eq "false";
517 printf "Checking if kqueue exists... ";
520 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
522 while (defiined(my $line = <KQUEUE>)) {
524 # try and find the delcaration of:
526 if ($line =~ /int(\0x9|\s)+kqueue/) {
532 print "yes\n" if $has_kqueue == 1;
533 print "no\n" if $has_kqueue == 0;
535 printf "Checking if epoll exists... ";
538 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
544 my $kernel = `uname -r`;
546 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
551 # Suggestion from nenolod, weed out odd systems which have glibc built
552 # against 2.4 kernels (ick)
553 my $kernel_arch = `uname -p`;
557 if ($kernel_arch =~ /x86_64/) {
558 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
561 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
565 while (defined(my $line = <FH>))
568 if ($line =~ /GNU C Library .* version (.*?) /)
571 $libcv =~ /(\d+\.\d+)/;
574 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
577 # Fix for some retarded libc builds, strip off >> and << etc.
578 $kernelv =~ /(\d+\.\d+)/;
586 printf "libc too old: $libcv... ";
591 printf "libc built against older kernel $kernelv... ";
596 print "yes\n" if $has_epoll == 1;
597 print "no\n" if $has_epoll == 0;
599 printf "Checking if Solaris I/O completion ports are available... ";
601 our $system = `uname -s`;
603 $has_ports = 1 if ($system eq "SunOS");
606 my $kernel = `uname -r`;
608 if (($kernel !~ /^5\.1./)) {
612 print "yes\n" if $has_ports == 1;
613 print "no\n" if $has_ports == 0;
615 $config{HAS_EPOLL} = $has_epoll;
616 $config{HAS_KQUEUE} = $has_kqueue;
618 printf "Checking for libgnutls... ";
619 if (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y")) {
621 $config{HAS_GNUTLS} = "y";
624 $config{HAS_GNUTLS} = "n";
627 printf "Checking for openssl... ";
628 if (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y")) {
630 $config{HAS_OPENSSL} = "y";
633 $config{HAS_OPENSSL} = "n";
636 printf "Checking if you are running an ancient, unsupported OS... ";
637 if ($config{OSNAME} =~ /FreeBSD/i)
639 my $version = `uname -r`;
640 if ($version =~ /^4\./)
642 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
645 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
646 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
651 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
657 print "no ($version)\n";
663 print "no ($config{OSNAME})\n";
666 ################################################################################
667 # BEGIN INTERACTIVE PART #
668 ################################################################################
676 my $rev = getrevision();
677 # Display Introduction Message..
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
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. ***
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!
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";
694 print " (Non-SVN build)";
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";
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 "") {
712 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
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";
721 print "\033[1;32mWARNING!\033[0m Could not execute the compiler you specified. You may want to try again.\n";
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
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");
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?");
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?");
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?");
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";
761 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
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";
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)");
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";
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";
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";
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";
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";
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};
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");
822 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
824 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
827 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
829 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
834 if ($config{USE_GNUTLS} eq "y") {
836 open(TMP, "<src/modules/m_ssl_gnutls.cpp") or $failed = 1;
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");
848 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
850 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
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();
863 print "\n\033[1;32mCertificate generation failed!\033[0m\n\n";
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");
872 print "SSL Certificates found, skipping.\n\n";
877 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
879 } elsif ($config{USE_OPENSSL} eq "y") {
881 open(TMP, "<src/modules/m_ssl_openssl.cpp") or $failed = 1;
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");
893 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
895 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
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";
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");
910 print "SSL Certificates found, skipping.\n\n"
915 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
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";
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";
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";
939 if ($config{GCCVER} < "3") {
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.
949 ################################################################################
951 ################################################################################
953 # Retrieves the .config.cache file, and loads values into the main config hash.
954 open(CACHE, ".config.cache") or return 0;
957 # Ignore Blank lines, and comments..
960 my ($key, $value) = split("=", $_, 2);
961 $value =~ /^\"(.*)\"$/;
962 # Do something with data here!
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";
980 my ($desc, $hash_key) = @_;
983 print "In what directory $desc?\n";
984 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
985 chomp(my $var = <STDIN>);
987 $var = $config{$hash_key};
989 if ($var =~ /^\~\/(.+)$/) {
990 # Convert it to a full path..
991 $var = resolve_directory($ENV{HOME} . "/" . $1);
993 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
995 # Assume relative Path was given.. fill in the rest.
996 $var = $this . "/$var";
999 $var = resolve_directory($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..
1006 system("mkdir -p \"$var\" >> /dev/null 2>&1");
1007 my $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
1009 print "Unable to create directory. ($var)\n\n";
1014 # They said they don't want to create, and we can't install there.
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";
1025 # Either Dir Exists, or was created fine.
1026 $config{$hash_key} = $var;
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";
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++";
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!
1056 $config{CC} = "eg++";
1057 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
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";
1070 if ($config{OSNAME} =~ /FreeBSD/i) {
1071 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1072 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1075 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1077 # solaris/sunos needs these
1078 # socket = bsd sockets api
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";
1087 if($config{OSNAME} =~ /MINGW32/i)
1089 # All code is position-independent on windows
1090 $config{FLAGS} =~ s/-fPIC //;
1094 return $config{OSNAME};
1097 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1100 my($writeheader) = @_;
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)
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__
1117 /* this is for windows support. */
1118 #define CoreExport /**/
1119 #define DllExport /**/
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}
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"
1142 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1144 if ($config{OSNAME} =~ /SunOS/i) {
1145 print FILEHANDLE "#define IS_SOLARIS\n";
1147 if ($config{OSNAME} =~ /MINGW32/i) {
1148 print FILEHANDLE "#define IS_MINGW\n";
1150 if ($config{GCCVER} >= 3) {
1151 print FILEHANDLE "#define GCC3\n";
1153 if ($config{HAS_STRLCPY} eq "true") {
1154 print FILEHANDLE "#define HAS_STRLCPY\n";
1156 if ($config{HAS_STDINT} eq "true") {
1157 print FILEHANDLE "#define HAS_STDINT\n";
1159 if ($config{IPV6} =~ /y/i) {
1160 print FILEHANDLE "#define IPV6\n";
1162 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1163 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1166 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1167 print FILEHANDLE "#define USE_KQUEUE\n";
1168 $se = "socketengine_kqueue";
1171 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1172 print FILEHANDLE "#define USE_EPOLL\n";
1173 $se = "socketengine_epoll";
1176 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1177 print FILEHANDLE "#define USE_PORTS\n";
1178 $se = "socketengine_ports";
1181 # user didn't choose either epoll or select for their OS.
1182 # default them to USE_SELECT (ewwy puke puke)
1184 print FILEHANDLE "#define USE_SELECT\n";
1185 $se = "socketengine_select";
1187 print FILEHANDLE "\n#endif\n";
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__
1199 #include "socketengines/$se.h"
1207 # Create a Modules List..
1209 foreach my $i (@modlist)
1211 $modules .= "m_".$i.".so ";
1213 chomp($modules); # Remove Redundant whitespace..
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";
1225 closedir(DIRHANDLE);
1228 # Write all .in files.
1231 my $exe = "inspircd";
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.
1238 chomp($version = `sh ./src/version.sh`);
1239 chomp(my $revision = getrevision());
1240 $version = "$version(r$revision)";
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'
1245 print "Writing \033[1;32mMakefiles\033[0m\n";
1246 write_dynamic_modules_makefile();
1247 write_dynamic_makefile();
1249 opendir(DIRHANDLE, $this);
1251 foreach my $name (sort readdir(DIRHANDLE)) {
1252 if ($name =~ /^\.(.+)\.inc$/) {
1255 # Bug #353, omit this on non-darwin
1256 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1258 # All .name.inc files need parsing!
1260 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1261 while (<FILEHANDLE>) {
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/;
1287 open(FILEHANDLE, ">$file");
1288 print FILEHANDLE $tmp;
1291 closedir(DIRHANDLE);
1293 # Make inspircd executable!
1294 chmod 0744, 'inspircd';
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");
1303 # Module Makefile Header
1305 print FILEHANDLE <<EOF;
1306 ###################################################
1307 # Copyright 2002-2007 The InspIRCd Development Team
1308 # http://www.inspircd.org/wiki/index.php/Credits
1310 # Thanks to Andrew Church <achurch\@achurch.org>
1311 # for assisting with making this work right.
1313 # Automatically Generated by ./configure to add a
1314 # modules please run ./configure -modupdate
1315 ###################################################
1321 if ($config{OSNAME} =~ /darwin/) {
1322 print FILEHANDLE <<EOCHEESE;
1324 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1328 print FILEHANDLE <<EOCHEESE;
1330 PICLDFLAGS = -fPIC -DPIC -shared
1336 # End Module Makefile Header
1339 # Create a Modules List..
1343 foreach my $i (@modlist) {
1345 # Write Entry to the MakeFile
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");
1351 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1354 my $nicerflags = $config{FLAGS};
1355 $nicerflags =~ s/-pedantic//g;
1357 if (nopedantic("src/modules/m_".$i.".cpp"))
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
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
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";
1374 # End Write Entry to the MakeFile
1378 opendir(DIRHANDLE, "src/modules");
1379 foreach my $name (sort readdir(DIRHANDLE)) {
1380 if ($name =~ /^m_(.+?)$/) {
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";
1393 print FILEHANDLE " \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1395 print FILEHANDLE "\n$mfrules\n";
1396 closedir(MDIRHANDLE);
1397 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1401 closedir(DIRHANDLE);
1404 sub read_module_directory {
1405 my ($dpath, $reldpath) = @_;
1407 if (opendir(MDIRHANDLE, $dpath) == 0) {
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");
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";
1423 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1424 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
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++.
1436 open (CPP, "<$file") or die("Can't open $file for reading!");
1441 foreach my $d (@ignoredeps)
1447 foreach my $dep (@immutabledeps)
1449 $immutable = $immutable . "../include/$dep ";
1451 $immutable =~ s/ $//g;
1453 while (defined(my $line = <CPP>))
1456 if ($line =~ /#include "(.+\.h)"/)
1458 if (!exists($dupe{$1}))
1460 $retlist = $retlist . "../include/$1 ";
1466 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1469 sub write_dynamic_makefile
1473 my %existing_install_list = ();
1474 opendir(DIRHANDLE, "src/commands");
1475 foreach my $name (sort readdir(DIRHANDLE))
1477 if ($name =~ /^cmd_(.+)\.cpp$/)
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";
1484 closedir(DIRHANDLE);
1488 $config{USE_EPOLL} = 0;
1492 $config{USE_KQUEUE} = 0;
1496 $config{USE_PORTS} = 0;
1499 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1501 print "Scanning \033[1;32m$dir\033[0m for core files ";
1502 opendir(DIRHANDLE, $dir);
1503 foreach my $name (sort readdir(DIRHANDLE))
1505 if ($name =~ /\.cpp$/)
1507 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1509 while (defined(my $line = <CPP>))
1512 if ($line =~ /\/\* \$Core: (\w+) \*\//i)
1514 $filelist{$name} = $1;
1516 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1518 $specialdeps{$name} = $1;
1520 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1522 $extraobjects{$name} = $1;
1524 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1526 $extrabuildlines{$name} = $1;
1528 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1530 $extrasources{$name} = $1;
1532 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1534 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1537 while (defined($line = <CPP>))
1540 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1541 last if ($line =~ /\/\* \$EndIf \*\//i);
1545 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1547 if (!exists($existing_install_list{$1}))
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";
1557 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1559 if (!exists($existing_install_list{$1}))
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";
1573 closedir(DIRHANDLE);
1577 my $freebsd4libs = $config{CRAQ};
1580 my $all_libsonly = "";
1586 if ($config{IS_DARWIN} eq "YES")
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 "
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) ";
1598 foreach my $cpp (sort keys %filelist)
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";
1605 $all = $all . "moo inspircd\n";
1607 $othercrap = $othercrap . " $all_libsonly\n\n";
1609 open(FH,">src/Makefile") or die("Could not write src/Makefile");
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)
1619 print FH "$all\n\n";
1621 my $deps = calcdeps("src/inspircd.cpp");
1622 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1623 print FH "$othercrap\n";
1625 foreach my $cpp (sort keys %filelist)
1627 my $thislib = $filelist{$cpp} . "." . $libraryext;
1631 $objs =~ s/\.cpp$/.o/;
1632 if (exists($extraobjects{$cpp}))
1634 $objs = $objs . " " . $extraobjects{$cpp};
1636 if (exists($extrasources{$cpp}))
1638 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1640 if ($config{IS_DARWIN} eq "YES")
1642 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1646 if (defined $opt_disablerpath)
1648 $libcrap = " -shared";
1652 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1655 $deps = calcdeps("src/$cpp");
1656 if (exists($extrasources{$cpp}))
1658 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1660 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1663 $deps = $deps . $d . " ";
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}))
1671 print FH " " . $extrabuildlines{$cpp} . "\n";
1673 print FH " \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1676 print FH "moo:\n \${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1678 # close main makefile
1682 # generate a list of .so
1683 foreach my $cmd (@cmdlist) {
1684 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1687 # and now reopen the commands makefile
1688 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1691 CXXFLAGS = -I../../include \${FLAGS}
1698 # now print the command file details.
1699 foreach my $cmd (@cmdlist) {
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
1707 #try build a .so, no intermediate .o
1708 # \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so
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