2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2008 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_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,
105 $opt_opermaxchans, $opt_freebsd_port);
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 'enable-ports' => \$opt_ports,
127 'enable-epoll' => \$opt_epoll,
128 'enable-kqueue' => \$opt_kqueue,
129 'disable-ports' => \$opt_noports,
130 'disable-epoll' => \$opt_noepoll,
131 'disable-kqueue' => \$opt_nokqueue,
132 'disable-rpath' => \$opt_disablerpath,
133 'enable-ipv6' => \$opt_ipv6,
134 'enable-remote-ipv6' => \$opt_ipv6links,
135 'disable-remote-ipv6' => \$opt_noipv6links,
136 'with-cc=s' => \$opt_cc,
137 'with-ident-length=i' => \$opt_ident,
138 'with-quit-length=i' => \$opt_quit,
139 'with-topic-length=i' => \$opt_topic,
140 'with-maxbuf=i' => \$opt_maxbuf,
141 'with-kick-length=i' => \$opt_kick,
142 'with-gecos-length=i' => \$opt_gecos,
143 'with-away-length=i' => \$opt_away,
144 'with-max-modes=i' => \$opt_modes,
145 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
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_modes) ||
185 (defined $opt_topic) ||
186 (defined $opt_quit) ||
187 (defined $opt_ident) ||
189 (defined $opt_ipv6) ||
190 (defined $opt_ipv6links) ||
191 (defined $opt_noipv6links) ||
192 (defined $opt_kqueue) ||
193 (defined $opt_epoll) ||
194 (defined $opt_ports) ||
195 (defined $opt_maxchans) ||
196 (defined $opt_opermaxchans) ||
197 (defined $opt_chan_length) ||
198 (defined $opt_nick_length) ||
199 (defined $opt_use_openssl) ||
200 (defined $opt_nokqueue) ||
201 (defined $opt_noepoll) ||
202 (defined $opt_noports) ||
203 (defined $opt_maxbuf) ||
204 (defined $opt_use_gnutls) ||
205 (defined $opt_freebsd_port)
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.
245 if (defined $opt_freebsd_port)
247 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
248 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
249 $config{USE_FREEBSD_BASE_SSL} = "n";
253 if ($^O eq "freebsd")
255 # default: use base ssl
256 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
257 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
261 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
262 $config{HAS_OPENSSL_PORT} = "";
266 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
267 chomp(our $openssl_ver = $config{HAS_OPENSSL});
268 $config{USE_GNUTLS} = "n";
269 if (defined $opt_use_gnutls)
271 $config{USE_GNUTLS} = "y"; # Use gnutls.
273 $config{USE_OPENSSL} = "n"; # Use openssl.
274 if (defined $opt_use_openssl)
276 $config{USE_OPENSSL} = "y";
279 # no, let's not change these.
280 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
281 if (!defined $opt_disable_debug)
283 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
287 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
290 $config{NICK_LENGT} = "31"; # Default Nick Length
291 if (defined $opt_nick_length)
293 $config{NICK_LENGT} = $opt_nick_length;
295 $config{CHAN_LENGT} = "64"; # Default Channel Name Length
296 if (defined $opt_chan_length)
298 $config{CHAN_LENGT} = $opt_chan_length;
300 $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once.
301 if (defined $opt_modes)
303 $config{MAXI_MODES} = $opt_modes;
305 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
306 $config{HAS_STDINT} = "false"; # stdint.h check
307 $config{USE_KQUEUE} = "y"; # kqueue enabled
308 if (defined $opt_kqueue)
310 $config{USE_KQUEUE} = "y";
312 if (defined $opt_nokqueue)
314 $config{USE_KQUEUE} = "n";
316 $config{USE_EPOLL} = "y"; # epoll enabled
317 if (defined $opt_epoll)
319 $config{USE_EPOLL} = "y";
321 if (defined $opt_noepoll)
323 $config{USE_EPOLL} = "n";
325 $config{USE_PORTS} = "y"; # epoll enabled
326 if (defined $opt_ports)
328 $config{USE_PORTS} = "y";
330 if (defined $opt_noports)
332 $config{USE_PORTS} = "n";
334 $config{IPV6} = "n"; # IPv6 support (experimental)
335 if (defined $opt_ipv6)
339 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
340 if (defined $opt_ipv6links)
342 $config{SUPPORT_IP6LINKS} = "y";
344 if (defined $opt_noipv6links)
346 $config{SUPPORT_IP6LINKS} = "n";
348 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
349 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
350 $config{OSNAME} = $^O; # Operating System Name
351 $config{IS_DARWIN} = "NO"; # Is OSX?
352 $config{STARTSCRIPT} = "inspircd"; # start script?
353 $config{DESTINATION} = "BASE"; # Is target path.
354 $config{EXTRA_DIR} = ""; # Is empty.
355 if ($config{OSNAME} =~ /darwin/i)
357 $config{IS_DARWIN} = "YES";
358 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
359 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
360 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
362 $config{CC} = "g++"; # C++ compiler
365 $config{CC} = $opt_cc;
367 our $exec = $config{CC} . " -dumpversion | cut -c 1";
368 chomp($config{GCCVER} = `$exec`); # Major GCC Version
369 $config{MAKEORDER} = "ircd mods"; # build order
370 $config{MAX_IDENT} = "12"; # max ident size
371 $config{MAX_QUIT} = "255"; # max quit message size
372 $config{MAX_TOPIC} = "307"; # max topic size
373 $config{MAX_KICK} = "255"; # max kick message size
374 $config{MAX_GECOS} = "128"; # max GECOS size
375 $config{MAX_AWAY} = "200"; # max AWAY size
376 $config{MAXBUF} = "512"; # Max buffer size
377 if (defined $opt_ident)
379 $config{MAX_IDENT} = $opt_ident;
381 if (defined $opt_quit)
383 $config{MAX_QUIT} = $opt_quit;
385 if (defined $opt_topic)
387 $config{MAX_TOPIC} = $opt_topic;
389 if (defined $opt_kick)
391 $config{MAX_KICK} = $opt_kick;
393 if (defined $opt_gecos)
395 $config{MAX_GECOS} = $opt_gecos;
397 if (defined $opt_away)
399 $config{MAX_AWAY} = $opt_away;
402 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
403 $config{HAS_OPENSSL} = $1;
405 $config{HAS_OPENSSL} = "";
408 if ($config{GCCVER} eq "") {
409 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
413 # Get and Set some important vars..
418 unlink(".config.cache");
421 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
426 chomp($topdir = getcwd());
427 $this = resolve_directory($topdir); # PWD, Regardless.
429 # Does the cache file exist?
431 # No, No it doesn't.. *BASH*
432 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
435 # We've Loaded the cache file and all our variables..
436 print "Updating files...\n";
438 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
440 print "Disabling debug information (-g).\n";
441 $config{OPTIMISATI} = "";
444 $has_epoll = $config{HAS_EPOLL};
445 $has_ports = $config{HAS_PORTS};
446 $has_kqueue = $config{HAS_KQUEUE};
455 print "Configure update failed: $@\n";
463 chomp($topdir = getcwd());
464 $this = resolve_directory($topdir); # PWD, Regardless.
466 # Does the cache file exist?
468 # No, No it doesn't.. *BASH*
469 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
472 # We've Loaded the cache file and all our variables..
473 print "Updating files...\n";
475 $has_epoll = $config{HAS_EPOLL};
476 $has_ports = $config{HAS_PORTS};
477 $has_kqueue = $config{HAS_KQUEUE};
486 print "Module update failed: $@\n";
496 open(FH,"<.svn/entries") or $fail = 1;
498 print "This is not an SVN copy of InspIRCd.\n";
505 open my $fd, "-|", "svn update";
506 my $configurechanged = 0; # Needs ./configure -update
507 my $coredirchanged = 0; # Needs ./configure -update
508 my $moduledirchanged = 0; # Needs ./configure -modupdate
509 my $rootincchanged = 0;
511 while (defined(my $line = <$fd>))
515 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
516 ($action, $file) = ($1, $2);
519 push @conflicted, $file;
520 if ($file eq "configure")
522 $configurechanged = 1;
524 elsif ($file =~ m#^src/modules#)
526 $moduledirchanged = 1;
528 elsif ($file =~ m#^src/#)
532 elsif ($file =~ m/^\..*\.inc$/)
537 elsif ($action eq "U" || $action eq "G")
539 if ($file eq "configure")
541 $configurechanged = 1;
543 elsif ($file =~ m/^\..*\.inc$/)
548 elsif ($action eq "A" || $action eq "D")
550 if ($file =~ m#^src/modules#)
552 $moduledirchanged = 1;
554 elsif ($file =~ m#^src/#)
560 unless (close $fd) # close() waits for exit and returns false if the command failed
564 print STDERR "Problem updating from SVN, please check above for errors\n";
568 print STDERR "Failed to run SVN: $!\n";
572 if (scalar(@conflicted) > 0)
574 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
575 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate\n", (($coredirchanged || $configurechanged) ? "" : "mod");
576 print "Conflicted files: " . join ", ", @conflicted . "\n";
579 if ($configurechanged || $coredirchanged)
581 system("perl configure -update");
583 elsif ($moduledirchanged || $rootincchanged)
585 system("perl configure -modupdate");
589 print "No need to update Makefiles.\n";
591 if (defined $opt_rebuild) {
592 system("make install");
597 print "Running non-interactive configure...\n" unless $interactive;
598 print "Checking for cache from previous configure... ";
599 print ((!getcache()) ? "not found\n" : "found\n");
600 print "Checking operating system version... ";
601 print getosflags() . "\n";
603 printf "Checking if stdint.h exists... ";
604 $config{HAS_STDINT} = "true";
606 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
607 if ($config{HAS_STDINT} eq "true") {
610 print "yes\n" if $config{HAS_STDINT} eq "true";
611 print "no\n" if $config{HAS_STDINT} eq "false";
613 printf "Checking if strlcpy exists... ";
614 # Perform the strlcpy() test..
615 $config{HAS_STRLCPY} = "false";
617 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
619 while (defined(my $line = <STRLCPY>)) {
621 # try and find the delcaration of:
622 # size_t strlcpy(...)
623 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
624 $config{HAS_STRLCPY} = "true";
629 print "yes\n" if $config{HAS_STRLCPY} eq "true";
630 print "no\n" if $config{HAS_STRLCPY} eq "false";
632 printf "Checking if kqueue exists... ";
635 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
637 while (defined(my $line = <KQUEUE>)) {
639 # try and find the delcaration of:
641 if ($line =~ /int(\0x9|\s)+kqueue/) {
647 print "yes\n" if $has_kqueue == 1;
648 print "no\n" if $has_kqueue == 0;
650 printf "Checking if epoll exists... ";
653 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
659 my $kernel = `uname -r`;
661 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
666 # Suggestion from nenolod, weed out odd systems which have glibc built
667 # against 2.4 kernels (ick)
668 my $kernel_arch = `uname -p`;
672 if ($kernel_arch =~ /x86_64/) {
673 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
676 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
680 while (defined(my $line = <FH>))
683 if ($line =~ /GNU C Library .* version (.*?) /)
686 $libcv =~ /(\d+\.\d+)/;
689 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
692 # Fix for some retarded libc builds, strip off >> and << etc.
693 $kernelv =~ /(\d+\.\d+)/;
701 printf "libc too old: $libcv... ";
706 printf "libc built against older kernel $kernelv... ";
711 print "yes\n" if $has_epoll == 1;
712 print "no\n" if $has_epoll == 0;
714 printf "Checking if Solaris I/O completion ports are available... ";
716 our $system = `uname -s`;
718 $has_ports = 1 if ($system eq "SunOS");
721 my $kernel = `uname -r`;
723 if (($kernel !~ /^5\.1./)) {
727 print "yes\n" if $has_ports == 1;
728 print "no\n" if $has_ports == 0;
730 $config{HAS_EPOLL} = $has_epoll;
731 $config{HAS_KQUEUE} = $has_kqueue;
733 printf "Checking for libgnutls... ";
734 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
736 $config{HAS_GNUTLS} = "y";
739 $config{HAS_GNUTLS} = "n";
742 printf "Checking for openssl... ";
743 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
745 $config{HAS_OPENSSL} = "y";
748 $config{HAS_OPENSSL} = "n";
751 printf "Checking if you are running an ancient, unsupported OS... ";
752 if ($config{OSNAME} =~ /FreeBSD/i)
754 my $version = `uname -r`;
755 if ($version =~ /^4\./)
757 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
760 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
761 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
766 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
772 print "no ($version)\n";
778 print "no ($config{OSNAME})\n";
781 ################################################################################
782 # BEGIN INTERACTIVE PART #
783 ################################################################################
788 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
791 my $rev = getrevision();
792 # Display Introduction Message..
794 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
795 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
797 *** If you are unsure of any of these values, leave it blank for ***
798 *** standard settings that will work, and your server will run ***
799 *** using them. Please consult your IRC network admin if in doubt. ***
801 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
802 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
803 dir, otherwise you won't have a config file!
805 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
806 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
809 print " (Non-SVN build)";
813 $config{CHANGE_COMPILER} = "n";
814 print "I have detected the following compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
816 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
817 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
818 should NOT be used. You should probably specify a newer compiler.\n\n";
819 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
820 if ($config{CHANGE_COMPILER} =~ /y/i) {
821 print "What command do you want to use to invoke your compiler?\n";
822 print "[\e[1;32m$config{CC}\e[0m] -> ";
823 chomp($config{CC} = <STDIN>);
824 if ($config{CC} eq "") {
827 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
829 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
830 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
831 if ($config{GCCVER} < 3) {
832 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
836 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
843 # Directory Settings..
844 my $tmpbase = $config{BASE_DIR};
845 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
846 if ($tmpbase ne $config{BASE_DIR}) {
847 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
848 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
849 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
850 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
853 dir_check("are the configuration files", "CONFIG_DIR");
854 dir_check("are the modules to be compiled to", "MODULE_DIR");
855 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
856 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
859 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?");
863 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?");
867 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?");
870 my $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
871 if (!$chose_hiperf) {
872 print "No high-performance socket engines are available, or you chose\n";
873 print "not to enable one. Defaulting to select() engine.\n\n";
876 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
879 if ($config{IPV6} eq "y") {
880 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";
881 $config{SUPPORT_IP6LINKS} = "y";
883 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? If you are using a recent operating system and are\nunsure, answer yes. If you answer 'no' here, your InspIRCd server will\nbe unable to parse IPV6 addresses (e.g. for CIDR bans)\n\nEnable linking to servers which have IPV6 enabled?");
887 $config{USE_FREEBSD_BASE_SSL} = "n";
888 $config{USE_FREEBSD_PORTS_SSL} = "n";
889 if ($config{HAS_OPENSSL_PORT} ne "")
891 $config{USE_FREEBSD_PORTS_SSL} = "y";
892 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
893 print "version \e[1;32m".$config{HAS_OPENSSL_PORT}."\e[0m. Your base system OpenSSL is version \e[1;32m".$openssl_ver."\e[0m.\n\n";
894 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
896 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
898 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
900 # update to port version
901 $openssl_ver = $config{HAS_OPENSSL_PORT};
906 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
909 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
910 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
911 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
912 print "instead, you should enable the OpenSSL module yourself\n";
913 print "by copying it from src/modules/extra to src/modules.\n\n";
914 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
915 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
918 if ($config{HAS_GNUTLS} eq "y") {
919 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
920 if ($config{USE_GNUTLS} eq "y") {
921 print "\nUsing GnuTLS SSL module.\n";
923 } elsif ($config{HAS_OPENSSL} eq "y") {
924 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
925 if ($config{USE_OPENSSL} eq "y") {
926 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
930 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";
933 print "\nThe following questions will ask you for various figures relating\n";
934 print "To your IRCd install. Please note that these should usually be left\n";
935 print "as defaults unless you have a real reason to change them. If they\n";
936 print "changed, then the values must be identical on all servers on your\n";
937 print "network, or malfunctions and/or crashes may occur, with the exception\n";
938 print "of the 'maximum number of clients' setting which may be different on\n";
939 print "different servers on the network.\n\n";
941 promptnumeric("length of nicknames", "NICK_LENGT");
942 promptnumeric("length of channel names", "CHAN_LENGT");
943 promptnumeric("number of mode changes in one line", "MAXI_MODES");
944 promptnumeric("length of an ident (username)", "MAX_IDENT");
945 promptnumeric("length of a quit message", "MAX_QUIT");
946 promptnumeric("length of a channel topic", "MAX_TOPIC");
947 promptnumeric("length of a kick message", "MAX_KICK");
948 promptnumeric("length of a GECOS (real name)", "MAX_GECOS");
949 promptnumeric("length of an away message", "MAX_AWAY");
954 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
956 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
959 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
961 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
966 if ($config{USE_GNUTLS} eq "y") {
967 unless (-r "src/modules/m_ssl_gnutls.cpp") {
968 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
969 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
974 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
975 print "SSL Certificates Not found, Generating.. \n\n
976 *************************************************************
977 * Generating the Private Key may take some time, go grab a *
978 * Coffee. Even better, to generate some more entropy if it *
979 * is taking a while, open another console and type du / a *
980 * few times and get that HD going :) Then answer the *
981 * Questions which follow. If you are unsure, just hit enter *
982 *************************************************************\n\n";
983 $failed = make_gnutls_cert();
985 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
987 print "\nCertificate generation complete, copying to config directory... ";
988 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
989 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
994 print "SSL Certificates found, skipping.\n\n";
999 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
1001 } elsif ($config{USE_OPENSSL} eq "y") {
1002 unless (-r "src/modules/m_ssl_openssl.cpp") {
1003 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
1004 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
1010 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
1011 print "SSL Certificates Not found, Generating.. \n\n
1012 *************************************************************
1013 * Generating the certificates may take some time, go grab a *
1014 * coffee, or something. *
1015 *************************************************************\n\n";
1016 make_openssl_cert();
1017 print "\nCertificate generation complete, copying to config directory... ";
1018 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
1019 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
1020 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
1023 print "SSL Certificates found, skipping.\n\n"
1028 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
1031 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
1032 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
1040 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
1041 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
1042 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
1043 print "modules in your config. This configure script has added those modules to the\n";
1044 print "build process. For more info please refer to:\n";
1045 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
1047 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
1048 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
1049 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";
1052 if ($config{GCCVER} < "3") {
1054 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
1055 GCC 2.x series compilers only had partial (read as broken) C++ support, and
1056 your compile will most likely fail horribly! If you have any problems, do NOT
1057 report them to the bugtracker or forums without first upgrading your compiler
1058 to a newer 3.x or 4.x (or whatever is available currently) version.
1062 ################################################################################
1063 # HELPER FUNCTIONS #
1064 ################################################################################
1066 # Retrieves the .config.cache file, and loads values into the main config hash.
1067 open(CACHE, ".config.cache") or return 0;
1070 # Ignore Blank lines, and comments..
1073 my ($key, $value) = split("=", $_, 2);
1074 $value =~ /^\"(.*)\"$/;
1075 # Do something with data here!
1083 # Dump the contents of %config
1084 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1085 open(FILEHANDLE, ">.config.cache");
1086 foreach my $key (keys %config) {
1087 print FILEHANDLE "$key=\"$config{$key}\"\n";
1093 my ($desc, $hash_key) = @_;
1095 while (!$complete) {
1096 print "In what directory $desc?\n";
1097 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1098 chomp(my $var = <STDIN>);
1100 $var = $config{$hash_key};
1102 if ($var =~ /^\~\/(.+)$/) {
1103 # Convert it to a full path..
1104 $var = resolve_directory($ENV{HOME} . "/" . $1);
1106 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1108 # Assume relative Path was given.. fill in the rest.
1109 $var = $this . "/$var";
1112 $var = resolve_directory($var);
1114 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1115 chomp(my $tmp = <STDIN>);
1116 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1117 # Attempt to Create the Dir..
1120 File::Path::mkpath($var, 0, 0777);
1123 unless (defined($chk) && -d $var) {
1124 print "Unable to create directory. ($var)\n\n";
1129 # They said they don't want to create, and we can't install there.
1134 if (!is_dir($var)) {
1135 # Target exists, but is not a directory.
1136 print "File $var exists, but is not a directory.\n\n";
1140 # Either Dir Exists, or was created fine.
1141 $config{$hash_key} = $var;
1151 # Beware: Linux sets it's own cflags below for some retarded reason
1152 $config{LDLIBS} = "-pthread -lstdc++";
1153 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1154 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1155 $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared" unless defined $opt_disablerpath;
1156 $config{MAKEPROG} = "make";
1158 if ($config{OSNAME} =~ /darwin/i) {
1159 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1160 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1161 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1164 if ($config{OSNAME} =~ /OpenBSD/i) {
1165 $config{MAKEPROG} = "gmake";
1166 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1167 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1168 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1169 # if theyre not running this, configure lets the build continue but they probably wont manage to
1170 # compile as this standard version is 2.95.3!
1172 $config{CC} = "eg++";
1173 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1178 if ($config{OSNAME} =~ /Linux/i) {
1179 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1180 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1181 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1182 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1183 $config{MAKEPROG} = "make";
1186 if ($config{OSNAME} =~ /FreeBSD/i) {
1187 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1188 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1191 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1193 # solaris/sunos needs these
1194 # socket = bsd sockets api
1196 # rt = POSIX realtime extensions
1197 # resolv = inet_aton only (why isnt this in nsl?!)
1198 $config{MAKEPROG} = "gmake";
1199 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1203 if($config{OSNAME} =~ /MINGW32/i)
1205 # All code is position-independent on windows
1206 $config{FLAGS} =~ s/-fPIC //;
1210 return $config{OSNAME};
1213 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1216 my($writeheader) = @_;
1218 # First File.. inspircd_config.h
1219 chomp(my $incos = `uname -n -s -r`);
1220 chomp(my $version = `sh src/version.sh`);
1221 chomp(my $revision2 = getrevision());
1222 if ($writeheader == 1)
1224 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1225 open(FILEHANDLE, ">include/inspircd_config.h");
1226 my $NL = $config{NICK_LENGT}+1;
1227 my $CL = $config{CHAN_LENGT}+1;
1228 print FILEHANDLE <<EOF;
1229 /* Auto generated by configure, do not modify! */
1230 #ifndef __CONFIGURATION_AUTO__
1231 #define __CONFIGURATION_AUTO__
1233 /* this is for windows support. */
1234 #define CoreExport /**/
1235 #define DllExport /**/
1237 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1238 #define MOD_PATH "$config{MODULE_DIR}"
1239 #define VERSION "$version"
1240 #define REVISION "$revision2"
1241 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1244 #define MAXMODES $config{MAXI_MODES}
1245 #define IDENTMAX $config{MAX_IDENT}
1246 #define MAXQUIT $config{MAX_QUIT}
1247 #define MAXTOPIC $config{MAX_TOPIC}
1248 #define MAXKICK $config{MAX_KICK}
1249 #define MAXGECOS $config{MAX_GECOS}
1250 #define MAXAWAY $config{MAX_AWAY}
1251 #define OPTIMISATION $config{OPTIMITEMP}
1252 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1253 #define SYSTEM "$incos"
1256 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1258 if ($config{OSNAME} =~ /SunOS/i) {
1259 print FILEHANDLE "#define IS_SOLARIS\n";
1261 if ($config{OSNAME} =~ /MINGW32/i) {
1262 print FILEHANDLE "#define IS_MINGW\n";
1264 if ($config{GCCVER} >= 3) {
1265 print FILEHANDLE "#define GCC3\n";
1267 if ($config{HAS_STRLCPY} eq "true") {
1268 print FILEHANDLE "#define HAS_STRLCPY\n";
1270 if ($config{HAS_STDINT} eq "true") {
1271 print FILEHANDLE "#define HAS_STDINT\n";
1273 if ($config{IPV6} =~ /y/i) {
1274 print FILEHANDLE "#define IPV6\n";
1276 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1277 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1280 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1281 print FILEHANDLE "#define USE_KQUEUE\n";
1282 $se = "socketengine_kqueue";
1285 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1286 print FILEHANDLE "#define USE_EPOLL\n";
1287 $se = "socketengine_epoll";
1290 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1291 print FILEHANDLE "#define USE_PORTS\n";
1292 $se = "socketengine_ports";
1295 # user didn't choose either epoll or select for their OS.
1296 # default them to USE_SELECT (ewwy puke puke)
1298 print FILEHANDLE "#define USE_SELECT\n";
1299 $se = "socketengine_select";
1301 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1307 open(FILEHANDLE, ">include/inspircd_se_config.h");
1308 print FILEHANDLE <<EOF;
1309 /* Auto generated by configure, do not modify or commit to svn! */
1310 #ifndef __CONFIGURATION_SOCKETENGINE__
1311 #define __CONFIGURATION_SOCKETENGINE__
1313 #include "socketengines/$se.h"
1321 # Create a Modules List..
1323 foreach my $i (@modlist)
1325 $modules .= "m_".$i.".so ";
1327 chomp($modules); # Remove Redundant whitespace..
1329 opendir(DIRHANDLE, "src/modules");
1330 foreach my $name (sort readdir(DIRHANDLE)) {
1331 if ($name =~ /^m_(.+?)$/) {
1332 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1333 closedir(MDIRHANDLE);
1334 $modules .= "$name.so ";
1335 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name.so\n";
1339 closedir(DIRHANDLE);
1342 # Write all .in files.
1345 my $exe = "inspircd";
1347 # Do this once here, and cache it in the .*.inc files,
1348 # rather than attempting to read src/version.sh from
1349 # compiled code -- we might not have the source to hand.
1350 # Fix for bug#177 by Brain.
1352 chomp($version = `sh ./src/version.sh`);
1353 chomp(my $revision = getrevision());
1354 $version = "$version(r$revision)";
1356 # We can actually parse any file starting with . and ending with .inc,
1357 # but right now we only parse .inspircd.inc to form './inspircd'
1359 print "Writing \e[1;32mMakefiles\e[0m\n";
1360 write_dynamic_modules_makefile();
1361 write_dynamic_makefile();
1363 opendir(DIRHANDLE, $this);
1365 foreach my $name (sort readdir(DIRHANDLE)) {
1366 if ($name =~ /^\.(.+)\.inc$/) {
1369 # Bug #353, omit this on non-darwin
1370 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1372 # All .name.inc files need parsing!
1374 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1375 while (<FILEHANDLE>) {
1380 print "Writing \e[1;32m$file\e[0m ...\n";
1381 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1382 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1383 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1384 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1385 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1386 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1387 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1388 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1389 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1390 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1391 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1392 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1393 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1394 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1395 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1396 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1397 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1398 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1399 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1401 open(FILEHANDLE, ">$file");
1402 print FILEHANDLE $tmp;
1405 closedir(DIRHANDLE);
1407 # Make inspircd executable!
1408 chmod 0744, 'inspircd';
1411 sub write_dynamic_modules_makefile {
1412 # Modules Makefile..
1413 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1414 open(FILEHANDLE, ">src/modules/Makefile");
1417 # Module Makefile Header
1419 print FILEHANDLE <<EOF;
1420 ###################################################
1421 # Copyright 2002-2007 The InspIRCd Development Team
1422 # http://www.inspircd.org/wiki/index.php/Credits
1424 # Thanks to Andrew Church <achurch\@achurch.org>
1425 # for assisting with making this work right.
1427 # Automatically Generated by ./configure to add a
1428 # modules please run ./configure -modupdate
1429 ###################################################
1435 if ($config{OSNAME} =~ /darwin/) {
1436 print FILEHANDLE <<EOCHEESE;
1438 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1442 print FILEHANDLE <<EOCHEESE;
1444 PICLDFLAGS = -fPIC -DPIC -shared
1450 # End Module Makefile Header
1453 # Create a Modules List..
1457 foreach my $i (@modlist) {
1459 # Write Entry to the MakeFile
1461 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1462 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1463 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1465 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1468 if (nopedantic("src/modules/m_".$i.".cpp"))
1471 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
1472 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1478 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
1479 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1482 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1483 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1485 # End Write Entry to the MakeFile
1489 opendir(DIRHANDLE, "src/modules");
1490 foreach my $name (sort readdir(DIRHANDLE)) {
1491 if ($name =~ /^m_(.+?)$/) {
1496 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1497 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1498 read_module_directory("src/modules/$name", $name);
1499 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1500 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";
1501 if ($config{IS_DARWIN} eq "YES") {
1502 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1504 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1506 print FILEHANDLE "\n$mfrules\n";
1507 closedir(MDIRHANDLE);
1508 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1512 closedir(DIRHANDLE);
1515 sub read_module_directory {
1516 my ($dpath, $reldpath) = @_;
1518 if (opendir(MDIRHANDLE, $dpath) == 0) {
1522 foreach my $fname (sort readdir(MDIRHANDLE)) {
1523 if ($fname =~ /\.cpp$/) {
1524 my $cmflags = getcompilerflags("$dpath/$fname");
1525 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1526 my $deps = getdependencies("$dpath/$fname");
1528 $oname =~ s/\.cpp$/.o/g;
1529 $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";
1530 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1531 $mobjs = $mobjs . " $reldpath/$oname";
1534 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1535 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1542 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1543 # dependencies which are not relevent in C++.
1547 open (CPP, "<$file") or die("Can't open $file for reading!");
1552 foreach my $d (@ignoredeps)
1558 foreach my $dep (@immutabledeps)
1560 $immutable = $immutable . "../include/$dep ";
1562 $immutable =~ s/ $//g;
1564 while (defined(my $line = <CPP>))
1567 if ($line =~ /#include "(.+\.h)"/)
1569 if (!exists($dupe{$1}))
1571 $retlist = $retlist . "../include/$1 ";
1577 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1580 sub write_dynamic_makefile
1584 my %existing_install_list = ();
1585 opendir(DIRHANDLE, "src/commands");
1586 foreach my $name (sort readdir(DIRHANDLE))
1588 if ($name =~ /^cmd_(.+)\.cpp$/)
1590 $cmdlist[$i++] = $1;
1591 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1592 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1595 closedir(DIRHANDLE);
1599 $config{USE_EPOLL} = 0;
1603 $config{USE_KQUEUE} = 0;
1607 $config{USE_PORTS} = 0;
1610 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1612 print "Scanning \e[1;32m$dir\e[0m for core files ";
1613 opendir(DIRHANDLE, $dir);
1614 foreach my $name (sort readdir(DIRHANDLE))
1616 if ($name =~ /\.cpp$/)
1618 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1620 while (defined(my $line = <CPP>))
1623 if ($line =~ /\/\* \$Core: (\w+) \*\//i)
1625 $filelist{$name} = $1;
1627 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1629 $specialdeps{$name} = $1;
1631 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1633 $extraobjects{$name} = $1;
1635 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1637 $extrabuildlines{$name} = $1;
1639 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1641 $extrasources{$name} = $1;
1643 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1645 if (defined $config{$1})
1647 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1650 while (defined($line = <CPP>))
1653 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1654 last if ($line =~ /\/\* \$EndIf \*\//i);
1659 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1661 if (!exists($existing_install_list{$1}))
1663 $existing_install_list{$1} = 1;
1664 my $idir = (split(' ',$1))[1];
1665 my $ifile = (split(' ',$1))[0];
1666 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1667 $ifile =~ s/.*\///g;
1668 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1671 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1673 if (!exists($existing_install_list{$1}))
1675 $existing_install_list{$1} = 1;
1676 my $idir = (split(' ',$1))[1];
1677 my $ifile = (split(' ',$1))[0];
1678 $install_list = $install_list . " -cp $1\n";
1679 $ifile =~ s/.*\///g;
1680 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1687 closedir(DIRHANDLE);
1691 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1694 my $all_libsonly = "";
1695 my $libraryext = "";
1699 if ($config{IS_DARWIN} eq "YES")
1701 $libraryext = "dylib";
1702 $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 "
1707 $RPATH = "-Wl,--rpath -Wl,$config{LIBRARY_DIR}" unless defined $opt_disablerpath;
1708 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include $RPATH \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1711 foreach my $cpp (sort keys %filelist)
1713 $all = $all . $filelist{$cpp} . "." . $libraryext . " ";
1714 $all_libsonly = $all_libsonly . $filelist{$cpp} . "." . $libraryext . " ";
1715 $install_list = $install_list . " -install -m \$(INSTMODE) src/" . $filelist{$cpp} . "." . $libraryext . " \$(LIBPATH)\n";
1716 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/" . $filelist{$cpp} . "." . $libraryext . "\n";
1718 $all = $all . "moo inspircd\n";
1720 $othercrap = $othercrap . " $all_libsonly\n\n";
1722 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1725 CC = im a cheezeball
1726 CXXFLAGS = -I../include \${FLAGS}
1727 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1728 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1732 print FH "$all\n\n";
1734 my $deps = calcdeps("src/inspircd.cpp");
1735 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1736 print FH "$othercrap\n";
1738 foreach my $cpp (sort keys %filelist)
1740 my $thislib = $filelist{$cpp} . "." . $libraryext;
1744 $objs =~ s/\.cpp$/.o/;
1745 if (exists($extraobjects{$cpp}))
1747 $objs = $objs . " " . $extraobjects{$cpp};
1749 if (exists($extrasources{$cpp}))
1751 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1753 if ($config{IS_DARWIN} eq "YES")
1755 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1759 if (defined $opt_disablerpath)
1761 $libcrap = " -shared";
1765 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1768 $deps = calcdeps("src/$cpp");
1769 if (exists($extrasources{$cpp}))
1771 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1773 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1776 $deps = $deps . $d . " ";
1780 print FH $thislib . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1781 print FH " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1782 if (exists($extrabuildlines{$cpp}))
1784 print FH " " . $extrabuildlines{$cpp} . "\n";
1786 print FH " \@../make/run-cc.pl \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1789 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1791 # close main makefile
1795 # generate a list of .so
1796 foreach my $cmd (@cmdlist) {
1797 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1800 # and now reopen the commands makefile
1801 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1804 CXXFLAGS = -I../../include \${FLAGS}
1811 # now print the command file details.
1812 foreach my $cmd (@cmdlist) {
1814 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
1815 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1821 # Routine to list out the extra/ modules that have been enabled.
1822 # Note: when getting any filenames out and comparing, it's important to lc it if the
1823 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1824 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1825 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1826 sub list_extras () {
1829 my $srcdir = File::Spec->catdir("src", "modules");
1830 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1833 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1834 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1837 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1838 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1841 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1843 EXTRA: for my $extra (@extras) {
1844 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1845 next if ($extra eq '.svn');
1846 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1847 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1848 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1849 if (-l $abs_source) {
1850 # Symlink, is it in the right place?
1851 my $targ = readlink($abs_source);
1852 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1853 if ($abs_targ eq $abs_extra) {
1854 $extras{$extra} = "\e[32;1menabled\e[0m";
1856 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1858 } elsif (-e $abs_source) {
1859 my ($devext, $inoext) = stat($abs_extra);
1860 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1862 if ($devsrc == $devext && $inosrc == $inoext) {
1863 $extras{$extra} = "\e[32;1menabled\e[0m";
1865 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1868 open my $extfd, "<", $abs_extra;
1869 open my $srcfd, "<", $abs_source;
1871 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1872 $extras{$extra} = "\e[32;1menabled\e[0m";
1874 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1878 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1881 # Now let's add dependency info
1882 for my $extra (keys(%extras)) {
1883 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1884 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1885 my @deps = split / +/, getdependencies($abs_extra);
1886 for my $dep (@deps) {
1887 if (exists($extras{$dep})) {
1888 my $ref = \$extras{$dep}; # Take reference.
1889 if ($$ref !~ m/needed by/) {
1890 # First dependency found.
1891 if ($$ref =~ m/enabled/) {
1892 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1894 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1895 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1898 if ($$ref =~ m/enabled/) {
1899 $$ref .= ", \e[32;1m$extra\e[0m";
1901 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1907 for my $extra (sort {$a cmp $b} keys(%extras)) {
1908 my $text = $extras{$extra};
1909 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1910 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1912 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1915 return keys(%extras) if wantarray; # Can be used by manage_extras.
1918 sub enable_extras (@) {
1920 for my $extra (@extras) {
1921 my $extrapath = "src/modules/extra/$extra";
1922 if (!-e $extrapath) {
1923 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1926 my $source = "src/modules/$extra";
1928 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1931 # Get dependencies, and add them to be processed.
1932 my @deps = split / +/, getdependencies($extrapath);
1933 for my $dep (@deps) {
1934 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1935 if (!-e "src/modules/$dep") {
1936 if (-e "src/modules/extra/$dep") {
1937 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1940 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";
1944 print "Enabling $extra ... \n";
1945 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1949 sub disable_extras (@)
1951 opendir my $dd, "src/modules/extra/";
1952 my @files = readdir($dd);
1955 EXTRA: for my $extra (@extras) {
1956 my $extrapath = "src/modules/extra/$extra";
1957 my $source = "src/modules/$extra";
1958 if (!-e $extrapath) {
1959 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1962 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1963 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";
1966 # Check if anything needs this.
1967 for my $file (@files) {
1968 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1969 # File depends on this extra...
1970 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1971 # And is both enabled and not about to be disabled.
1972 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1973 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1979 print "Disabling $extra ... \n";
1980 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";