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 ###################################################
20 use warnings FATAL => qw(all);
24 $Data::Dumper::Sortkeys = 1;
25 $Data::Dumper::Useqq = 1;
34 # Utility functions for our buildsystem
38 use make::opensslcert;
40 ###############################################################################################
44 ###############################################################################################
46 # If you wish to ignore a dependency throughout the entire core, add it here.
49 "inspircd_win32wrapper.h", # windows has its own configure program
52 # If you wish for all files in the entire core to have a given dependency, insert it here.
53 # You should keep this to an absolute minimum to avoid rebuilds that are not neccessary.
55 our @immutabledeps = (
56 "inspircd_config.h", # auto re-generated by configure
60 ###############################################################################################
62 # NON-EDITABLE VARIABLES
64 ###############################################################################################
66 # List of commands that make up 'make install' and 'make deinstall'
68 our $install_list = "";
69 our $uninstall_list = "";
71 # This is a list of all files in the core. Each cpp file is mapped to a shared object file,
72 # whos file extension is omitted (these can vary from system to system). Auto detected by
73 # scanning the src/*.cpp files for files containing /* $Core: */ identifiers.
77 # If you wish for a file to have special dependencies in the makefile, add an entry here.
78 # Auto populated by /* $ExtraDeps: */ instruction
80 our %specialdeps = ();
82 # If you wish for a file to have extra make lines (in between the compile and link steps)
83 # then insert them here.
84 # Auto populated by /* $ExtraBuild: */ instruction
86 our %extrabuildlines = ();
88 # If you wish for a file to be linked against extra objects or arctives, insert them here.
89 # Auto populated by /* $ExtraObjects: */ instruction
91 our %extraobjects = ();
93 # If you wish to compile extra cpp sources into an object, define them here.
94 # NOTE: Certain cpp files such as the socket engines have a value auto calculated
95 # for this table so that their derived class is built.
96 # Auto populated by /* $ExtraSources: */ instruction
98 our %extrasources = ();
100 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_nick_length,
101 $opt_chan_length, $opt_maxclients, $opt_ports, $opt_epoll, $opt_kqueue, $opt_noports,
102 $opt_noepoll, $opt_nokqueue, $opt_disablerpath, $opt_ipv6, $opt_ipv6links,
103 $opt_noipv6links, $opt_ident, $opt_quit, $opt_topic, $opt_maxbuf, $opt_kick,
104 $opt_gecos, $opt_away, $opt_modes, $opt_disable_debug, $opt_maxchans,
107 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
112 sub enable_extras (@);
114 sub disable_extras (@);
116 my @opt_enableextras;
117 my @opt_disableextras;
120 'enable-gnutls' => \$opt_use_gnutls,
121 'rebuild' => \$opt_rebuild,
122 'enable-openssl' => \$opt_use_openssl,
123 'disable-interactive' => \$opt_nointeractive,
124 'with-nick-length=i' => \$opt_nick_length,
125 'with-channel-length=i' => \$opt_chan_length,
126 'with-max-clients=i' => \$opt_maxclients,
127 'enable-ports' => \$opt_ports,
128 'enable-epoll' => \$opt_epoll,
129 'enable-kqueue' => \$opt_kqueue,
130 'disable-ports' => \$opt_noports,
131 'disable-epoll' => \$opt_noepoll,
132 'disable-kqueue' => \$opt_nokqueue,
133 'disable-rpath' => \$opt_disablerpath,
134 'enable-ipv6' => \$opt_ipv6,
135 'enable-remote-ipv6' => \$opt_ipv6links,
136 'disable-remote-ipv6' => \$opt_noipv6links,
137 'with-cc=s' => \$opt_cc,
138 'with-ident-length=i' => \$opt_ident,
139 'with-quit-length=i' => \$opt_quit,
140 'with-topic-length=i' => \$opt_topic,
141 'with-maxbuf=i' => \$opt_maxbuf,
142 'with-kick-length=i' => \$opt_kick,
143 'with-gecos-length=i' => \$opt_gecos,
144 'with-away-length=i' => \$opt_away,
145 'with-max-modes=i' => \$opt_modes,
146 'prefix=s' => \$opt_base_dir,
147 'config-dir=s' => \$opt_config_dir,
148 'module-dir=s' => \$opt_module_dir,
149 'binary-dir=s' => \$opt_binary_dir,
150 'library-dir=s' => \$opt_library_dir,
151 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
152 'help' => sub { showhelp(); },
153 'modupdate' => sub { modupdate(); },
154 'update' => sub { update(); },
155 'svnupdate' => sub { svnupdate(); },
156 'clean' => sub { clean(); },
157 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
158 'enable-extras=s@' => \@opt_enableextras, # ^
159 'disable-extras=s@' => \@opt_disableextras, # ^
162 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
163 @opt_enableextras = split /,/, join(',', @opt_enableextras);
164 @opt_disableextras = split /,/, join(',', @opt_disableextras);
165 enable_extras(@opt_enableextras);
166 disable_extras(@opt_disableextras);
168 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
169 print "Run $0 -modupdate after you've done this to update the makefiles.\n";
173 our $non_interactive = (
174 (defined $opt_library_dir) ||
175 (defined $opt_base_dir) ||
176 (defined $opt_config_dir) ||
177 (defined $opt_module_dir) ||
178 (defined $opt_base_dir) ||
179 (defined $opt_binary_dir) ||
180 (defined $opt_nointeractive) ||
181 (defined $opt_away) ||
182 (defined $opt_gecos) ||
183 (defined $opt_kick) ||
184 (defined $opt_maxclients) ||
185 (defined $opt_modes) ||
186 (defined $opt_topic) ||
187 (defined $opt_quit) ||
188 (defined $opt_ident) ||
190 (defined $opt_ipv6) ||
191 (defined $opt_ipv6links) ||
192 (defined $opt_noipv6links) ||
193 (defined $opt_kqueue) ||
194 (defined $opt_epoll) ||
195 (defined $opt_ports) ||
196 (defined $opt_maxchans) ||
197 (defined $opt_opermaxchans) ||
198 (defined $opt_chan_length) ||
199 (defined $opt_nick_length) ||
200 (defined $opt_use_openssl) ||
201 (defined $opt_nokqueue) ||
202 (defined $opt_noepoll) ||
203 (defined $opt_noports) ||
204 (defined $opt_maxbuf) ||
205 (defined $opt_use_gnutls)
207 our $interactive = !$non_interactive;
209 chomp(our $topdir = getcwd());
210 our $this = resolve_directory($topdir); # PWD, Regardless.
211 our @modlist = (); # Declare for Module List..
212 our %config = (); # Initiate Configuration Hash..
213 $config{ME} = resolve_directory($topdir); # Present Working Directory
215 $config{BASE_DIR} = $config{ME};
217 if (defined $opt_base_dir)
219 $config{BASE_DIR} = $opt_base_dir;
222 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
223 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
224 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
225 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
227 if (defined $opt_config_dir)
229 $config{CONFIG_DIR} = $opt_config_dir;
231 if (defined $opt_module_dir)
233 $config{MODULE_DIR} = $opt_module_dir;
235 if (defined $opt_binary_dir)
237 $config{BINARY_DIR} = $opt_binary_dir;
239 if (defined $opt_library_dir)
241 $config{LIBRARY_DIR} = $opt_library_dir;
243 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
244 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version
245 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
246 chomp(our $openssl_ver = $config{HAS_OPENSSL});
247 $config{USE_GNUTLS} = "n";
248 if (defined $opt_use_gnutls)
250 $config{USE_GNUTLS} = "y"; # Use gnutls.
252 $config{USE_OPENSSL} = "n"; # Use openssl.
253 if (defined $opt_use_openssl)
255 $config{USE_OPENSSL} = "y";
258 # no, let's not change these.
259 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
260 if (!defined $opt_disable_debug)
262 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
266 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
269 $config{NICK_LENGT} = "31"; # Default Nick Length
270 if (defined $opt_nick_length)
272 $config{NICK_LENGT} = $opt_nick_length;
274 $config{CHAN_LENGT} = "64"; # Default Channel Name Length
275 if (defined $opt_chan_length)
277 $config{CHAN_LENGT} = $opt_chan_length;
279 $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once.
280 if (defined $opt_modes)
282 $config{MAXI_MODES} = $opt_modes;
284 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
285 $config{HAS_STDINT} = "false"; # stdint.h check
286 $config{USE_KQUEUE} = "y"; # kqueue enabled
287 if (defined $opt_kqueue)
289 $config{USE_KQUEUE} = "y";
291 if (defined $opt_nokqueue)
293 $config{USE_KQUEUE} = "n";
295 $config{USE_EPOLL} = "y"; # epoll enabled
296 if (defined $opt_epoll)
298 $config{USE_EPOLL} = "y";
300 if (defined $opt_noepoll)
302 $config{USE_EPOLL} = "n";
304 $config{USE_PORTS} = "y"; # epoll enabled
305 if (defined $opt_ports)
307 $config{USE_PORTS} = "y";
309 if (defined $opt_noports)
311 $config{USE_PORTS} = "n";
313 $config{IPV6} = "n"; # IPv6 support (experimental)
314 if (defined $opt_ipv6)
318 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
319 if (defined $opt_ipv6links)
321 $config{SUPPORT_IP6LINKS} = "y";
323 if (defined $opt_noipv6links)
325 $config{SUPPORT_IP6LINKS} = "n";
327 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`); # FD Limit
328 chomp($config{MAX_DESCRIPTORS} = `sh -c \"ulimit -n\"`); # Hard FD Limit
329 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
330 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
331 $config{OSNAME} = $^O; # Operating System Name
332 $config{IS_DARWIN} = "NO"; # Is OSX?
333 $config{STARTSCRIPT} = "inspircd"; # start script?
334 $config{DESTINATION} = "BASE"; # Is target path.
335 $config{EXTRA_DIR} = ""; # Is empty.
336 if ($config{OSNAME} =~ /darwin/i)
338 $config{IS_DARWIN} = "YES";
339 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
340 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
341 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
343 $config{CC} = "g++"; # C++ compiler
346 $config{CC} = $opt_cc;
348 our $exec = $config{CC} . " -dumpversion | cut -c 1";
349 chomp($config{GCCVER} = `$exec`); # Major GCC Version
350 $config{MAKEORDER} = "ircd mods"; # build order
351 $config{MAX_IDENT} = "12"; # max ident size
352 $config{MAX_QUIT} = "255"; # max quit message size
353 $config{MAX_TOPIC} = "307"; # max topic size
354 $config{MAX_KICK} = "255"; # max kick message size
355 $config{MAX_GECOS} = "128"; # max GECOS size
356 $config{MAX_AWAY} = "200"; # max AWAY size
357 $config{MAXBUF} = "512"; # Max buffer size
358 if (defined $opt_ident)
360 $config{MAX_IDENT} = $opt_ident;
362 if (defined $opt_quit)
364 $config{MAX_QUIT} = $opt_quit;
366 if (defined $opt_topic)
368 $config{MAX_TOPIC} = $opt_topic;
370 if (defined $opt_kick)
372 $config{MAX_KICK} = $opt_kick;
374 if (defined $opt_gecos)
376 $config{MAX_GECOS} = $opt_gecos;
378 if (defined $opt_away)
380 $config{MAX_AWAY} = $opt_away;
383 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
384 $config{HAS_OPENSSL} = $1;
386 $config{HAS_OPENSSL} = "";
389 if ($config{GCCVER} eq "") {
390 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
394 our $fd_scan_fail = "";
395 if (!$config{MAX_CLIENT_T}) {
396 $config{MAX_CLIENT_T} = 1024; # Set a reasonable 'Default'
397 $fd_scan_fail = "true"; # Used Later
400 # Get and Set some important vars..
405 unlink(".config.cache");
408 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
413 chomp($topdir = getcwd());
414 $this = resolve_directory($topdir); # PWD, Regardless.
416 # Does the cache file exist?
418 # No, No it doesn't.. *BASH*
419 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
422 # We've Loaded the cache file and all our variables..
423 print "Updating files...\n";
425 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
427 print "Disabling debug information (-g).\n";
428 $config{OPTIMISATI} = "";
431 $has_epoll = $config{HAS_EPOLL};
432 $has_ports = $config{HAS_PORTS};
433 $has_kqueue = $config{HAS_KQUEUE};
442 print "Configure update failed: $@\n";
450 chomp($topdir = getcwd());
451 $this = resolve_directory($topdir); # PWD, Regardless.
453 # Does the cache file exist?
455 # No, No it doesn't.. *BASH*
456 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
459 # We've Loaded the cache file and all our variables..
460 print "Updating files...\n";
462 $has_epoll = $config{HAS_EPOLL};
463 $has_ports = $config{HAS_PORTS};
464 $has_kqueue = $config{HAS_KQUEUE};
473 print "Module update failed: $@\n";
483 open(FH,"<.svn/entries") or $fail = 1;
485 print "This is not an SVN copy of InspIRCd.\n";
492 open my $fd, "-|", "svn update";
493 my $configurechanged = 0; # Needs ./configure -update
494 my $coredirchanged = 0; # Needs ./configure -update
495 my $moduledirchanged = 0; # Needs ./configure -modupdate
497 while (defined(my $line = <$fd>))
501 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
502 ($action, $file) = ($1, $2);
505 push @conflicted, $file;
506 if ($file eq "configure")
508 $configurechanged = 1;
510 if ($file =~ m#^src/modules#)
512 $moduledirchanged = 1;
514 elsif ($file =~ m#^src/#)
519 elsif ($action eq "U" || $action eq "G")
521 if ($file eq "configure")
523 $configurechanged = 1;
526 elsif ($action eq "A" || $action eq "D")
528 if ($file =~ m#^src/modules#)
530 $moduledirchanged = 1;
532 elsif ($file =~ m#^src/#)
538 unless (close $fd) # close() waits for exit and returns false if the command failed
542 print STDERR "Problem updating from SVN, please check above for errors\n";
546 print STDERR "Failed to run SVN: $!\n";
550 if (scalar(@conflicted) > 0)
552 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
553 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate", (($coredirchanged || $configurechanged) ? "" : "mod");
555 if ($configurechanged || $coredirchanged)
557 system("perl configure -update");
559 elsif ($moduledirchanged)
561 system("perl configure -modupdate");
565 print "No need to update Makefiles.\n";
567 if (defined $opt_rebuild) {
568 system("make install");
573 print "Running non-interactive configure...\n" unless $interactive;
574 print "Checking for cache from previous configure... ";
575 print ((!getcache()) ? "not found\n" : "found\n");
576 print "Checking operating system version... ";
577 print getosflags() . "\n";
579 if (defined $opt_maxclients)
581 $config{MAX_CLIENT} = $opt_maxclients;
584 if (!$config{MAX_CLIENT}) {
585 # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
586 # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
587 # higher than the found value" :))
588 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
591 printf "Checking if stdint.h exists... ";
592 $config{HAS_STDINT} = "true";
594 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
595 if ($config{HAS_STDINT} eq "true") {
598 print "yes\n" if $config{HAS_STDINT} eq "true";
599 print "no\n" if $config{HAS_STDINT} eq "false";
601 printf "Checking if strlcpy exists... ";
602 # Perform the strlcpy() test..
603 $config{HAS_STRLCPY} = "false";
605 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
607 while (defined(my $line = <STRLCPY>)) {
609 # try and find the delcaration of:
610 # size_t strlcpy(...)
611 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
612 $config{HAS_STRLCPY} = "true";
617 print "yes\n" if $config{HAS_STRLCPY} eq "true";
618 print "no\n" if $config{HAS_STRLCPY} eq "false";
620 printf "Checking if kqueue exists... ";
623 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
625 while (defined(my $line = <KQUEUE>)) {
627 # try and find the delcaration of:
629 if ($line =~ /int(\0x9|\s)+kqueue/) {
635 print "yes\n" if $has_kqueue == 1;
636 print "no\n" if $has_kqueue == 0;
638 printf "Checking if epoll exists... ";
641 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
647 my $kernel = `uname -r`;
649 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
654 # Suggestion from nenolod, weed out odd systems which have glibc built
655 # against 2.4 kernels (ick)
656 my $kernel_arch = `uname -p`;
660 if ($kernel_arch =~ /x86_64/) {
661 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
664 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
668 while (defined(my $line = <FH>))
671 if ($line =~ /GNU C Library .* version (.*?) /)
674 $libcv =~ /(\d+\.\d+)/;
677 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
680 # Fix for some retarded libc builds, strip off >> and << etc.
681 $kernelv =~ /(\d+\.\d+)/;
689 printf "libc too old: $libcv... ";
694 printf "libc built against older kernel $kernelv... ";
699 print "yes\n" if $has_epoll == 1;
700 print "no\n" if $has_epoll == 0;
702 printf "Checking if Solaris I/O completion ports are available... ";
704 our $system = `uname -s`;
706 $has_ports = 1 if ($system eq "SunOS");
709 my $kernel = `uname -r`;
711 if (($kernel !~ /^5\.1./)) {
715 print "yes\n" if $has_ports == 1;
716 print "no\n" if $has_ports == 0;
718 $config{HAS_EPOLL} = $has_epoll;
719 $config{HAS_KQUEUE} = $has_kqueue;
721 printf "Checking for libgnutls... ";
722 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
724 $config{HAS_GNUTLS} = "y";
727 $config{HAS_GNUTLS} = "n";
730 printf "Checking for openssl... ";
731 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
733 $config{HAS_OPENSSL} = "y";
736 $config{HAS_OPENSSL} = "n";
739 printf "Checking if you are running an ancient, unsupported OS... ";
740 if ($config{OSNAME} =~ /FreeBSD/i)
742 my $version = `uname -r`;
743 if ($version =~ /^4\./)
745 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
748 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
749 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
754 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
760 print "no ($version)\n";
766 print "no ($config{OSNAME})\n";
769 ################################################################################
770 # BEGIN INTERACTIVE PART #
771 ################################################################################
776 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
779 my $rev = getrevision();
780 # Display Introduction Message..
782 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
783 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
785 *** If you are unsure of any of these values, leave it blank for ***
786 *** standard settings that will work, and your server will run ***
787 *** using them. Please consult your IRC network admin if in doubt. ***
789 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
790 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
791 dir, otherwise you won't have a config file!
793 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
794 Maximum file descriptors: \e[1;32m$config{MAX_CLIENT_T}\e[0m
795 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
798 print " (Non-SVN build)";
802 $config{CHANGE_COMPILER} = "n";
803 print "I have detected the following compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
805 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
806 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
807 should NOT be used. You should probably specify a newer compiler.\n\n";
808 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
809 if ($config{CHANGE_COMPILER} =~ /y/i) {
810 print "What command do you want to use to invoke your compiler?\n";
811 print "[\e[1;32m$config{CC}\e[0m] -> ";
812 chomp($config{CC} = <STDIN>);
813 if ($config{CC} eq "") {
816 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
818 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
819 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
820 if ($config{GCCVER} < 3) {
821 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
825 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
832 # Directory Settings..
833 my $tmpbase = $config{BASE_DIR};
834 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
835 if ($tmpbase ne $config{BASE_DIR}) {
836 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
837 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
838 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
839 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
842 dir_check("are the configuration files", "CONFIG_DIR");
843 dir_check("are the modules to be compiled to", "MODULE_DIR");
844 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
845 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
848 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?");
852 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?");
856 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?");
859 my $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
860 if (!$chose_hiperf) {
861 print "No high-performance socket engines are available, or you chose\n";
862 print "not to enable one. Defaulting to select() engine.\n\n";
865 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
868 if ($config{IPV6} eq "y") {
869 print "You have chosen to build an \e[1;32mIPV6-enabled\e[0m server.\nTo accept IPV4 users, you can still use IPV4 addresses\nin your port bindings..\n\n";
870 $config{SUPPORT_IP6LINKS} = "y";
872 yesno('SUPPORT_IP6LINKS',"You have chosen to build an \e[1;32mIPV4-only\e[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)");
876 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
877 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
878 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
879 print "instead, you should enable the OpenSSL module yourself\n";
880 print "by copying it from src/modules/extra to src/modules.\n\n";
881 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
882 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
885 if ($config{HAS_GNUTLS} eq "y") {
886 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
887 if ($config{USE_GNUTLS} eq "y") {
888 print "\nUsing GnuTLS SSL module.\n";
890 } elsif ($config{HAS_OPENSSL} eq "y") {
891 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
892 if ($config{USE_OPENSSL} eq "y") {
893 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
897 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";
900 print "\nThe following questions will ask you for various figures relating\n";
901 print "To your IRCd install. Please note that these should usually be left\n";
902 print "as defaults unless you have a real reason to change them. If they\n";
903 print "changed, then the values must be identical on all servers on your\n";
904 print "network, or malfunctions and/or crashes may occur, with the exception\n";
905 print "of the 'maximum number of clients' setting which may be different on\n";
906 print "different servers on the network.\n\n";
908 # File Descriptor Settings..
909 promptnumeric("number of clients at any one time", "MAX_CLIENT_T");
910 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
911 $config{MAX_DESCRIPTORS} = $config{MAX_CLIENT_T};
913 promptnumeric("length of nicknames", "NICK_LENGT");
914 promptnumeric("length of channel names", "CHAN_LENGT");
915 promptnumeric("number of mode changes in one line", "MAXI_MODES");
916 promptnumeric("length of an ident (username)", "MAX_IDENT");
917 promptnumeric("length of a quit message", "MAX_QUIT");
918 promptnumeric("length of a channel topic", "MAX_TOPIC");
919 promptnumeric("length of a kick message", "MAX_KICK");
920 promptnumeric("length of a GECOS (real name)", "MAX_GECOS");
921 promptnumeric("length of an away message", "MAX_AWAY");
926 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
928 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
931 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
933 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
938 if ($config{USE_GNUTLS} eq "y") {
939 unless (-r "src/modules/m_ssl_gnutls.cpp") {
940 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
941 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
946 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
947 print "SSL Certificates Not found, Generating.. \n\n
948 *************************************************************
949 * Generating the Private Key may take some time, go grab a *
950 * Coffee. Even better, to generate some more entropy if it *
951 * is taking a while, open another console and type du / a *
952 * few times and get that HD going :) Then answer the *
953 * Questions which follow. If you are unsure, just hit enter *
954 *************************************************************\n\n";
955 $failed = make_gnutls_cert();
957 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
959 print "\nCertificate generation complete, copying to config directory... ";
960 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
961 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
966 print "SSL Certificates found, skipping.\n\n";
971 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
973 } elsif ($config{USE_OPENSSL} eq "y") {
974 unless (-r "src/modules/m_ssl_openssl.cpp") {
975 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
976 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
982 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
983 print "SSL Certificates Not found, Generating.. \n\n
984 *************************************************************
985 * Generating the certificates may take some time, go grab a *
986 * coffee, or something. *
987 *************************************************************\n\n";
989 print "\nCertificate generation complete, copying to config directory... ";
990 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
991 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
992 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
995 print "SSL Certificates found, skipping.\n\n"
1000 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
1003 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
1004 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
1012 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
1013 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
1014 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
1015 print "modules in your config. This configure script has added those modules to the\n";
1016 print "build process. For more info please refer to:\n";
1017 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
1019 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
1020 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
1021 print "\e[1;32mWARNING!\e[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";
1024 if ($config{GCCVER} < "3") {
1026 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
1027 GCC 2.x series compilers only had partial (read as broken) C++ support, and
1028 your compile will most likely fail horribly! If you have any problems, do NOT
1029 report them to the bugtracker or forums without first upgrading your compiler
1030 to a newer 3.x or 4.x (or whatever is available currently) version.
1034 ################################################################################
1035 # HELPER FUNCTIONS #
1036 ################################################################################
1038 # Retrieves the .config.cache file, and loads values into the main config hash.
1039 open(CACHE, ".config.cache") or return 0;
1042 # Ignore Blank lines, and comments..
1045 my ($key, $value) = split("=", $_, 2);
1046 $value =~ /^\"(.*)\"$/;
1047 # Do something with data here!
1055 # Dump the contents of %config
1056 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1057 open(FILEHANDLE, ">.config.cache");
1058 foreach my $key (keys %config) {
1059 print FILEHANDLE "$key=\"$config{$key}\"\n";
1065 my ($desc, $hash_key) = @_;
1067 while (!$complete) {
1068 print "In what directory $desc?\n";
1069 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1070 chomp(my $var = <STDIN>);
1072 $var = $config{$hash_key};
1074 if ($var =~ /^\~\/(.+)$/) {
1075 # Convert it to a full path..
1076 $var = resolve_directory($ENV{HOME} . "/" . $1);
1078 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1080 # Assume relative Path was given.. fill in the rest.
1081 $var = $this . "/$var";
1084 $var = resolve_directory($var);
1086 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1087 chomp(my $tmp = <STDIN>);
1088 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1089 # Attempt to Create the Dir..
1092 File::Path::mkpath($var, 0, 0777);
1095 unless (defined($chk) && -d $var) {
1096 print "Unable to create directory. ($var)\n\n";
1101 # They said they don't want to create, and we can't install there.
1106 if (!is_dir($var)) {
1107 # Target exists, but is not a directory.
1108 print "File $var exists, but is not a directory.\n\n";
1112 # Either Dir Exists, or was created fine.
1113 $config{$hash_key} = $var;
1123 # Beware: Linux sets it's own cflags below for some retarded reason
1124 $config{LDLIBS} = "-pthread -lstdc++";
1125 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1126 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -g";
1127 $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared" unless defined $opt_disablerpath;
1128 $config{MAKEPROG} = "make";
1130 if ($config{OSNAME} =~ /darwin/i) {
1131 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1132 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1133 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1136 if ($config{OSNAME} =~ /OpenBSD/i) {
1137 $config{MAKEPROG} = "gmake";
1138 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1139 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1140 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1141 # if theyre not running this, configure lets the build continue but they probably wont manage to
1142 # compile as this standard version is 2.95.3!
1144 $config{CC} = "eg++";
1145 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1150 if ($config{OSNAME} =~ /Linux/i) {
1151 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1152 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1153 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1154 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1155 $config{MAKEPROG} = "make";
1158 if ($config{OSNAME} =~ /FreeBSD/i) {
1159 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1160 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1163 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1165 # solaris/sunos needs these
1166 # socket = bsd sockets api
1168 # rt = POSIX realtime extensions
1169 # resolv = inet_aton only (why isnt this in nsl?!)
1170 $config{MAKEPROG} = "gmake";
1171 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1175 if($config{OSNAME} =~ /MINGW32/i)
1177 # All code is position-independent on windows
1178 $config{FLAGS} =~ s/-fPIC //;
1182 return $config{OSNAME};
1185 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1188 my($writeheader) = @_;
1190 # First File.. inspircd_config.h
1191 chomp(my $incos = `uname -n -s -r`);
1192 chomp(my $version = `sh src/version.sh`);
1193 chomp(my $revision2 = getrevision());
1194 if ($writeheader == 1)
1196 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1197 open(FILEHANDLE, ">include/inspircd_config.h");
1198 my $NL = $config{NICK_LENGT}+1;
1199 my $CL = $config{CHAN_LENGT}+1;
1200 print FILEHANDLE <<EOF;
1201 /* Auto generated by configure, do not modify! */
1202 #ifndef __CONFIGURATION_AUTO__
1203 #define __CONFIGURATION_AUTO__
1205 /* this is for windows support. */
1206 #define CoreExport /**/
1207 #define DllExport /**/
1209 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1210 #define MOD_PATH "$config{MODULE_DIR}"
1211 #define VERSION "$version"
1212 #define REVISION "$revision2"
1213 #define MAXCLIENTS $config{MAX_CLIENT}
1214 #define MAXCLIENTS_S "$config{MAX_CLIENT}"
1215 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1216 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
1219 #define MAXMODES $config{MAXI_MODES}
1220 #define IDENTMAX $config{MAX_IDENT}
1221 #define MAXQUIT $config{MAX_QUIT}
1222 #define MAXTOPIC $config{MAX_TOPIC}
1223 #define MAXKICK $config{MAX_KICK}
1224 #define MAXGECOS $config{MAX_GECOS}
1225 #define MAXAWAY $config{MAX_AWAY}
1226 #define OPTIMISATION $config{OPTIMITEMP}
1227 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1228 #define SYSTEM "$incos"
1231 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1233 if ($config{OSNAME} =~ /SunOS/i) {
1234 print FILEHANDLE "#define IS_SOLARIS\n";
1236 if ($config{OSNAME} =~ /MINGW32/i) {
1237 print FILEHANDLE "#define IS_MINGW\n";
1239 if ($config{GCCVER} >= 3) {
1240 print FILEHANDLE "#define GCC3\n";
1242 if ($config{HAS_STRLCPY} eq "true") {
1243 print FILEHANDLE "#define HAS_STRLCPY\n";
1245 if ($config{HAS_STDINT} eq "true") {
1246 print FILEHANDLE "#define HAS_STDINT\n";
1248 if ($config{IPV6} =~ /y/i) {
1249 print FILEHANDLE "#define IPV6\n";
1251 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1252 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1255 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1256 print FILEHANDLE "#define USE_KQUEUE\n";
1257 $se = "socketengine_kqueue";
1260 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1261 print FILEHANDLE "#define USE_EPOLL\n";
1262 $se = "socketengine_epoll";
1265 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1266 print FILEHANDLE "#define USE_PORTS\n";
1267 $se = "socketengine_ports";
1270 # user didn't choose either epoll or select for their OS.
1271 # default them to USE_SELECT (ewwy puke puke)
1273 print FILEHANDLE "#define USE_SELECT\n";
1274 $se = "socketengine_select";
1276 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1282 open(FILEHANDLE, ">include/inspircd_se_config.h");
1283 print FILEHANDLE <<EOF;
1284 /* Auto generated by configure, do not modify or commit to svn! */
1285 #ifndef __CONFIGURATION_SOCKETENGINE__
1286 #define __CONFIGURATION_SOCKETENGINE__
1288 #include "socketengines/$se.h"
1296 # Create a Modules List..
1298 foreach my $i (@modlist)
1300 $modules .= "m_".$i.".so ";
1302 chomp($modules); # Remove Redundant whitespace..
1304 opendir(DIRHANDLE, "src/modules");
1305 foreach my $name (sort readdir(DIRHANDLE)) {
1306 if ($name =~ /^m_(.+?)$/) {
1307 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1308 closedir(MDIRHANDLE);
1309 $modules .= "$name.so ";
1310 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name.so\n";
1314 closedir(DIRHANDLE);
1317 # Write all .in files.
1320 my $exe = "inspircd";
1322 # Do this once here, and cache it in the .*.inc files,
1323 # rather than attempting to read src/version.sh from
1324 # compiled code -- we might not have the source to hand.
1325 # Fix for bug#177 by Brain.
1327 chomp($version = `sh ./src/version.sh`);
1328 chomp(my $revision = getrevision());
1329 $version = "$version(r$revision)";
1331 # We can actually parse any file starting with . and ending with .inc,
1332 # but right now we only parse .inspircd.inc to form './inspircd'
1334 print "Writing \e[1;32mMakefiles\e[0m\n";
1335 write_dynamic_modules_makefile();
1336 write_dynamic_makefile();
1338 opendir(DIRHANDLE, $this);
1340 foreach my $name (sort readdir(DIRHANDLE)) {
1341 if ($name =~ /^\.(.+)\.inc$/) {
1344 # Bug #353, omit this on non-darwin
1345 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1347 # All .name.inc files need parsing!
1349 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1350 while (<FILEHANDLE>) {
1355 print "Writing \e[1;32m$file\e[0m ...\n";
1356 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1357 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1358 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1359 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1360 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1361 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1362 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1363 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1364 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1365 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1366 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1367 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1368 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1369 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1370 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1371 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1372 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1373 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1374 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1376 open(FILEHANDLE, ">$file");
1377 print FILEHANDLE $tmp;
1380 closedir(DIRHANDLE);
1382 # Make inspircd executable!
1383 chmod 0744, 'inspircd';
1386 sub write_dynamic_modules_makefile {
1387 # Modules Makefile..
1388 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1389 open(FILEHANDLE, ">src/modules/Makefile");
1392 # Module Makefile Header
1394 print FILEHANDLE <<EOF;
1395 ###################################################
1396 # Copyright 2002-2007 The InspIRCd Development Team
1397 # http://www.inspircd.org/wiki/index.php/Credits
1399 # Thanks to Andrew Church <achurch\@achurch.org>
1400 # for assisting with making this work right.
1402 # Automatically Generated by ./configure to add a
1403 # modules please run ./configure -modupdate
1404 ###################################################
1410 if ($config{OSNAME} =~ /darwin/) {
1411 print FILEHANDLE <<EOCHEESE;
1413 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1417 print FILEHANDLE <<EOCHEESE;
1419 PICLDFLAGS = -fPIC -DPIC -shared
1425 # End Module Makefile Header
1428 # Create a Modules List..
1432 foreach my $i (@modlist) {
1434 # Write Entry to the MakeFile
1436 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1437 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1438 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1440 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1443 if (nopedantic("src/modules/m_".$i.".cpp"))
1446 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
1447 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1453 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
1454 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1457 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1458 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1460 # End Write Entry to the MakeFile
1464 opendir(DIRHANDLE, "src/modules");
1465 foreach my $name (sort readdir(DIRHANDLE)) {
1466 if ($name =~ /^m_(.+?)$/) {
1471 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1472 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1473 read_module_directory("src/modules/$name", $name);
1474 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1475 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";
1476 if ($config{IS_DARWIN} eq "YES") {
1477 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1479 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1481 print FILEHANDLE "\n$mfrules\n";
1482 closedir(MDIRHANDLE);
1483 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1487 closedir(DIRHANDLE);
1490 sub read_module_directory {
1491 my ($dpath, $reldpath) = @_;
1493 if (opendir(MDIRHANDLE, $dpath) == 0) {
1497 foreach my $fname (sort readdir(MDIRHANDLE)) {
1498 if ($fname =~ /\.cpp$/) {
1499 my $cmflags = getcompilerflags("$dpath/$fname");
1500 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1501 my $deps = getdependencies("$dpath/$fname");
1503 $oname =~ s/\.cpp$/.o/g;
1504 $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";
1505 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1506 $mobjs = $mobjs . " $reldpath/$oname";
1509 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1510 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1517 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1518 # dependencies which are not relevent in C++.
1522 open (CPP, "<$file") or die("Can't open $file for reading!");
1527 foreach my $d (@ignoredeps)
1533 foreach my $dep (@immutabledeps)
1535 $immutable = $immutable . "../include/$dep ";
1537 $immutable =~ s/ $//g;
1539 while (defined(my $line = <CPP>))
1542 if ($line =~ /#include "(.+\.h)"/)
1544 if (!exists($dupe{$1}))
1546 $retlist = $retlist . "../include/$1 ";
1552 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1555 sub write_dynamic_makefile
1559 my %existing_install_list = ();
1560 opendir(DIRHANDLE, "src/commands");
1561 foreach my $name (sort readdir(DIRHANDLE))
1563 if ($name =~ /^cmd_(.+)\.cpp$/)
1565 $cmdlist[$i++] = $1;
1566 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1567 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1570 closedir(DIRHANDLE);
1574 $config{USE_EPOLL} = 0;
1578 $config{USE_KQUEUE} = 0;
1582 $config{USE_PORTS} = 0;
1585 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1587 print "Scanning \e[1;32m$dir\e[0m for core files ";
1588 opendir(DIRHANDLE, $dir);
1589 foreach my $name (sort readdir(DIRHANDLE))
1591 if ($name =~ /\.cpp$/)
1593 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1595 while (defined(my $line = <CPP>))
1598 if ($line =~ /\/\* \$Core: (\w+) \*\//i)
1600 $filelist{$name} = $1;
1602 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1604 $specialdeps{$name} = $1;
1606 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1608 $extraobjects{$name} = $1;
1610 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1612 $extrabuildlines{$name} = $1;
1614 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1616 $extrasources{$name} = $1;
1618 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1620 if (defined $config{$1})
1622 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1625 while (defined($line = <CPP>))
1628 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1629 last if ($line =~ /\/\* \$EndIf \*\//i);
1634 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1636 if (!exists($existing_install_list{$1}))
1638 $existing_install_list{$1} = 1;
1639 my $idir = (split(' ',$1))[1];
1640 my $ifile = (split(' ',$1))[0];
1641 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1642 $ifile =~ s/.*\///g;
1643 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1646 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1648 if (!exists($existing_install_list{$1}))
1650 $existing_install_list{$1} = 1;
1651 my $idir = (split(' ',$1))[1];
1652 my $ifile = (split(' ',$1))[0];
1653 $install_list = $install_list . " -cp $1\n";
1654 $ifile =~ s/.*\///g;
1655 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1662 closedir(DIRHANDLE);
1666 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1669 my $all_libsonly = "";
1670 my $libraryext = "";
1674 if ($config{IS_DARWIN} eq "YES")
1676 $libraryext = "dylib";
1677 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd.cpp\n \@../make/run-cc.pl \$(CC) -pipe -dynamic -bind_at_load -L. -o inspircd \$(LDLIBS) inspircd.o "
1682 $RPATH = "-Wl,--rpath -Wl,$config{LIBRARY_DIR}" unless defined $opt_disablerpath;
1683 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include $RPATH \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1686 foreach my $cpp (sort keys %filelist)
1688 $all = $all . $filelist{$cpp} . "." . $libraryext . " ";
1689 $all_libsonly = $all_libsonly . $filelist{$cpp} . "." . $libraryext . " ";
1690 $install_list = $install_list . " -install -m \$(INSTMODE) src/" . $filelist{$cpp} . "." . $libraryext . " \$(LIBPATH)\n";
1691 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/" . $filelist{$cpp} . "." . $libraryext . "\n";
1693 $all = $all . "moo inspircd\n";
1695 $othercrap = $othercrap . " $all_libsonly\n\n";
1697 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1700 CC = im a cheezeball
1701 CXXFLAGS = -I../include \${FLAGS}
1702 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1703 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1707 print FH "$all\n\n";
1709 my $deps = calcdeps("src/inspircd.cpp");
1710 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1711 print FH "$othercrap\n";
1713 foreach my $cpp (sort keys %filelist)
1715 my $thislib = $filelist{$cpp} . "." . $libraryext;
1719 $objs =~ s/\.cpp$/.o/;
1720 if (exists($extraobjects{$cpp}))
1722 $objs = $objs . " " . $extraobjects{$cpp};
1724 if (exists($extrasources{$cpp}))
1726 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1728 if ($config{IS_DARWIN} eq "YES")
1730 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1734 if (defined $opt_disablerpath)
1736 $libcrap = " -shared";
1740 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1743 $deps = calcdeps("src/$cpp");
1744 if (exists($extrasources{$cpp}))
1746 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1748 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1751 $deps = $deps . $d . " ";
1755 print FH $thislib . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1756 print FH " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1757 if (exists($extrabuildlines{$cpp}))
1759 print FH " " . $extrabuildlines{$cpp} . "\n";
1761 print FH " \@../make/run-cc.pl \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1764 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1766 # close main makefile
1770 # generate a list of .so
1771 foreach my $cmd (@cmdlist) {
1772 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1775 # and now reopen the commands makefile
1776 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1779 CXXFLAGS = -I../../include \${FLAGS}
1786 # now print the command file details.
1787 foreach my $cmd (@cmdlist) {
1789 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
1790 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1796 # Routine to list out the extra/ modules that have been enabled.
1797 # Note: when getting any filenames out and comparing, it's important to lc it if the
1798 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1799 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1800 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1801 sub list_extras () {
1804 my $srcdir = File::Spec->catdir("src", "modules");
1805 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1808 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1809 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1812 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1813 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1816 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1818 EXTRA: for my $extra (@extras) {
1819 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1820 next if ($extra eq '.svn');
1821 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1822 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1823 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1824 if (-l $abs_source) {
1825 # Symlink, is it in the right place?
1826 my $targ = readlink($abs_source);
1827 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1828 if ($abs_targ eq $abs_extra) {
1829 $extras{$extra} = "\e[32;1menabled\e[0m";
1831 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1833 } elsif (-e $abs_source) {
1834 my ($devext, $inoext) = stat($abs_extra);
1835 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1837 if ($devsrc == $devext && $inosrc == $inoext) {
1838 $extras{$extra} = "\e[32;1menabled\e[0m";
1840 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1843 open my $extfd, "<", $abs_extra;
1844 open my $srcfd, "<", $abs_source;
1846 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1847 $extras{$extra} = "\e[32;1menabled\e[0m";
1849 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1853 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1856 # Now let's add dependency info
1857 for my $extra (keys(%extras)) {
1858 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1859 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1860 my @deps = split / +/, getdependencies($abs_extra);
1861 for my $dep (@deps) {
1862 if (exists($extras{$dep})) {
1863 my $ref = \$extras{$dep}; # Take reference.
1864 if ($$ref !~ m/needed by/) {
1865 # First dependency found.
1866 if ($$ref =~ m/enabled/) {
1867 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1869 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1870 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1873 if ($$ref =~ m/enabled/) {
1874 $$ref .= ", \e[32;1m$extra\e[0m";
1876 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1882 for my $extra (sort {$a cmp $b} keys(%extras)) {
1883 my $text = $extras{$extra};
1884 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1885 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1887 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1890 return keys(%extras) if wantarray; # Can be used by manage_extras.
1893 sub enable_extras (@) {
1895 for my $extra (@extras) {
1896 my $extrapath = "src/modules/extra/$extra";
1897 if (!-e $extrapath) {
1898 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1901 my $source = "src/modules/$extra";
1903 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1906 # Get dependencies, and add them to be processed.
1907 my @deps = split / +/, getdependencies($extrapath);
1908 for my $dep (@deps) {
1909 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1910 if (!-e "src/modules/$dep") {
1911 if (-e "src/modules/extra/$dep") {
1912 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1915 print STDERR "\e[33;1mWARNING:\e[0m module \e[32;1m$extra\e[0m might be missing dependency \e[32;1m$dep\e[0m - YOU are responsible for satisfying it!\n";
1919 print "Enabling $extra ... \n";
1920 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1924 sub disable_extras (@)
1926 opendir my $dd, "src/modules/extra/";
1927 my @files = readdir($dd);
1930 EXTRA: for my $extra (@extras) {
1931 my $extrapath = "src/modules/extra/$extra";
1932 my $source = "src/modules/$extra";
1933 if (!-e $extrapath) {
1934 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1937 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1938 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Source is not a link or doesn't refer to the right file. Remove manually if this is in error.\n";
1941 # Check if anything needs this.
1942 for my $file (@files) {
1943 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1944 # File depends on this extra...
1945 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1946 # And is both enabled and not about to be disabled.
1947 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1948 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1954 print "Disabling $extra ... \n";
1955 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";