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
496 my $rootincchanged = 0;
498 while (defined(my $line = <$fd>))
502 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
503 ($action, $file) = ($1, $2);
506 push @conflicted, $file;
507 if ($file eq "configure")
509 $configurechanged = 1;
511 elsif ($file =~ m#^src/modules#)
513 $moduledirchanged = 1;
515 elsif ($file =~ m#^src/#)
519 elsif ($file =~ m/^\..*\.inc$/)
524 elsif ($action eq "U" || $action eq "G")
526 if ($file eq "configure")
528 $configurechanged = 1;
530 elsif ($file =~ m/^\..*\.inc$/)
535 elsif ($action eq "A" || $action eq "D")
537 if ($file =~ m#^src/modules#)
539 $moduledirchanged = 1;
541 elsif ($file =~ m#^src/#)
547 unless (close $fd) # close() waits for exit and returns false if the command failed
551 print STDERR "Problem updating from SVN, please check above for errors\n";
555 print STDERR "Failed to run SVN: $!\n";
559 if (scalar(@conflicted) > 0)
561 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
562 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate", (($coredirchanged || $configurechanged) ? "" : "mod");
564 if ($configurechanged || $coredirchanged)
566 system("perl configure -update");
568 elsif ($moduledirchanged || $rootincchanged)
570 system("perl configure -modupdate");
574 print "No need to update Makefiles.\n";
576 if (defined $opt_rebuild) {
577 system("make install");
582 print "Running non-interactive configure...\n" unless $interactive;
583 print "Checking for cache from previous configure... ";
584 print ((!getcache()) ? "not found\n" : "found\n");
585 print "Checking operating system version... ";
586 print getosflags() . "\n";
588 if (defined $opt_maxclients)
590 $config{MAX_CLIENT} = $opt_maxclients;
593 if (!$config{MAX_CLIENT}) {
594 # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
595 # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
596 # higher than the found value" :))
597 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
600 printf "Checking if stdint.h exists... ";
601 $config{HAS_STDINT} = "true";
603 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
604 if ($config{HAS_STDINT} eq "true") {
607 print "yes\n" if $config{HAS_STDINT} eq "true";
608 print "no\n" if $config{HAS_STDINT} eq "false";
610 printf "Checking if strlcpy exists... ";
611 # Perform the strlcpy() test..
612 $config{HAS_STRLCPY} = "false";
614 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
616 while (defined(my $line = <STRLCPY>)) {
618 # try and find the delcaration of:
619 # size_t strlcpy(...)
620 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
621 $config{HAS_STRLCPY} = "true";
626 print "yes\n" if $config{HAS_STRLCPY} eq "true";
627 print "no\n" if $config{HAS_STRLCPY} eq "false";
629 printf "Checking if kqueue exists... ";
632 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
634 while (defined(my $line = <KQUEUE>)) {
636 # try and find the delcaration of:
638 if ($line =~ /int(\0x9|\s)+kqueue/) {
644 print "yes\n" if $has_kqueue == 1;
645 print "no\n" if $has_kqueue == 0;
647 printf "Checking if epoll exists... ";
650 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
656 my $kernel = `uname -r`;
658 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
663 # Suggestion from nenolod, weed out odd systems which have glibc built
664 # against 2.4 kernels (ick)
665 my $kernel_arch = `uname -p`;
669 if ($kernel_arch =~ /x86_64/) {
670 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
673 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
677 while (defined(my $line = <FH>))
680 if ($line =~ /GNU C Library .* version (.*?) /)
683 $libcv =~ /(\d+\.\d+)/;
686 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
689 # Fix for some retarded libc builds, strip off >> and << etc.
690 $kernelv =~ /(\d+\.\d+)/;
698 printf "libc too old: $libcv... ";
703 printf "libc built against older kernel $kernelv... ";
708 print "yes\n" if $has_epoll == 1;
709 print "no\n" if $has_epoll == 0;
711 printf "Checking if Solaris I/O completion ports are available... ";
713 our $system = `uname -s`;
715 $has_ports = 1 if ($system eq "SunOS");
718 my $kernel = `uname -r`;
720 if (($kernel !~ /^5\.1./)) {
724 print "yes\n" if $has_ports == 1;
725 print "no\n" if $has_ports == 0;
727 $config{HAS_EPOLL} = $has_epoll;
728 $config{HAS_KQUEUE} = $has_kqueue;
730 printf "Checking for libgnutls... ";
731 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
733 $config{HAS_GNUTLS} = "y";
736 $config{HAS_GNUTLS} = "n";
739 printf "Checking for openssl... ";
740 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
742 $config{HAS_OPENSSL} = "y";
745 $config{HAS_OPENSSL} = "n";
748 printf "Checking if you are running an ancient, unsupported OS... ";
749 if ($config{OSNAME} =~ /FreeBSD/i)
751 my $version = `uname -r`;
752 if ($version =~ /^4\./)
754 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
757 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
758 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
763 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
769 print "no ($version)\n";
775 print "no ($config{OSNAME})\n";
778 ################################################################################
779 # BEGIN INTERACTIVE PART #
780 ################################################################################
785 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
788 my $rev = getrevision();
789 # Display Introduction Message..
791 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
792 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
794 *** If you are unsure of any of these values, leave it blank for ***
795 *** standard settings that will work, and your server will run ***
796 *** using them. Please consult your IRC network admin if in doubt. ***
798 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
799 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
800 dir, otherwise you won't have a config file!
802 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
803 Maximum file descriptors: \e[1;32m$config{MAX_CLIENT_T}\e[0m
804 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
807 print " (Non-SVN build)";
811 $config{CHANGE_COMPILER} = "n";
812 print "I have detected the following compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
814 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
815 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
816 should NOT be used. You should probably specify a newer compiler.\n\n";
817 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
818 if ($config{CHANGE_COMPILER} =~ /y/i) {
819 print "What command do you want to use to invoke your compiler?\n";
820 print "[\e[1;32m$config{CC}\e[0m] -> ";
821 chomp($config{CC} = <STDIN>);
822 if ($config{CC} eq "") {
825 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
827 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
828 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
829 if ($config{GCCVER} < 3) {
830 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
834 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
841 # Directory Settings..
842 my $tmpbase = $config{BASE_DIR};
843 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
844 if ($tmpbase ne $config{BASE_DIR}) {
845 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
846 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
847 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
848 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
851 dir_check("are the configuration files", "CONFIG_DIR");
852 dir_check("are the modules to be compiled to", "MODULE_DIR");
853 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
854 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
857 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?");
861 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?");
865 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?");
868 my $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
869 if (!$chose_hiperf) {
870 print "No high-performance socket engines are available, or you chose\n";
871 print "not to enable one. Defaulting to select() engine.\n\n";
874 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
877 if ($config{IPV6} eq "y") {
878 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";
879 $config{SUPPORT_IP6LINKS} = "y";
881 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)");
885 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
886 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
887 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
888 print "instead, you should enable the OpenSSL module yourself\n";
889 print "by copying it from src/modules/extra to src/modules.\n\n";
890 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
891 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
894 if ($config{HAS_GNUTLS} eq "y") {
895 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
896 if ($config{USE_GNUTLS} eq "y") {
897 print "\nUsing GnuTLS SSL module.\n";
899 } elsif ($config{HAS_OPENSSL} eq "y") {
900 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
901 if ($config{USE_OPENSSL} eq "y") {
902 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
906 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";
909 print "\nThe following questions will ask you for various figures relating\n";
910 print "To your IRCd install. Please note that these should usually be left\n";
911 print "as defaults unless you have a real reason to change them. If they\n";
912 print "changed, then the values must be identical on all servers on your\n";
913 print "network, or malfunctions and/or crashes may occur, with the exception\n";
914 print "of the 'maximum number of clients' setting which may be different on\n";
915 print "different servers on the network.\n\n";
917 # File Descriptor Settings..
918 promptnumeric("number of clients at any one time", "MAX_CLIENT_T");
919 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
920 $config{MAX_DESCRIPTORS} = $config{MAX_CLIENT_T};
922 promptnumeric("length of nicknames", "NICK_LENGT");
923 promptnumeric("length of channel names", "CHAN_LENGT");
924 promptnumeric("number of mode changes in one line", "MAXI_MODES");
925 promptnumeric("length of an ident (username)", "MAX_IDENT");
926 promptnumeric("length of a quit message", "MAX_QUIT");
927 promptnumeric("length of a channel topic", "MAX_TOPIC");
928 promptnumeric("length of a kick message", "MAX_KICK");
929 promptnumeric("length of a GECOS (real name)", "MAX_GECOS");
930 promptnumeric("length of an away message", "MAX_AWAY");
935 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
937 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
940 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
942 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
947 if ($config{USE_GNUTLS} eq "y") {
948 unless (-r "src/modules/m_ssl_gnutls.cpp") {
949 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
950 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
955 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
956 print "SSL Certificates Not found, Generating.. \n\n
957 *************************************************************
958 * Generating the Private Key may take some time, go grab a *
959 * Coffee. Even better, to generate some more entropy if it *
960 * is taking a while, open another console and type du / a *
961 * few times and get that HD going :) Then answer the *
962 * Questions which follow. If you are unsure, just hit enter *
963 *************************************************************\n\n";
964 $failed = make_gnutls_cert();
966 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
968 print "\nCertificate generation complete, copying to config directory... ";
969 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
970 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
975 print "SSL Certificates found, skipping.\n\n";
980 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
982 } elsif ($config{USE_OPENSSL} eq "y") {
983 unless (-r "src/modules/m_ssl_openssl.cpp") {
984 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
985 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
991 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
992 print "SSL Certificates Not found, Generating.. \n\n
993 *************************************************************
994 * Generating the certificates may take some time, go grab a *
995 * coffee, or something. *
996 *************************************************************\n\n";
998 print "\nCertificate generation complete, copying to config directory... ";
999 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
1000 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
1001 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
1004 print "SSL Certificates found, skipping.\n\n"
1009 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
1012 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
1013 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
1021 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
1022 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
1023 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
1024 print "modules in your config. This configure script has added those modules to the\n";
1025 print "build process. For more info please refer to:\n";
1026 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
1028 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
1029 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
1030 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";
1033 if ($config{GCCVER} < "3") {
1035 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
1036 GCC 2.x series compilers only had partial (read as broken) C++ support, and
1037 your compile will most likely fail horribly! If you have any problems, do NOT
1038 report them to the bugtracker or forums without first upgrading your compiler
1039 to a newer 3.x or 4.x (or whatever is available currently) version.
1043 ################################################################################
1044 # HELPER FUNCTIONS #
1045 ################################################################################
1047 # Retrieves the .config.cache file, and loads values into the main config hash.
1048 open(CACHE, ".config.cache") or return 0;
1051 # Ignore Blank lines, and comments..
1054 my ($key, $value) = split("=", $_, 2);
1055 $value =~ /^\"(.*)\"$/;
1056 # Do something with data here!
1064 # Dump the contents of %config
1065 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1066 open(FILEHANDLE, ">.config.cache");
1067 foreach my $key (keys %config) {
1068 print FILEHANDLE "$key=\"$config{$key}\"\n";
1074 my ($desc, $hash_key) = @_;
1076 while (!$complete) {
1077 print "In what directory $desc?\n";
1078 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1079 chomp(my $var = <STDIN>);
1081 $var = $config{$hash_key};
1083 if ($var =~ /^\~\/(.+)$/) {
1084 # Convert it to a full path..
1085 $var = resolve_directory($ENV{HOME} . "/" . $1);
1087 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1089 # Assume relative Path was given.. fill in the rest.
1090 $var = $this . "/$var";
1093 $var = resolve_directory($var);
1095 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1096 chomp(my $tmp = <STDIN>);
1097 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1098 # Attempt to Create the Dir..
1101 File::Path::mkpath($var, 0, 0777);
1104 unless (defined($chk) && -d $var) {
1105 print "Unable to create directory. ($var)\n\n";
1110 # They said they don't want to create, and we can't install there.
1115 if (!is_dir($var)) {
1116 # Target exists, but is not a directory.
1117 print "File $var exists, but is not a directory.\n\n";
1121 # Either Dir Exists, or was created fine.
1122 $config{$hash_key} = $var;
1132 # Beware: Linux sets it's own cflags below for some retarded reason
1133 $config{LDLIBS} = "-pthread -lstdc++";
1134 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1135 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -g";
1136 $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared" unless defined $opt_disablerpath;
1137 $config{MAKEPROG} = "make";
1139 if ($config{OSNAME} =~ /darwin/i) {
1140 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1141 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1142 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1145 if ($config{OSNAME} =~ /OpenBSD/i) {
1146 $config{MAKEPROG} = "gmake";
1147 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1148 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1149 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1150 # if theyre not running this, configure lets the build continue but they probably wont manage to
1151 # compile as this standard version is 2.95.3!
1153 $config{CC} = "eg++";
1154 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1159 if ($config{OSNAME} =~ /Linux/i) {
1160 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1161 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1162 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1163 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1164 $config{MAKEPROG} = "make";
1167 if ($config{OSNAME} =~ /FreeBSD/i) {
1168 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1169 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1172 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1174 # solaris/sunos needs these
1175 # socket = bsd sockets api
1177 # rt = POSIX realtime extensions
1178 # resolv = inet_aton only (why isnt this in nsl?!)
1179 $config{MAKEPROG} = "gmake";
1180 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1184 if($config{OSNAME} =~ /MINGW32/i)
1186 # All code is position-independent on windows
1187 $config{FLAGS} =~ s/-fPIC //;
1191 return $config{OSNAME};
1194 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1197 my($writeheader) = @_;
1199 # First File.. inspircd_config.h
1200 chomp(my $incos = `uname -n -s -r`);
1201 chomp(my $version = `sh src/version.sh`);
1202 chomp(my $revision2 = getrevision());
1203 if ($writeheader == 1)
1205 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1206 open(FILEHANDLE, ">include/inspircd_config.h");
1207 my $NL = $config{NICK_LENGT}+1;
1208 my $CL = $config{CHAN_LENGT}+1;
1209 print FILEHANDLE <<EOF;
1210 /* Auto generated by configure, do not modify! */
1211 #ifndef __CONFIGURATION_AUTO__
1212 #define __CONFIGURATION_AUTO__
1214 /* this is for windows support. */
1215 #define CoreExport /**/
1216 #define DllExport /**/
1218 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1219 #define MOD_PATH "$config{MODULE_DIR}"
1220 #define VERSION "$version"
1221 #define REVISION "$revision2"
1222 #define MAXCLIENTS $config{MAX_CLIENT}
1223 #define MAXCLIENTS_S "$config{MAX_CLIENT}"
1224 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1225 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
1228 #define MAXMODES $config{MAXI_MODES}
1229 #define IDENTMAX $config{MAX_IDENT}
1230 #define MAXQUIT $config{MAX_QUIT}
1231 #define MAXTOPIC $config{MAX_TOPIC}
1232 #define MAXKICK $config{MAX_KICK}
1233 #define MAXGECOS $config{MAX_GECOS}
1234 #define MAXAWAY $config{MAX_AWAY}
1235 #define OPTIMISATION $config{OPTIMITEMP}
1236 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1237 #define SYSTEM "$incos"
1240 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1242 if ($config{OSNAME} =~ /SunOS/i) {
1243 print FILEHANDLE "#define IS_SOLARIS\n";
1245 if ($config{OSNAME} =~ /MINGW32/i) {
1246 print FILEHANDLE "#define IS_MINGW\n";
1248 if ($config{GCCVER} >= 3) {
1249 print FILEHANDLE "#define GCC3\n";
1251 if ($config{HAS_STRLCPY} eq "true") {
1252 print FILEHANDLE "#define HAS_STRLCPY\n";
1254 if ($config{HAS_STDINT} eq "true") {
1255 print FILEHANDLE "#define HAS_STDINT\n";
1257 if ($config{IPV6} =~ /y/i) {
1258 print FILEHANDLE "#define IPV6\n";
1260 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1261 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1264 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1265 print FILEHANDLE "#define USE_KQUEUE\n";
1266 $se = "socketengine_kqueue";
1269 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1270 print FILEHANDLE "#define USE_EPOLL\n";
1271 $se = "socketengine_epoll";
1274 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1275 print FILEHANDLE "#define USE_PORTS\n";
1276 $se = "socketengine_ports";
1279 # user didn't choose either epoll or select for their OS.
1280 # default them to USE_SELECT (ewwy puke puke)
1282 print FILEHANDLE "#define USE_SELECT\n";
1283 $se = "socketengine_select";
1285 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1291 open(FILEHANDLE, ">include/inspircd_se_config.h");
1292 print FILEHANDLE <<EOF;
1293 /* Auto generated by configure, do not modify or commit to svn! */
1294 #ifndef __CONFIGURATION_SOCKETENGINE__
1295 #define __CONFIGURATION_SOCKETENGINE__
1297 #include "socketengines/$se.h"
1305 # Create a Modules List..
1307 foreach my $i (@modlist)
1309 $modules .= "m_".$i.".so ";
1311 chomp($modules); # Remove Redundant whitespace..
1313 opendir(DIRHANDLE, "src/modules");
1314 foreach my $name (sort readdir(DIRHANDLE)) {
1315 if ($name =~ /^m_(.+?)$/) {
1316 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1317 closedir(MDIRHANDLE);
1318 $modules .= "$name.so ";
1319 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name.so\n";
1323 closedir(DIRHANDLE);
1326 # Write all .in files.
1329 my $exe = "inspircd";
1331 # Do this once here, and cache it in the .*.inc files,
1332 # rather than attempting to read src/version.sh from
1333 # compiled code -- we might not have the source to hand.
1334 # Fix for bug#177 by Brain.
1336 chomp($version = `sh ./src/version.sh`);
1337 chomp(my $revision = getrevision());
1338 $version = "$version(r$revision)";
1340 # We can actually parse any file starting with . and ending with .inc,
1341 # but right now we only parse .inspircd.inc to form './inspircd'
1343 print "Writing \e[1;32mMakefiles\e[0m\n";
1344 write_dynamic_modules_makefile();
1345 write_dynamic_makefile();
1347 opendir(DIRHANDLE, $this);
1349 foreach my $name (sort readdir(DIRHANDLE)) {
1350 if ($name =~ /^\.(.+)\.inc$/) {
1353 # Bug #353, omit this on non-darwin
1354 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1356 # All .name.inc files need parsing!
1358 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1359 while (<FILEHANDLE>) {
1364 print "Writing \e[1;32m$file\e[0m ...\n";
1365 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1366 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1367 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1368 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1369 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1370 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1371 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1372 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1373 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1374 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1375 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1376 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1377 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1378 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1379 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1380 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1381 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1382 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1383 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1385 open(FILEHANDLE, ">$file");
1386 print FILEHANDLE $tmp;
1389 closedir(DIRHANDLE);
1391 # Make inspircd executable!
1392 chmod 0744, 'inspircd';
1395 sub write_dynamic_modules_makefile {
1396 # Modules Makefile..
1397 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1398 open(FILEHANDLE, ">src/modules/Makefile");
1401 # Module Makefile Header
1403 print FILEHANDLE <<EOF;
1404 ###################################################
1405 # Copyright 2002-2007 The InspIRCd Development Team
1406 # http://www.inspircd.org/wiki/index.php/Credits
1408 # Thanks to Andrew Church <achurch\@achurch.org>
1409 # for assisting with making this work right.
1411 # Automatically Generated by ./configure to add a
1412 # modules please run ./configure -modupdate
1413 ###################################################
1419 if ($config{OSNAME} =~ /darwin/) {
1420 print FILEHANDLE <<EOCHEESE;
1422 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1426 print FILEHANDLE <<EOCHEESE;
1428 PICLDFLAGS = -fPIC -DPIC -shared
1434 # End Module Makefile Header
1437 # Create a Modules List..
1441 foreach my $i (@modlist) {
1443 # Write Entry to the MakeFile
1445 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1446 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1447 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1449 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1452 if (nopedantic("src/modules/m_".$i.".cpp"))
1455 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
1456 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1462 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
1463 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1466 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1467 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1469 # End Write Entry to the MakeFile
1473 opendir(DIRHANDLE, "src/modules");
1474 foreach my $name (sort readdir(DIRHANDLE)) {
1475 if ($name =~ /^m_(.+?)$/) {
1480 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1481 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1482 read_module_directory("src/modules/$name", $name);
1483 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1484 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";
1485 if ($config{IS_DARWIN} eq "YES") {
1486 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1488 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1490 print FILEHANDLE "\n$mfrules\n";
1491 closedir(MDIRHANDLE);
1492 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1496 closedir(DIRHANDLE);
1499 sub read_module_directory {
1500 my ($dpath, $reldpath) = @_;
1502 if (opendir(MDIRHANDLE, $dpath) == 0) {
1506 foreach my $fname (sort readdir(MDIRHANDLE)) {
1507 if ($fname =~ /\.cpp$/) {
1508 my $cmflags = getcompilerflags("$dpath/$fname");
1509 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1510 my $deps = getdependencies("$dpath/$fname");
1512 $oname =~ s/\.cpp$/.o/g;
1513 $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";
1514 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1515 $mobjs = $mobjs . " $reldpath/$oname";
1518 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1519 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1526 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1527 # dependencies which are not relevent in C++.
1531 open (CPP, "<$file") or die("Can't open $file for reading!");
1536 foreach my $d (@ignoredeps)
1542 foreach my $dep (@immutabledeps)
1544 $immutable = $immutable . "../include/$dep ";
1546 $immutable =~ s/ $//g;
1548 while (defined(my $line = <CPP>))
1551 if ($line =~ /#include "(.+\.h)"/)
1553 if (!exists($dupe{$1}))
1555 $retlist = $retlist . "../include/$1 ";
1561 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1564 sub write_dynamic_makefile
1568 my %existing_install_list = ();
1569 opendir(DIRHANDLE, "src/commands");
1570 foreach my $name (sort readdir(DIRHANDLE))
1572 if ($name =~ /^cmd_(.+)\.cpp$/)
1574 $cmdlist[$i++] = $1;
1575 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1576 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1579 closedir(DIRHANDLE);
1583 $config{USE_EPOLL} = 0;
1587 $config{USE_KQUEUE} = 0;
1591 $config{USE_PORTS} = 0;
1594 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1596 print "Scanning \e[1;32m$dir\e[0m for core files ";
1597 opendir(DIRHANDLE, $dir);
1598 foreach my $name (sort readdir(DIRHANDLE))
1600 if ($name =~ /\.cpp$/)
1602 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1604 while (defined(my $line = <CPP>))
1607 if ($line =~ /\/\* \$Core: (\w+) \*\//i)
1609 $filelist{$name} = $1;
1611 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1613 $specialdeps{$name} = $1;
1615 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1617 $extraobjects{$name} = $1;
1619 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1621 $extrabuildlines{$name} = $1;
1623 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1625 $extrasources{$name} = $1;
1627 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1629 if (defined $config{$1})
1631 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1634 while (defined($line = <CPP>))
1637 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1638 last if ($line =~ /\/\* \$EndIf \*\//i);
1643 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1645 if (!exists($existing_install_list{$1}))
1647 $existing_install_list{$1} = 1;
1648 my $idir = (split(' ',$1))[1];
1649 my $ifile = (split(' ',$1))[0];
1650 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1651 $ifile =~ s/.*\///g;
1652 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1655 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1657 if (!exists($existing_install_list{$1}))
1659 $existing_install_list{$1} = 1;
1660 my $idir = (split(' ',$1))[1];
1661 my $ifile = (split(' ',$1))[0];
1662 $install_list = $install_list . " -cp $1\n";
1663 $ifile =~ s/.*\///g;
1664 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1671 closedir(DIRHANDLE);
1675 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1678 my $all_libsonly = "";
1679 my $libraryext = "";
1683 if ($config{IS_DARWIN} eq "YES")
1685 $libraryext = "dylib";
1686 $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 "
1691 $RPATH = "-Wl,--rpath -Wl,$config{LIBRARY_DIR}" unless defined $opt_disablerpath;
1692 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include $RPATH \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1695 foreach my $cpp (sort keys %filelist)
1697 $all = $all . $filelist{$cpp} . "." . $libraryext . " ";
1698 $all_libsonly = $all_libsonly . $filelist{$cpp} . "." . $libraryext . " ";
1699 $install_list = $install_list . " -install -m \$(INSTMODE) src/" . $filelist{$cpp} . "." . $libraryext . " \$(LIBPATH)\n";
1700 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/" . $filelist{$cpp} . "." . $libraryext . "\n";
1702 $all = $all . "moo inspircd\n";
1704 $othercrap = $othercrap . " $all_libsonly\n\n";
1706 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1709 CC = im a cheezeball
1710 CXXFLAGS = -I../include \${FLAGS}
1711 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1712 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1716 print FH "$all\n\n";
1718 my $deps = calcdeps("src/inspircd.cpp");
1719 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1720 print FH "$othercrap\n";
1722 foreach my $cpp (sort keys %filelist)
1724 my $thislib = $filelist{$cpp} . "." . $libraryext;
1728 $objs =~ s/\.cpp$/.o/;
1729 if (exists($extraobjects{$cpp}))
1731 $objs = $objs . " " . $extraobjects{$cpp};
1733 if (exists($extrasources{$cpp}))
1735 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1737 if ($config{IS_DARWIN} eq "YES")
1739 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1743 if (defined $opt_disablerpath)
1745 $libcrap = " -shared";
1749 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1752 $deps = calcdeps("src/$cpp");
1753 if (exists($extrasources{$cpp}))
1755 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1757 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1760 $deps = $deps . $d . " ";
1764 print FH $thislib . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1765 print FH " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1766 if (exists($extrabuildlines{$cpp}))
1768 print FH " " . $extrabuildlines{$cpp} . "\n";
1770 print FH " \@../make/run-cc.pl \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1773 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1775 # close main makefile
1779 # generate a list of .so
1780 foreach my $cmd (@cmdlist) {
1781 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1784 # and now reopen the commands makefile
1785 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1788 CXXFLAGS = -I../../include \${FLAGS}
1795 # now print the command file details.
1796 foreach my $cmd (@cmdlist) {
1798 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
1799 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1805 # Routine to list out the extra/ modules that have been enabled.
1806 # Note: when getting any filenames out and comparing, it's important to lc it if the
1807 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1808 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1809 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1810 sub list_extras () {
1813 my $srcdir = File::Spec->catdir("src", "modules");
1814 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1817 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1818 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1821 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1822 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1825 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1827 EXTRA: for my $extra (@extras) {
1828 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1829 next if ($extra eq '.svn');
1830 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1831 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1832 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1833 if (-l $abs_source) {
1834 # Symlink, is it in the right place?
1835 my $targ = readlink($abs_source);
1836 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1837 if ($abs_targ eq $abs_extra) {
1838 $extras{$extra} = "\e[32;1menabled\e[0m";
1840 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1842 } elsif (-e $abs_source) {
1843 my ($devext, $inoext) = stat($abs_extra);
1844 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1846 if ($devsrc == $devext && $inosrc == $inoext) {
1847 $extras{$extra} = "\e[32;1menabled\e[0m";
1849 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1852 open my $extfd, "<", $abs_extra;
1853 open my $srcfd, "<", $abs_source;
1855 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1856 $extras{$extra} = "\e[32;1menabled\e[0m";
1858 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1862 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1865 # Now let's add dependency info
1866 for my $extra (keys(%extras)) {
1867 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1868 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1869 my @deps = split / +/, getdependencies($abs_extra);
1870 for my $dep (@deps) {
1871 if (exists($extras{$dep})) {
1872 my $ref = \$extras{$dep}; # Take reference.
1873 if ($$ref !~ m/needed by/) {
1874 # First dependency found.
1875 if ($$ref =~ m/enabled/) {
1876 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1878 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1879 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1882 if ($$ref =~ m/enabled/) {
1883 $$ref .= ", \e[32;1m$extra\e[0m";
1885 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1891 for my $extra (sort {$a cmp $b} keys(%extras)) {
1892 my $text = $extras{$extra};
1893 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1894 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1896 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1899 return keys(%extras) if wantarray; # Can be used by manage_extras.
1902 sub enable_extras (@) {
1904 for my $extra (@extras) {
1905 my $extrapath = "src/modules/extra/$extra";
1906 if (!-e $extrapath) {
1907 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1910 my $source = "src/modules/$extra";
1912 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1915 # Get dependencies, and add them to be processed.
1916 my @deps = split / +/, getdependencies($extrapath);
1917 for my $dep (@deps) {
1918 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1919 if (!-e "src/modules/$dep") {
1920 if (-e "src/modules/extra/$dep") {
1921 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1924 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";
1928 print "Enabling $extra ... \n";
1929 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1933 sub disable_extras (@)
1935 opendir my $dd, "src/modules/extra/";
1936 my @files = readdir($dd);
1939 EXTRA: for my $extra (@extras) {
1940 my $extrapath = "src/modules/extra/$extra";
1941 my $source = "src/modules/$extra";
1942 if (!-e $extrapath) {
1943 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1946 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1947 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";
1950 # Check if anything needs this.
1951 for my $file (@files) {
1952 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1953 # File depends on this extra...
1954 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1955 # And is both enabled and not about to be disabled.
1956 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1957 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1963 print "Disabling $extra ... \n";
1964 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";