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 ($^O eq "freebsd")
247 # default: use base ssl
248 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
249 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
253 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
254 $config{HAS_OPENSSL_PORT} = "";
257 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
258 chomp(our $openssl_ver = $config{HAS_OPENSSL});
259 $config{USE_GNUTLS} = "n";
260 if (defined $opt_use_gnutls)
262 $config{USE_GNUTLS} = "y"; # Use gnutls.
264 $config{USE_OPENSSL} = "n"; # Use openssl.
265 if (defined $opt_use_openssl)
267 $config{USE_OPENSSL} = "y";
270 # no, let's not change these.
271 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
272 if (!defined $opt_disable_debug)
274 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
278 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
281 $config{NICK_LENGT} = "31"; # Default Nick Length
282 if (defined $opt_nick_length)
284 $config{NICK_LENGT} = $opt_nick_length;
286 $config{CHAN_LENGT} = "64"; # Default Channel Name Length
287 if (defined $opt_chan_length)
289 $config{CHAN_LENGT} = $opt_chan_length;
291 $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once.
292 if (defined $opt_modes)
294 $config{MAXI_MODES} = $opt_modes;
296 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
297 $config{HAS_STDINT} = "false"; # stdint.h check
298 $config{USE_KQUEUE} = "y"; # kqueue enabled
299 if (defined $opt_kqueue)
301 $config{USE_KQUEUE} = "y";
303 if (defined $opt_nokqueue)
305 $config{USE_KQUEUE} = "n";
307 $config{USE_EPOLL} = "y"; # epoll enabled
308 if (defined $opt_epoll)
310 $config{USE_EPOLL} = "y";
312 if (defined $opt_noepoll)
314 $config{USE_EPOLL} = "n";
316 $config{USE_PORTS} = "y"; # epoll enabled
317 if (defined $opt_ports)
319 $config{USE_PORTS} = "y";
321 if (defined $opt_noports)
323 $config{USE_PORTS} = "n";
325 $config{IPV6} = "n"; # IPv6 support (experimental)
326 if (defined $opt_ipv6)
330 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
331 if (defined $opt_ipv6links)
333 $config{SUPPORT_IP6LINKS} = "y";
335 if (defined $opt_noipv6links)
337 $config{SUPPORT_IP6LINKS} = "n";
339 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
340 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
341 $config{OSNAME} = $^O; # Operating System Name
342 $config{IS_DARWIN} = "NO"; # Is OSX?
343 $config{STARTSCRIPT} = "inspircd"; # start script?
344 $config{DESTINATION} = "BASE"; # Is target path.
345 $config{EXTRA_DIR} = ""; # Is empty.
346 if ($config{OSNAME} =~ /darwin/i)
348 $config{IS_DARWIN} = "YES";
349 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
350 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
351 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
353 $config{CC} = "g++"; # C++ compiler
356 $config{CC} = $opt_cc;
358 our $exec = $config{CC} . " -dumpversion | cut -c 1";
359 chomp($config{GCCVER} = `$exec`); # Major GCC Version
360 $config{MAKEORDER} = "ircd mods"; # build order
361 $config{MAX_IDENT} = "12"; # max ident size
362 $config{MAX_QUIT} = "255"; # max quit message size
363 $config{MAX_TOPIC} = "307"; # max topic size
364 $config{MAX_KICK} = "255"; # max kick message size
365 $config{MAX_GECOS} = "128"; # max GECOS size
366 $config{MAX_AWAY} = "200"; # max AWAY size
367 $config{MAXBUF} = "512"; # Max buffer size
368 if (defined $opt_ident)
370 $config{MAX_IDENT} = $opt_ident;
372 if (defined $opt_quit)
374 $config{MAX_QUIT} = $opt_quit;
376 if (defined $opt_topic)
378 $config{MAX_TOPIC} = $opt_topic;
380 if (defined $opt_kick)
382 $config{MAX_KICK} = $opt_kick;
384 if (defined $opt_gecos)
386 $config{MAX_GECOS} = $opt_gecos;
388 if (defined $opt_away)
390 $config{MAX_AWAY} = $opt_away;
393 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
394 $config{HAS_OPENSSL} = $1;
396 $config{HAS_OPENSSL} = "";
399 if ($config{GCCVER} eq "") {
400 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
404 # Get and Set some important vars..
409 unlink(".config.cache");
412 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
417 chomp($topdir = getcwd());
418 $this = resolve_directory($topdir); # PWD, Regardless.
420 # Does the cache file exist?
422 # No, No it doesn't.. *BASH*
423 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
426 # We've Loaded the cache file and all our variables..
427 print "Updating files...\n";
429 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
431 print "Disabling debug information (-g).\n";
432 $config{OPTIMISATI} = "";
435 $has_epoll = $config{HAS_EPOLL};
436 $has_ports = $config{HAS_PORTS};
437 $has_kqueue = $config{HAS_KQUEUE};
446 print "Configure update failed: $@\n";
454 chomp($topdir = getcwd());
455 $this = resolve_directory($topdir); # PWD, Regardless.
457 # Does the cache file exist?
459 # No, No it doesn't.. *BASH*
460 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
463 # We've Loaded the cache file and all our variables..
464 print "Updating files...\n";
466 $has_epoll = $config{HAS_EPOLL};
467 $has_ports = $config{HAS_PORTS};
468 $has_kqueue = $config{HAS_KQUEUE};
477 print "Module update failed: $@\n";
487 open(FH,"<.svn/entries") or $fail = 1;
489 print "This is not an SVN copy of InspIRCd.\n";
496 open my $fd, "-|", "svn update";
497 my $configurechanged = 0; # Needs ./configure -update
498 my $coredirchanged = 0; # Needs ./configure -update
499 my $moduledirchanged = 0; # Needs ./configure -modupdate
500 my $rootincchanged = 0;
502 while (defined(my $line = <$fd>))
506 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
507 ($action, $file) = ($1, $2);
510 push @conflicted, $file;
511 if ($file eq "configure")
513 $configurechanged = 1;
515 elsif ($file =~ m#^src/modules#)
517 $moduledirchanged = 1;
519 elsif ($file =~ m#^src/#)
523 elsif ($file =~ m/^\..*\.inc$/)
528 elsif ($action eq "U" || $action eq "G")
530 if ($file eq "configure")
532 $configurechanged = 1;
534 elsif ($file =~ m/^\..*\.inc$/)
539 elsif ($action eq "A" || $action eq "D")
541 if ($file =~ m#^src/modules#)
543 $moduledirchanged = 1;
545 elsif ($file =~ m#^src/#)
551 unless (close $fd) # close() waits for exit and returns false if the command failed
555 print STDERR "Problem updating from SVN, please check above for errors\n";
559 print STDERR "Failed to run SVN: $!\n";
563 if (scalar(@conflicted) > 0)
565 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
566 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate\n", (($coredirchanged || $configurechanged) ? "" : "mod");
567 print "Conflicted files: " . join ", ", @conflicted . "\n";
570 if ($configurechanged || $coredirchanged)
572 system("perl configure -update");
574 elsif ($moduledirchanged || $rootincchanged)
576 system("perl configure -modupdate");
580 print "No need to update Makefiles.\n";
582 if (defined $opt_rebuild) {
583 system("make install");
588 print "Running non-interactive configure...\n" unless $interactive;
589 print "Checking for cache from previous configure... ";
590 print ((!getcache()) ? "not found\n" : "found\n");
591 print "Checking operating system version... ";
592 print getosflags() . "\n";
594 printf "Checking if stdint.h exists... ";
595 $config{HAS_STDINT} = "true";
597 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
598 if ($config{HAS_STDINT} eq "true") {
601 print "yes\n" if $config{HAS_STDINT} eq "true";
602 print "no\n" if $config{HAS_STDINT} eq "false";
604 printf "Checking if strlcpy exists... ";
605 # Perform the strlcpy() test..
606 $config{HAS_STRLCPY} = "false";
608 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
610 while (defined(my $line = <STRLCPY>)) {
612 # try and find the delcaration of:
613 # size_t strlcpy(...)
614 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
615 $config{HAS_STRLCPY} = "true";
620 print "yes\n" if $config{HAS_STRLCPY} eq "true";
621 print "no\n" if $config{HAS_STRLCPY} eq "false";
623 printf "Checking if kqueue exists... ";
626 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
628 while (defined(my $line = <KQUEUE>)) {
630 # try and find the delcaration of:
632 if ($line =~ /int(\0x9|\s)+kqueue/) {
638 print "yes\n" if $has_kqueue == 1;
639 print "no\n" if $has_kqueue == 0;
641 printf "Checking if epoll exists... ";
644 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
650 my $kernel = `uname -r`;
652 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
657 # Suggestion from nenolod, weed out odd systems which have glibc built
658 # against 2.4 kernels (ick)
659 my $kernel_arch = `uname -p`;
663 if ($kernel_arch =~ /x86_64/) {
664 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
667 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
671 while (defined(my $line = <FH>))
674 if ($line =~ /GNU C Library .* version (.*?) /)
677 $libcv =~ /(\d+\.\d+)/;
680 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
683 # Fix for some retarded libc builds, strip off >> and << etc.
684 $kernelv =~ /(\d+\.\d+)/;
692 printf "libc too old: $libcv... ";
697 printf "libc built against older kernel $kernelv... ";
702 print "yes\n" if $has_epoll == 1;
703 print "no\n" if $has_epoll == 0;
705 printf "Checking if Solaris I/O completion ports are available... ";
707 our $system = `uname -s`;
709 $has_ports = 1 if ($system eq "SunOS");
712 my $kernel = `uname -r`;
714 if (($kernel !~ /^5\.1./)) {
718 print "yes\n" if $has_ports == 1;
719 print "no\n" if $has_ports == 0;
721 $config{HAS_EPOLL} = $has_epoll;
722 $config{HAS_KQUEUE} = $has_kqueue;
724 printf "Checking for libgnutls... ";
725 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
727 $config{HAS_GNUTLS} = "y";
730 $config{HAS_GNUTLS} = "n";
733 printf "Checking for openssl... ";
734 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
736 $config{HAS_OPENSSL} = "y";
739 $config{HAS_OPENSSL} = "n";
742 printf "Checking if you are running an ancient, unsupported OS... ";
743 if ($config{OSNAME} =~ /FreeBSD/i)
745 my $version = `uname -r`;
746 if ($version =~ /^4\./)
748 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
751 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
752 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
757 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
763 print "no ($version)\n";
769 print "no ($config{OSNAME})\n";
772 ################################################################################
773 # BEGIN INTERACTIVE PART #
774 ################################################################################
779 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
782 my $rev = getrevision();
783 # Display Introduction Message..
785 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
786 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
788 *** If you are unsure of any of these values, leave it blank for ***
789 *** standard settings that will work, and your server will run ***
790 *** using them. Please consult your IRC network admin if in doubt. ***
792 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
793 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
794 dir, otherwise you won't have a config file!
796 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
797 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
800 print " (Non-SVN build)";
804 $config{CHANGE_COMPILER} = "n";
805 print "I have detected the following compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
807 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
808 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
809 should NOT be used. You should probably specify a newer compiler.\n\n";
810 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
811 if ($config{CHANGE_COMPILER} =~ /y/i) {
812 print "What command do you want to use to invoke your compiler?\n";
813 print "[\e[1;32m$config{CC}\e[0m] -> ";
814 chomp($config{CC} = <STDIN>);
815 if ($config{CC} eq "") {
818 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
820 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
821 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
822 if ($config{GCCVER} < 3) {
823 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
827 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
834 # Directory Settings..
835 my $tmpbase = $config{BASE_DIR};
836 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
837 if ($tmpbase ne $config{BASE_DIR}) {
838 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
839 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
840 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
841 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
844 dir_check("are the configuration files", "CONFIG_DIR");
845 dir_check("are the modules to be compiled to", "MODULE_DIR");
846 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
847 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
850 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?");
854 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?");
858 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?");
861 my $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
862 if (!$chose_hiperf) {
863 print "No high-performance socket engines are available, or you chose\n";
864 print "not to enable one. Defaulting to select() engine.\n\n";
867 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
870 if ($config{IPV6} eq "y") {
871 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";
872 $config{SUPPORT_IP6LINKS} = "y";
874 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)");
878 $config{USE_FREEBSD_BASE_SSL} = "n";
879 if ($config{HAS_OPENSSL_PORT} ne "")
881 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
882 print "version \e[1;32m".$config{HAS_OPENSSL_PORT}."\e[0m. Your base system OpenSSL is version\n";
883 print "\e[1;32m".$openssl_ver."\e[0m.\n";
884 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD base version?");
885 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
888 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
889 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
890 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
891 print "instead, you should enable the OpenSSL module yourself\n";
892 print "by copying it from src/modules/extra to src/modules.\n\n";
893 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
894 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
897 if ($config{HAS_GNUTLS} eq "y") {
898 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
899 if ($config{USE_GNUTLS} eq "y") {
900 print "\nUsing GnuTLS SSL module.\n";
902 } elsif ($config{HAS_OPENSSL} eq "y") {
903 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
904 if ($config{USE_OPENSSL} eq "y") {
905 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
909 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";
912 print "\nThe following questions will ask you for various figures relating\n";
913 print "To your IRCd install. Please note that these should usually be left\n";
914 print "as defaults unless you have a real reason to change them. If they\n";
915 print "changed, then the values must be identical on all servers on your\n";
916 print "network, or malfunctions and/or crashes may occur, with the exception\n";
917 print "of the 'maximum number of clients' setting which may be different on\n";
918 print "different servers on the network.\n\n";
920 promptnumeric("length of nicknames", "NICK_LENGT");
921 promptnumeric("length of channel names", "CHAN_LENGT");
922 promptnumeric("number of mode changes in one line", "MAXI_MODES");
923 promptnumeric("length of an ident (username)", "MAX_IDENT");
924 promptnumeric("length of a quit message", "MAX_QUIT");
925 promptnumeric("length of a channel topic", "MAX_TOPIC");
926 promptnumeric("length of a kick message", "MAX_KICK");
927 promptnumeric("length of a GECOS (real name)", "MAX_GECOS");
928 promptnumeric("length of an away message", "MAX_AWAY");
933 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
935 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
938 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
940 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
945 if ($config{USE_GNUTLS} eq "y") {
946 unless (-r "src/modules/m_ssl_gnutls.cpp") {
947 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
948 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
953 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
954 print "SSL Certificates Not found, Generating.. \n\n
955 *************************************************************
956 * Generating the Private Key may take some time, go grab a *
957 * Coffee. Even better, to generate some more entropy if it *
958 * is taking a while, open another console and type du / a *
959 * few times and get that HD going :) Then answer the *
960 * Questions which follow. If you are unsure, just hit enter *
961 *************************************************************\n\n";
962 $failed = make_gnutls_cert();
964 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
966 print "\nCertificate generation complete, copying to config directory... ";
967 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
968 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
973 print "SSL Certificates found, skipping.\n\n";
978 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
980 } elsif ($config{USE_OPENSSL} eq "y") {
981 unless (-r "src/modules/m_ssl_openssl.cpp") {
982 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
983 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
989 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
990 print "SSL Certificates Not found, Generating.. \n\n
991 *************************************************************
992 * Generating the certificates may take some time, go grab a *
993 * coffee, or something. *
994 *************************************************************\n\n";
996 print "\nCertificate generation complete, copying to config directory... ";
997 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
998 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
999 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
1002 print "SSL Certificates found, skipping.\n\n"
1007 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
1010 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
1011 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
1019 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
1020 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
1021 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
1022 print "modules in your config. This configure script has added those modules to the\n";
1023 print "build process. For more info please refer to:\n";
1024 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
1026 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
1027 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
1028 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";
1031 if ($config{GCCVER} < "3") {
1033 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
1034 GCC 2.x series compilers only had partial (read as broken) C++ support, and
1035 your compile will most likely fail horribly! If you have any problems, do NOT
1036 report them to the bugtracker or forums without first upgrading your compiler
1037 to a newer 3.x or 4.x (or whatever is available currently) version.
1041 ################################################################################
1042 # HELPER FUNCTIONS #
1043 ################################################################################
1045 # Retrieves the .config.cache file, and loads values into the main config hash.
1046 open(CACHE, ".config.cache") or return 0;
1049 # Ignore Blank lines, and comments..
1052 my ($key, $value) = split("=", $_, 2);
1053 $value =~ /^\"(.*)\"$/;
1054 # Do something with data here!
1062 # Dump the contents of %config
1063 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1064 open(FILEHANDLE, ">.config.cache");
1065 foreach my $key (keys %config) {
1066 print FILEHANDLE "$key=\"$config{$key}\"\n";
1072 my ($desc, $hash_key) = @_;
1074 while (!$complete) {
1075 print "In what directory $desc?\n";
1076 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1077 chomp(my $var = <STDIN>);
1079 $var = $config{$hash_key};
1081 if ($var =~ /^\~\/(.+)$/) {
1082 # Convert it to a full path..
1083 $var = resolve_directory($ENV{HOME} . "/" . $1);
1085 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1087 # Assume relative Path was given.. fill in the rest.
1088 $var = $this . "/$var";
1091 $var = resolve_directory($var);
1093 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1094 chomp(my $tmp = <STDIN>);
1095 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1096 # Attempt to Create the Dir..
1099 File::Path::mkpath($var, 0, 0777);
1102 unless (defined($chk) && -d $var) {
1103 print "Unable to create directory. ($var)\n\n";
1108 # They said they don't want to create, and we can't install there.
1113 if (!is_dir($var)) {
1114 # Target exists, but is not a directory.
1115 print "File $var exists, but is not a directory.\n\n";
1119 # Either Dir Exists, or was created fine.
1120 $config{$hash_key} = $var;
1130 # Beware: Linux sets it's own cflags below for some retarded reason
1131 $config{LDLIBS} = "-pthread -lstdc++";
1132 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1133 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1134 $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared" unless defined $opt_disablerpath;
1135 $config{MAKEPROG} = "make";
1137 if ($config{OSNAME} =~ /darwin/i) {
1138 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1139 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1140 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1143 if ($config{OSNAME} =~ /OpenBSD/i) {
1144 $config{MAKEPROG} = "gmake";
1145 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1146 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1147 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1148 # if theyre not running this, configure lets the build continue but they probably wont manage to
1149 # compile as this standard version is 2.95.3!
1151 $config{CC} = "eg++";
1152 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1157 if ($config{OSNAME} =~ /Linux/i) {
1158 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1159 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1160 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1161 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1162 $config{MAKEPROG} = "make";
1165 if ($config{OSNAME} =~ /FreeBSD/i) {
1166 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1167 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1170 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1172 # solaris/sunos needs these
1173 # socket = bsd sockets api
1175 # rt = POSIX realtime extensions
1176 # resolv = inet_aton only (why isnt this in nsl?!)
1177 $config{MAKEPROG} = "gmake";
1178 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1182 if($config{OSNAME} =~ /MINGW32/i)
1184 # All code is position-independent on windows
1185 $config{FLAGS} =~ s/-fPIC //;
1189 return $config{OSNAME};
1192 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1195 my($writeheader) = @_;
1197 # First File.. inspircd_config.h
1198 chomp(my $incos = `uname -n -s -r`);
1199 chomp(my $version = `sh src/version.sh`);
1200 chomp(my $revision2 = getrevision());
1201 if ($writeheader == 1)
1203 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1204 open(FILEHANDLE, ">include/inspircd_config.h");
1205 my $NL = $config{NICK_LENGT}+1;
1206 my $CL = $config{CHAN_LENGT}+1;
1207 print FILEHANDLE <<EOF;
1208 /* Auto generated by configure, do not modify! */
1209 #ifndef __CONFIGURATION_AUTO__
1210 #define __CONFIGURATION_AUTO__
1212 /* this is for windows support. */
1213 #define CoreExport /**/
1214 #define DllExport /**/
1216 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1217 #define MOD_PATH "$config{MODULE_DIR}"
1218 #define VERSION "$version"
1219 #define REVISION "$revision2"
1220 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1223 #define MAXMODES $config{MAXI_MODES}
1224 #define IDENTMAX $config{MAX_IDENT}
1225 #define MAXQUIT $config{MAX_QUIT}
1226 #define MAXTOPIC $config{MAX_TOPIC}
1227 #define MAXKICK $config{MAX_KICK}
1228 #define MAXGECOS $config{MAX_GECOS}
1229 #define MAXAWAY $config{MAX_AWAY}
1230 #define OPTIMISATION $config{OPTIMITEMP}
1231 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1232 #define SYSTEM "$incos"
1235 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1237 if ($config{OSNAME} =~ /SunOS/i) {
1238 print FILEHANDLE "#define IS_SOLARIS\n";
1240 if ($config{OSNAME} =~ /MINGW32/i) {
1241 print FILEHANDLE "#define IS_MINGW\n";
1243 if ($config{GCCVER} >= 3) {
1244 print FILEHANDLE "#define GCC3\n";
1246 if ($config{HAS_STRLCPY} eq "true") {
1247 print FILEHANDLE "#define HAS_STRLCPY\n";
1249 if ($config{HAS_STDINT} eq "true") {
1250 print FILEHANDLE "#define HAS_STDINT\n";
1252 if ($config{IPV6} =~ /y/i) {
1253 print FILEHANDLE "#define IPV6\n";
1255 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1256 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1259 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1260 print FILEHANDLE "#define USE_KQUEUE\n";
1261 $se = "socketengine_kqueue";
1264 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1265 print FILEHANDLE "#define USE_EPOLL\n";
1266 $se = "socketengine_epoll";
1269 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1270 print FILEHANDLE "#define USE_PORTS\n";
1271 $se = "socketengine_ports";
1274 # user didn't choose either epoll or select for their OS.
1275 # default them to USE_SELECT (ewwy puke puke)
1277 print FILEHANDLE "#define USE_SELECT\n";
1278 $se = "socketengine_select";
1280 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1286 open(FILEHANDLE, ">include/inspircd_se_config.h");
1287 print FILEHANDLE <<EOF;
1288 /* Auto generated by configure, do not modify or commit to svn! */
1289 #ifndef __CONFIGURATION_SOCKETENGINE__
1290 #define __CONFIGURATION_SOCKETENGINE__
1292 #include "socketengines/$se.h"
1300 # Create a Modules List..
1302 foreach my $i (@modlist)
1304 $modules .= "m_".$i.".so ";
1306 chomp($modules); # Remove Redundant whitespace..
1308 opendir(DIRHANDLE, "src/modules");
1309 foreach my $name (sort readdir(DIRHANDLE)) {
1310 if ($name =~ /^m_(.+?)$/) {
1311 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1312 closedir(MDIRHANDLE);
1313 $modules .= "$name.so ";
1314 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name.so\n";
1318 closedir(DIRHANDLE);
1321 # Write all .in files.
1324 my $exe = "inspircd";
1326 # Do this once here, and cache it in the .*.inc files,
1327 # rather than attempting to read src/version.sh from
1328 # compiled code -- we might not have the source to hand.
1329 # Fix for bug#177 by Brain.
1331 chomp($version = `sh ./src/version.sh`);
1332 chomp(my $revision = getrevision());
1333 $version = "$version(r$revision)";
1335 # We can actually parse any file starting with . and ending with .inc,
1336 # but right now we only parse .inspircd.inc to form './inspircd'
1338 print "Writing \e[1;32mMakefiles\e[0m\n";
1339 write_dynamic_modules_makefile();
1340 write_dynamic_makefile();
1342 opendir(DIRHANDLE, $this);
1344 foreach my $name (sort readdir(DIRHANDLE)) {
1345 if ($name =~ /^\.(.+)\.inc$/) {
1348 # Bug #353, omit this on non-darwin
1349 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1351 # All .name.inc files need parsing!
1353 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1354 while (<FILEHANDLE>) {
1359 print "Writing \e[1;32m$file\e[0m ...\n";
1360 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1361 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1362 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1363 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1364 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1365 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1366 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1367 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1368 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1369 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1370 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1371 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1372 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1373 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1374 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1375 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1376 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1377 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1378 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1380 open(FILEHANDLE, ">$file");
1381 print FILEHANDLE $tmp;
1384 closedir(DIRHANDLE);
1386 # Make inspircd executable!
1387 chmod 0744, 'inspircd';
1390 sub write_dynamic_modules_makefile {
1391 # Modules Makefile..
1392 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1393 open(FILEHANDLE, ">src/modules/Makefile");
1396 # Module Makefile Header
1398 print FILEHANDLE <<EOF;
1399 ###################################################
1400 # Copyright 2002-2007 The InspIRCd Development Team
1401 # http://www.inspircd.org/wiki/index.php/Credits
1403 # Thanks to Andrew Church <achurch\@achurch.org>
1404 # for assisting with making this work right.
1406 # Automatically Generated by ./configure to add a
1407 # modules please run ./configure -modupdate
1408 ###################################################
1414 if ($config{OSNAME} =~ /darwin/) {
1415 print FILEHANDLE <<EOCHEESE;
1417 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1421 print FILEHANDLE <<EOCHEESE;
1423 PICLDFLAGS = -fPIC -DPIC -shared
1429 # End Module Makefile Header
1432 # Create a Modules List..
1436 foreach my $i (@modlist) {
1438 # Write Entry to the MakeFile
1440 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1441 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1442 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1444 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1447 if (nopedantic("src/modules/m_".$i.".cpp"))
1450 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
1451 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1457 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
1458 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1461 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1462 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1464 # End Write Entry to the MakeFile
1468 opendir(DIRHANDLE, "src/modules");
1469 foreach my $name (sort readdir(DIRHANDLE)) {
1470 if ($name =~ /^m_(.+?)$/) {
1475 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1476 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1477 read_module_directory("src/modules/$name", $name);
1478 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1479 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";
1480 if ($config{IS_DARWIN} eq "YES") {
1481 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1483 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1485 print FILEHANDLE "\n$mfrules\n";
1486 closedir(MDIRHANDLE);
1487 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1491 closedir(DIRHANDLE);
1494 sub read_module_directory {
1495 my ($dpath, $reldpath) = @_;
1497 if (opendir(MDIRHANDLE, $dpath) == 0) {
1501 foreach my $fname (sort readdir(MDIRHANDLE)) {
1502 if ($fname =~ /\.cpp$/) {
1503 my $cmflags = getcompilerflags("$dpath/$fname");
1504 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1505 my $deps = getdependencies("$dpath/$fname");
1507 $oname =~ s/\.cpp$/.o/g;
1508 $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";
1509 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1510 $mobjs = $mobjs . " $reldpath/$oname";
1513 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1514 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1521 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1522 # dependencies which are not relevent in C++.
1526 open (CPP, "<$file") or die("Can't open $file for reading!");
1531 foreach my $d (@ignoredeps)
1537 foreach my $dep (@immutabledeps)
1539 $immutable = $immutable . "../include/$dep ";
1541 $immutable =~ s/ $//g;
1543 while (defined(my $line = <CPP>))
1546 if ($line =~ /#include "(.+\.h)"/)
1548 if (!exists($dupe{$1}))
1550 $retlist = $retlist . "../include/$1 ";
1556 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1559 sub write_dynamic_makefile
1563 my %existing_install_list = ();
1564 opendir(DIRHANDLE, "src/commands");
1565 foreach my $name (sort readdir(DIRHANDLE))
1567 if ($name =~ /^cmd_(.+)\.cpp$/)
1569 $cmdlist[$i++] = $1;
1570 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1571 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1574 closedir(DIRHANDLE);
1578 $config{USE_EPOLL} = 0;
1582 $config{USE_KQUEUE} = 0;
1586 $config{USE_PORTS} = 0;
1589 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1591 print "Scanning \e[1;32m$dir\e[0m for core files ";
1592 opendir(DIRHANDLE, $dir);
1593 foreach my $name (sort readdir(DIRHANDLE))
1595 if ($name =~ /\.cpp$/)
1597 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1599 while (defined(my $line = <CPP>))
1602 if ($line =~ /\/\* \$Core: (\w+) \*\//i)
1604 $filelist{$name} = $1;
1606 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1608 $specialdeps{$name} = $1;
1610 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1612 $extraobjects{$name} = $1;
1614 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1616 $extrabuildlines{$name} = $1;
1618 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1620 $extrasources{$name} = $1;
1622 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1624 if (defined $config{$1})
1626 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1629 while (defined($line = <CPP>))
1632 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1633 last if ($line =~ /\/\* \$EndIf \*\//i);
1638 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1640 if (!exists($existing_install_list{$1}))
1642 $existing_install_list{$1} = 1;
1643 my $idir = (split(' ',$1))[1];
1644 my $ifile = (split(' ',$1))[0];
1645 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1646 $ifile =~ s/.*\///g;
1647 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1650 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1652 if (!exists($existing_install_list{$1}))
1654 $existing_install_list{$1} = 1;
1655 my $idir = (split(' ',$1))[1];
1656 my $ifile = (split(' ',$1))[0];
1657 $install_list = $install_list . " -cp $1\n";
1658 $ifile =~ s/.*\///g;
1659 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1666 closedir(DIRHANDLE);
1670 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1673 my $all_libsonly = "";
1674 my $libraryext = "";
1678 if ($config{IS_DARWIN} eq "YES")
1680 $libraryext = "dylib";
1681 $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 "
1686 $RPATH = "-Wl,--rpath -Wl,$config{LIBRARY_DIR}" unless defined $opt_disablerpath;
1687 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include $RPATH \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1690 foreach my $cpp (sort keys %filelist)
1692 $all = $all . $filelist{$cpp} . "." . $libraryext . " ";
1693 $all_libsonly = $all_libsonly . $filelist{$cpp} . "." . $libraryext . " ";
1694 $install_list = $install_list . " -install -m \$(INSTMODE) src/" . $filelist{$cpp} . "." . $libraryext . " \$(LIBPATH)\n";
1695 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/" . $filelist{$cpp} . "." . $libraryext . "\n";
1697 $all = $all . "moo inspircd\n";
1699 $othercrap = $othercrap . " $all_libsonly\n\n";
1701 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1704 CC = im a cheezeball
1705 CXXFLAGS = -I../include \${FLAGS}
1706 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1707 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1711 print FH "$all\n\n";
1713 my $deps = calcdeps("src/inspircd.cpp");
1714 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1715 print FH "$othercrap\n";
1717 foreach my $cpp (sort keys %filelist)
1719 my $thislib = $filelist{$cpp} . "." . $libraryext;
1723 $objs =~ s/\.cpp$/.o/;
1724 if (exists($extraobjects{$cpp}))
1726 $objs = $objs . " " . $extraobjects{$cpp};
1728 if (exists($extrasources{$cpp}))
1730 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1732 if ($config{IS_DARWIN} eq "YES")
1734 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1738 if (defined $opt_disablerpath)
1740 $libcrap = " -shared";
1744 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1747 $deps = calcdeps("src/$cpp");
1748 if (exists($extrasources{$cpp}))
1750 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1752 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1755 $deps = $deps . $d . " ";
1759 print FH $thislib . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1760 print FH " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1761 if (exists($extrabuildlines{$cpp}))
1763 print FH " " . $extrabuildlines{$cpp} . "\n";
1765 print FH " \@../make/run-cc.pl \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1768 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1770 # close main makefile
1774 # generate a list of .so
1775 foreach my $cmd (@cmdlist) {
1776 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1779 # and now reopen the commands makefile
1780 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1783 CXXFLAGS = -I../../include \${FLAGS}
1790 # now print the command file details.
1791 foreach my $cmd (@cmdlist) {
1793 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
1794 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1800 # Routine to list out the extra/ modules that have been enabled.
1801 # Note: when getting any filenames out and comparing, it's important to lc it if the
1802 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1803 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1804 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1805 sub list_extras () {
1808 my $srcdir = File::Spec->catdir("src", "modules");
1809 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1812 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1813 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1816 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1817 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1820 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1822 EXTRA: for my $extra (@extras) {
1823 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1824 next if ($extra eq '.svn');
1825 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1826 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1827 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1828 if (-l $abs_source) {
1829 # Symlink, is it in the right place?
1830 my $targ = readlink($abs_source);
1831 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1832 if ($abs_targ eq $abs_extra) {
1833 $extras{$extra} = "\e[32;1menabled\e[0m";
1835 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1837 } elsif (-e $abs_source) {
1838 my ($devext, $inoext) = stat($abs_extra);
1839 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1841 if ($devsrc == $devext && $inosrc == $inoext) {
1842 $extras{$extra} = "\e[32;1menabled\e[0m";
1844 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1847 open my $extfd, "<", $abs_extra;
1848 open my $srcfd, "<", $abs_source;
1850 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1851 $extras{$extra} = "\e[32;1menabled\e[0m";
1853 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1857 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1860 # Now let's add dependency info
1861 for my $extra (keys(%extras)) {
1862 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1863 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1864 my @deps = split / +/, getdependencies($abs_extra);
1865 for my $dep (@deps) {
1866 if (exists($extras{$dep})) {
1867 my $ref = \$extras{$dep}; # Take reference.
1868 if ($$ref !~ m/needed by/) {
1869 # First dependency found.
1870 if ($$ref =~ m/enabled/) {
1871 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1873 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1874 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1877 if ($$ref =~ m/enabled/) {
1878 $$ref .= ", \e[32;1m$extra\e[0m";
1880 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1886 for my $extra (sort {$a cmp $b} keys(%extras)) {
1887 my $text = $extras{$extra};
1888 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1889 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1891 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1894 return keys(%extras) if wantarray; # Can be used by manage_extras.
1897 sub enable_extras (@) {
1899 for my $extra (@extras) {
1900 my $extrapath = "src/modules/extra/$extra";
1901 if (!-e $extrapath) {
1902 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1905 my $source = "src/modules/$extra";
1907 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1910 # Get dependencies, and add them to be processed.
1911 my @deps = split / +/, getdependencies($extrapath);
1912 for my $dep (@deps) {
1913 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1914 if (!-e "src/modules/$dep") {
1915 if (-e "src/modules/extra/$dep") {
1916 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1919 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";
1923 print "Enabling $extra ... \n";
1924 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1928 sub disable_extras (@)
1930 opendir my $dd, "src/modules/extra/";
1931 my @files = readdir($dd);
1934 EXTRA: for my $extra (@extras) {
1935 my $extrapath = "src/modules/extra/$extra";
1936 my $source = "src/modules/$extra";
1937 if (!-e $extrapath) {
1938 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1941 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1942 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";
1945 # Check if anything needs this.
1946 for my $file (@files) {
1947 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1948 # File depends on this extra...
1949 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1950 # And is both enabled and not about to be disabled.
1951 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1952 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1958 print "Disabling $extra ... \n";
1959 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";