2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2007 The InspIRCd Development Team
6 # http://www.inspircd.org/wiki/index.php/Credits
8 # Licensed under GPL, please see the COPYING file
13 ###################################################
20 use warnings FATAL => qw(all);
24 $Data::Dumper::Sortkeys = 1;
25 $Data::Dumper::Useqq = 1;
34 # Utility functions for our buildsystem
38 use make::opensslcert;
40 ###############################################################################################
44 ###############################################################################################
46 # If you wish to ignore a dependency throughout the entire core, add it here.
49 "inspircd_win32wrapper.h", # windows has its own configure program
52 # If you wish for all files in the entire core to have a given dependency, insert it here.
53 # You should keep this to an absolute minimum to avoid rebuilds that are not neccessary.
55 our @immutabledeps = (
56 "inspircd_config.h", # auto re-generated by configure
60 ###############################################################################################
62 # NON-EDITABLE VARIABLES
64 ###############################################################################################
66 # List of commands that make up 'make install' and 'make deinstall'
68 our $install_list = "";
69 our $uninstall_list = "";
71 # This is a list of all files in the core. Each cpp file is mapped to a shared object file,
72 # whos file extension is omitted (these can vary from system to system). Auto detected by
73 # scanning the src/*.cpp files for files containing /* $Core: */ identifiers.
77 # If you wish for a file to have special dependencies in the makefile, add an entry here.
78 # Auto populated by /* $ExtraDeps: */ instruction
80 our %specialdeps = ();
82 # If you wish for a file to have extra make lines (in between the compile and link steps)
83 # then insert them here.
84 # Auto populated by /* $ExtraBuild: */ instruction
86 our %extrabuildlines = ();
88 # If you wish for a file to be linked against extra objects or arctives, insert them here.
89 # Auto populated by /* $ExtraObjects: */ instruction
91 our %extraobjects = ();
93 # If you wish to compile extra cpp sources into an object, define them here.
94 # NOTE: Certain cpp files such as the socket engines have a value auto calculated
95 # for this table so that their derived class is built.
96 # Auto populated by /* $ExtraSources: */ instruction
98 our %extrasources = ();
100 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_nick_length,
101 $opt_chan_length, $opt_maxclients, $opt_ports, $opt_epoll, $opt_kqueue, $opt_noports,
102 $opt_noepoll, $opt_nokqueue, $opt_disablerpath, $opt_ipv6, $opt_ipv6links,
103 $opt_noipv6links, $opt_ident, $opt_quit, $opt_topic, $opt_maxbuf, $opt_kick,
104 $opt_gecos, $opt_away, $opt_modes, $opt_disable_debug, $opt_maxchans,
107 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
112 sub enable_extras (@);
114 sub disable_extras (@);
116 my @opt_enableextras;
117 my @opt_disableextras;
120 'enable-gnutls' => \$opt_use_gnutls,
121 'rebuild' => \$opt_rebuild,
122 'enable-openssl' => \$opt_use_openssl,
123 'disable-interactive' => \$opt_nointeractive,
124 'with-nick-length=i' => \$opt_nick_length,
125 'with-channel-length=i' => \$opt_chan_length,
126 'with-max-clients=i' => \$opt_maxclients,
127 'enable-ports' => \$opt_ports,
128 'enable-epoll' => \$opt_epoll,
129 'enable-kqueue' => \$opt_kqueue,
130 'disable-ports' => \$opt_noports,
131 'disable-epoll' => \$opt_noepoll,
132 'disable-kqueue' => \$opt_nokqueue,
133 'disable-rpath' => \$opt_disablerpath,
134 'enable-ipv6' => \$opt_ipv6,
135 'enable-remote-ipv6' => \$opt_ipv6links,
136 'disable-remote-ipv6' => \$opt_noipv6links,
137 'with-cc=s' => \$opt_cc,
138 'with-ident-length=i' => \$opt_ident,
139 'with-quit-length=i' => \$opt_quit,
140 'with-topic-length=i' => \$opt_topic,
141 'with-maxbuf=i' => \$opt_maxbuf,
142 'with-kick-length=i' => \$opt_kick,
143 'with-gecos-length=i' => \$opt_gecos,
144 'with-away-length=i' => \$opt_away,
145 'with-max-modes=i' => \$opt_modes,
146 'prefix=s' => \$opt_base_dir,
147 'config-dir=s' => \$opt_config_dir,
148 'module-dir=s' => \$opt_module_dir,
149 'binary-dir=s' => \$opt_binary_dir,
150 'library-dir=s' => \$opt_library_dir,
151 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
152 'help' => sub { showhelp(); },
153 'modupdate' => sub { modupdate(); },
154 'update' => sub { update(); },
155 'svnupdate' => sub { svnupdate(); },
156 'clean' => sub { clean(); },
157 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
158 'enable-extras=s@' => \@opt_enableextras, # ^
159 'disable-extras=s@' => \@opt_disableextras, # ^
162 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
163 @opt_enableextras = split /,/, join(',', @opt_enableextras);
164 @opt_disableextras = split /,/, join(',', @opt_disableextras);
165 enable_extras(@opt_enableextras);
166 disable_extras(@opt_disableextras);
168 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
169 print "Run $0 -modupdate after you've done this to update the makefiles.\n";
173 our $non_interactive = (
174 (defined $opt_library_dir) ||
175 (defined $opt_base_dir) ||
176 (defined $opt_config_dir) ||
177 (defined $opt_module_dir) ||
178 (defined $opt_base_dir) ||
179 (defined $opt_binary_dir) ||
180 (defined $opt_nointeractive) ||
181 (defined $opt_away) ||
182 (defined $opt_gecos) ||
183 (defined $opt_kick) ||
184 (defined $opt_maxclients) ||
185 (defined $opt_modes) ||
186 (defined $opt_topic) ||
187 (defined $opt_quit) ||
188 (defined $opt_ident) ||
190 (defined $opt_ipv6) ||
191 (defined $opt_ipv6links) ||
192 (defined $opt_noipv6links) ||
193 (defined $opt_kqueue) ||
194 (defined $opt_epoll) ||
195 (defined $opt_ports) ||
196 (defined $opt_maxchans) ||
197 (defined $opt_opermaxchans) ||
198 (defined $opt_chan_length) ||
199 (defined $opt_nick_length) ||
200 (defined $opt_use_openssl) ||
201 (defined $opt_nokqueue) ||
202 (defined $opt_noepoll) ||
203 (defined $opt_noports) ||
204 (defined $opt_maxbuf) ||
205 (defined $opt_use_gnutls)
207 our $interactive = !$non_interactive;
209 chomp(our $topdir = getcwd());
210 our $this = resolve_directory($topdir); # PWD, Regardless.
211 our @modlist = (); # Declare for Module List..
212 our %config = (); # Initiate Configuration Hash..
213 $config{ME} = resolve_directory($topdir); # Present Working Directory
215 $config{BASE_DIR} = $config{ME};
217 if (defined $opt_base_dir)
219 $config{BASE_DIR} = $opt_base_dir;
222 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
223 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
224 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
225 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
227 if (defined $opt_config_dir)
229 $config{CONFIG_DIR} = $opt_config_dir;
231 if (defined $opt_module_dir)
233 $config{MODULE_DIR} = $opt_module_dir;
235 if (defined $opt_binary_dir)
237 $config{BINARY_DIR} = $opt_binary_dir;
239 if (defined $opt_library_dir)
241 $config{LIBRARY_DIR} = $opt_library_dir;
243 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
244 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version
245 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
246 chomp(our $openssl_ver = $config{HAS_OPENSSL});
247 $config{USE_GNUTLS} = "n";
248 if (defined $opt_use_gnutls)
250 $config{USE_GNUTLS} = "y"; # Use gnutls.
252 $config{USE_OPENSSL} = "n"; # Use openssl.
253 if (defined $opt_use_openssl)
255 $config{USE_OPENSSL} = "y";
258 # no, let's not change these.
259 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
260 if (!defined $opt_disable_debug)
262 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
266 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
269 $config{NICK_LENGT} = "31"; # Default Nick Length
270 if (defined $opt_nick_length)
272 $config{NICK_LENGT} = $opt_nick_length;
274 $config{CHAN_LENGT} = "64"; # Default Channel Name Length
275 if (defined $opt_chan_length)
277 $config{CHAN_LENGT} = $opt_chan_length;
279 $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once.
280 if (defined $opt_modes)
282 $config{MAXI_MODES} = $opt_modes;
284 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
285 $config{HAS_STDINT} = "false"; # stdint.h check
286 $config{USE_KQUEUE} = "y"; # kqueue enabled
287 if (defined $opt_kqueue)
289 $config{USE_KQUEUE} = "y";
291 if (defined $opt_nokqueue)
293 $config{USE_KQUEUE} = "n";
295 $config{USE_EPOLL} = "y"; # epoll enabled
296 if (defined $opt_epoll)
298 $config{USE_EPOLL} = "y";
300 if (defined $opt_noepoll)
302 $config{USE_EPOLL} = "n";
304 $config{USE_PORTS} = "y"; # epoll enabled
305 if (defined $opt_ports)
307 $config{USE_PORTS} = "y";
309 if (defined $opt_noports)
311 $config{USE_PORTS} = "n";
313 $config{IPV6} = "n"; # IPv6 support (experimental)
314 if (defined $opt_ipv6)
318 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
319 if (defined $opt_ipv6links)
321 $config{SUPPORT_IP6LINKS} = "y";
323 if (defined $opt_noipv6links)
325 $config{SUPPORT_IP6LINKS} = "n";
327 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`); # FD Limit
328 chomp($config{MAX_DESCRIPTORS} = `sh -c \"ulimit -n\"`); # Hard FD Limit
329 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
330 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
331 $config{OSNAME} = $^O; # Operating System Name
332 $config{IS_DARWIN} = "NO"; # Is OSX?
333 $config{STARTSCRIPT} = "inspircd"; # start script?
334 $config{DESTINATION} = "BASE"; # Is target path.
335 $config{EXTRA_DIR} = ""; # Is empty.
336 if ($config{OSNAME} =~ /darwin/i)
338 $config{IS_DARWIN} = "YES";
339 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
340 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
341 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
343 $config{CC} = "g++"; # C++ compiler
346 $config{CC} = $opt_cc;
348 our $exec = $config{CC} . " -dumpversion | cut -c 1";
349 chomp($config{GCCVER} = `$exec`); # Major GCC Version
350 $config{MAKEORDER} = "ircd mods"; # build order
351 $config{MAX_IDENT} = "12"; # max ident size
352 $config{MAX_QUIT} = "255"; # max quit message size
353 $config{MAX_TOPIC} = "307"; # max topic size
354 $config{MAX_KICK} = "255"; # max kick message size
355 $config{MAX_GECOS} = "128"; # max GECOS size
356 $config{MAX_AWAY} = "200"; # max AWAY size
357 $config{MAXBUF} = "512"; # Max buffer size
358 if (defined $opt_ident)
360 $config{MAX_IDENT} = $opt_ident;
362 if (defined $opt_quit)
364 $config{MAX_QUIT} = $opt_quit;
366 if (defined $opt_topic)
368 $config{MAX_TOPIC} = $opt_topic;
370 if (defined $opt_kick)
372 $config{MAX_KICK} = $opt_kick;
374 if (defined $opt_gecos)
376 $config{MAX_GECOS} = $opt_gecos;
378 if (defined $opt_away)
380 $config{MAX_AWAY} = $opt_away;
383 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
384 $config{HAS_OPENSSL} = $1;
386 $config{HAS_OPENSSL} = "";
389 if ($config{GCCVER} eq "") {
390 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
394 our $fd_scan_fail = "";
395 if (!$config{MAX_CLIENT_T}) {
396 $config{MAX_CLIENT_T} = 1024; # Set a reasonable 'Default'
397 $fd_scan_fail = "true"; # Used Later
400 # Get and Set some important vars..
405 unlink(".config.cache");
408 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
413 chomp($topdir = getcwd());
414 $this = resolve_directory($topdir); # PWD, Regardless.
416 # Does the cache file exist?
418 # No, No it doesn't.. *BASH*
419 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
422 # We've Loaded the cache file and all our variables..
423 print "Updating files...\n";
425 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
427 print "Disabling debug information (-g).\n";
428 $config{OPTIMISATI} = "";
431 $has_epoll = $config{HAS_EPOLL};
432 $has_ports = $config{HAS_PORTS};
433 $has_kqueue = $config{HAS_KQUEUE};
442 print "Configure update failed: $@\n";
450 chomp($topdir = getcwd());
451 $this = resolve_directory($topdir); # PWD, Regardless.
453 # Does the cache file exist?
455 # No, No it doesn't.. *BASH*
456 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
459 # We've Loaded the cache file and all our variables..
460 print "Updating files...\n";
462 $has_epoll = $config{HAS_EPOLL};
463 $has_ports = $config{HAS_PORTS};
464 $has_kqueue = $config{HAS_KQUEUE};
473 print "Module update failed: $@\n";
483 open(FH,"<.svn/entries") or $fail = 1;
485 print "This is not an SVN copy of InspIRCd.\n";
492 open my $fd, "-|", "svn update";
493 my $configurechanged = 0; # Needs ./configure -update
494 my $coredirchanged = 0; # Needs ./configure -update
495 my $moduledirchanged = 0; # Needs ./configure -modupdate
496 my $rootincchanged = 0;
498 while (defined(my $line = <$fd>))
502 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
503 ($action, $file) = ($1, $2);
506 push @conflicted, $file;
507 if ($file eq "configure")
509 $configurechanged = 1;
511 elsif ($file =~ m#^src/modules#)
513 $moduledirchanged = 1;
515 elsif ($file =~ m#^src/#)
519 elsif ($file =~ m/^\..*\.inc$/)
524 elsif ($action eq "U" || $action eq "G")
526 if ($file eq "configure")
528 $configurechanged = 1;
530 elsif ($file =~ m/^\..*\.inc$/)
535 elsif ($action eq "A" || $action eq "D")
537 if ($file =~ m#^src/modules#)
539 $moduledirchanged = 1;
541 elsif ($file =~ m#^src/#)
547 unless (close $fd) # close() waits for exit and returns false if the command failed
551 print STDERR "Problem updating from SVN, please check above for errors\n";
555 print STDERR "Failed to run SVN: $!\n";
559 if (scalar(@conflicted) > 0)
561 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
562 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate", (($coredirchanged || $configurechanged) ? "" : "mod");
563 print "Conflicted files: " . join ", ", @conflicted;
566 if ($configurechanged || $coredirchanged)
568 system("perl configure -update");
570 elsif ($moduledirchanged || $rootincchanged)
572 system("perl configure -modupdate");
576 print "No need to update Makefiles.\n";
578 if (defined $opt_rebuild) {
579 system("make install");
584 print "Running non-interactive configure...\n" unless $interactive;
585 print "Checking for cache from previous configure... ";
586 print ((!getcache()) ? "not found\n" : "found\n");
587 print "Checking operating system version... ";
588 print getosflags() . "\n";
590 if (defined $opt_maxclients)
592 $config{MAX_CLIENT} = $opt_maxclients;
595 if (!$config{MAX_CLIENT}) {
596 # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
597 # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
598 # higher than the found value" :))
599 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
602 printf "Checking if stdint.h exists... ";
603 $config{HAS_STDINT} = "true";
605 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
606 if ($config{HAS_STDINT} eq "true") {
609 print "yes\n" if $config{HAS_STDINT} eq "true";
610 print "no\n" if $config{HAS_STDINT} eq "false";
612 printf "Checking if strlcpy exists... ";
613 # Perform the strlcpy() test..
614 $config{HAS_STRLCPY} = "false";
616 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
618 while (defined(my $line = <STRLCPY>)) {
620 # try and find the delcaration of:
621 # size_t strlcpy(...)
622 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
623 $config{HAS_STRLCPY} = "true";
628 print "yes\n" if $config{HAS_STRLCPY} eq "true";
629 print "no\n" if $config{HAS_STRLCPY} eq "false";
631 printf "Checking if kqueue exists... ";
634 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
636 while (defined(my $line = <KQUEUE>)) {
638 # try and find the delcaration of:
640 if ($line =~ /int(\0x9|\s)+kqueue/) {
646 print "yes\n" if $has_kqueue == 1;
647 print "no\n" if $has_kqueue == 0;
649 printf "Checking if epoll exists... ";
652 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
658 my $kernel = `uname -r`;
660 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
665 # Suggestion from nenolod, weed out odd systems which have glibc built
666 # against 2.4 kernels (ick)
667 my $kernel_arch = `uname -p`;
671 if ($kernel_arch =~ /x86_64/) {
672 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
675 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
679 while (defined(my $line = <FH>))
682 if ($line =~ /GNU C Library .* version (.*?) /)
685 $libcv =~ /(\d+\.\d+)/;
688 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
691 # Fix for some retarded libc builds, strip off >> and << etc.
692 $kernelv =~ /(\d+\.\d+)/;
700 printf "libc too old: $libcv... ";
705 printf "libc built against older kernel $kernelv... ";
710 print "yes\n" if $has_epoll == 1;
711 print "no\n" if $has_epoll == 0;
713 printf "Checking if Solaris I/O completion ports are available... ";
715 our $system = `uname -s`;
717 $has_ports = 1 if ($system eq "SunOS");
720 my $kernel = `uname -r`;
722 if (($kernel !~ /^5\.1./)) {
726 print "yes\n" if $has_ports == 1;
727 print "no\n" if $has_ports == 0;
729 $config{HAS_EPOLL} = $has_epoll;
730 $config{HAS_KQUEUE} = $has_kqueue;
732 printf "Checking for libgnutls... ";
733 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
735 $config{HAS_GNUTLS} = "y";
738 $config{HAS_GNUTLS} = "n";
741 printf "Checking for openssl... ";
742 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
744 $config{HAS_OPENSSL} = "y";
747 $config{HAS_OPENSSL} = "n";
750 printf "Checking if you are running an ancient, unsupported OS... ";
751 if ($config{OSNAME} =~ /FreeBSD/i)
753 my $version = `uname -r`;
754 if ($version =~ /^4\./)
756 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
759 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
760 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
765 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
771 print "no ($version)\n";
777 print "no ($config{OSNAME})\n";
780 ################################################################################
781 # BEGIN INTERACTIVE PART #
782 ################################################################################
787 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
790 my $rev = getrevision();
791 # Display Introduction Message..
793 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
794 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
796 *** If you are unsure of any of these values, leave it blank for ***
797 *** standard settings that will work, and your server will run ***
798 *** using them. Please consult your IRC network admin if in doubt. ***
800 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
801 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
802 dir, otherwise you won't have a config file!
804 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
805 Maximum file descriptors: \e[1;32m$config{MAX_CLIENT_T}\e[0m
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?\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)");
887 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
888 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
889 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
890 print "instead, you should enable the OpenSSL module yourself\n";
891 print "by copying it from src/modules/extra to src/modules.\n\n";
892 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
893 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
896 if ($config{HAS_GNUTLS} eq "y") {
897 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
898 if ($config{USE_GNUTLS} eq "y") {
899 print "\nUsing GnuTLS SSL module.\n";
901 } elsif ($config{HAS_OPENSSL} eq "y") {
902 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
903 if ($config{USE_OPENSSL} eq "y") {
904 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
908 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";
911 print "\nThe following questions will ask you for various figures relating\n";
912 print "To your IRCd install. Please note that these should usually be left\n";
913 print "as defaults unless you have a real reason to change them. If they\n";
914 print "changed, then the values must be identical on all servers on your\n";
915 print "network, or malfunctions and/or crashes may occur, with the exception\n";
916 print "of the 'maximum number of clients' setting which may be different on\n";
917 print "different servers on the network.\n\n";
919 # File Descriptor Settings..
920 promptnumeric("number of clients at any one time", "MAX_CLIENT_T");
921 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
922 $config{MAX_DESCRIPTORS} = $config{MAX_CLIENT_T};
924 promptnumeric("length of nicknames", "NICK_LENGT");
925 promptnumeric("length of channel names", "CHAN_LENGT");
926 promptnumeric("number of mode changes in one line", "MAXI_MODES");
927 promptnumeric("length of an ident (username)", "MAX_IDENT");
928 promptnumeric("length of a quit message", "MAX_QUIT");
929 promptnumeric("length of a channel topic", "MAX_TOPIC");
930 promptnumeric("length of a kick message", "MAX_KICK");
931 promptnumeric("length of a GECOS (real name)", "MAX_GECOS");
932 promptnumeric("length of an away message", "MAX_AWAY");
937 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
939 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
942 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
944 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
949 if ($config{USE_GNUTLS} eq "y") {
950 unless (-r "src/modules/m_ssl_gnutls.cpp") {
951 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
952 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
957 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
958 print "SSL Certificates Not found, Generating.. \n\n
959 *************************************************************
960 * Generating the Private Key may take some time, go grab a *
961 * Coffee. Even better, to generate some more entropy if it *
962 * is taking a while, open another console and type du / a *
963 * few times and get that HD going :) Then answer the *
964 * Questions which follow. If you are unsure, just hit enter *
965 *************************************************************\n\n";
966 $failed = make_gnutls_cert();
968 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
970 print "\nCertificate generation complete, copying to config directory... ";
971 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
972 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
977 print "SSL Certificates found, skipping.\n\n";
982 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
984 } elsif ($config{USE_OPENSSL} eq "y") {
985 unless (-r "src/modules/m_ssl_openssl.cpp") {
986 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
987 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
993 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
994 print "SSL Certificates Not found, Generating.. \n\n
995 *************************************************************
996 * Generating the certificates may take some time, go grab a *
997 * coffee, or something. *
998 *************************************************************\n\n";
1000 print "\nCertificate generation complete, copying to config directory... ";
1001 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
1002 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
1003 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
1006 print "SSL Certificates found, skipping.\n\n"
1011 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
1014 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
1015 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
1023 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
1024 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
1025 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
1026 print "modules in your config. This configure script has added those modules to the\n";
1027 print "build process. For more info please refer to:\n";
1028 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
1030 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
1031 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
1032 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";
1035 if ($config{GCCVER} < "3") {
1037 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
1038 GCC 2.x series compilers only had partial (read as broken) C++ support, and
1039 your compile will most likely fail horribly! If you have any problems, do NOT
1040 report them to the bugtracker or forums without first upgrading your compiler
1041 to a newer 3.x or 4.x (or whatever is available currently) version.
1045 ################################################################################
1046 # HELPER FUNCTIONS #
1047 ################################################################################
1049 # Retrieves the .config.cache file, and loads values into the main config hash.
1050 open(CACHE, ".config.cache") or return 0;
1053 # Ignore Blank lines, and comments..
1056 my ($key, $value) = split("=", $_, 2);
1057 $value =~ /^\"(.*)\"$/;
1058 # Do something with data here!
1066 # Dump the contents of %config
1067 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1068 open(FILEHANDLE, ">.config.cache");
1069 foreach my $key (keys %config) {
1070 print FILEHANDLE "$key=\"$config{$key}\"\n";
1076 my ($desc, $hash_key) = @_;
1078 while (!$complete) {
1079 print "In what directory $desc?\n";
1080 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1081 chomp(my $var = <STDIN>);
1083 $var = $config{$hash_key};
1085 if ($var =~ /^\~\/(.+)$/) {
1086 # Convert it to a full path..
1087 $var = resolve_directory($ENV{HOME} . "/" . $1);
1089 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1091 # Assume relative Path was given.. fill in the rest.
1092 $var = $this . "/$var";
1095 $var = resolve_directory($var);
1097 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1098 chomp(my $tmp = <STDIN>);
1099 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1100 # Attempt to Create the Dir..
1103 File::Path::mkpath($var, 0, 0777);
1106 unless (defined($chk) && -d $var) {
1107 print "Unable to create directory. ($var)\n\n";
1112 # They said they don't want to create, and we can't install there.
1117 if (!is_dir($var)) {
1118 # Target exists, but is not a directory.
1119 print "File $var exists, but is not a directory.\n\n";
1123 # Either Dir Exists, or was created fine.
1124 $config{$hash_key} = $var;
1134 # Beware: Linux sets it's own cflags below for some retarded reason
1135 $config{LDLIBS} = "-pthread -lstdc++";
1136 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1137 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -g";
1138 $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared" unless defined $opt_disablerpath;
1139 $config{MAKEPROG} = "make";
1141 if ($config{OSNAME} =~ /darwin/i) {
1142 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1143 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1144 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1147 if ($config{OSNAME} =~ /OpenBSD/i) {
1148 $config{MAKEPROG} = "gmake";
1149 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1150 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1151 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1152 # if theyre not running this, configure lets the build continue but they probably wont manage to
1153 # compile as this standard version is 2.95.3!
1155 $config{CC} = "eg++";
1156 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1161 if ($config{OSNAME} =~ /Linux/i) {
1162 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1163 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1164 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1165 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1166 $config{MAKEPROG} = "make";
1169 if ($config{OSNAME} =~ /FreeBSD/i) {
1170 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1171 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1174 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1176 # solaris/sunos needs these
1177 # socket = bsd sockets api
1179 # rt = POSIX realtime extensions
1180 # resolv = inet_aton only (why isnt this in nsl?!)
1181 $config{MAKEPROG} = "gmake";
1182 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1186 if($config{OSNAME} =~ /MINGW32/i)
1188 # All code is position-independent on windows
1189 $config{FLAGS} =~ s/-fPIC //;
1193 return $config{OSNAME};
1196 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1199 my($writeheader) = @_;
1201 # First File.. inspircd_config.h
1202 chomp(my $incos = `uname -n -s -r`);
1203 chomp(my $version = `sh src/version.sh`);
1204 chomp(my $revision2 = getrevision());
1205 if ($writeheader == 1)
1207 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1208 open(FILEHANDLE, ">include/inspircd_config.h");
1209 my $NL = $config{NICK_LENGT}+1;
1210 my $CL = $config{CHAN_LENGT}+1;
1211 print FILEHANDLE <<EOF;
1212 /* Auto generated by configure, do not modify! */
1213 #ifndef __CONFIGURATION_AUTO__
1214 #define __CONFIGURATION_AUTO__
1216 /* this is for windows support. */
1217 #define CoreExport /**/
1218 #define DllExport /**/
1220 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1221 #define MOD_PATH "$config{MODULE_DIR}"
1222 #define VERSION "$version"
1223 #define REVISION "$revision2"
1224 #define MAXCLIENTS $config{MAX_CLIENT}
1225 #define MAXCLIENTS_S "$config{MAX_CLIENT}"
1226 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1227 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
1230 #define MAXMODES $config{MAXI_MODES}
1231 #define IDENTMAX $config{MAX_IDENT}
1232 #define MAXQUIT $config{MAX_QUIT}
1233 #define MAXTOPIC $config{MAX_TOPIC}
1234 #define MAXKICK $config{MAX_KICK}
1235 #define MAXGECOS $config{MAX_GECOS}
1236 #define MAXAWAY $config{MAX_AWAY}
1237 #define OPTIMISATION $config{OPTIMITEMP}
1238 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1239 #define SYSTEM "$incos"
1242 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1244 if ($config{OSNAME} =~ /SunOS/i) {
1245 print FILEHANDLE "#define IS_SOLARIS\n";
1247 if ($config{OSNAME} =~ /MINGW32/i) {
1248 print FILEHANDLE "#define IS_MINGW\n";
1250 if ($config{GCCVER} >= 3) {
1251 print FILEHANDLE "#define GCC3\n";
1253 if ($config{HAS_STRLCPY} eq "true") {
1254 print FILEHANDLE "#define HAS_STRLCPY\n";
1256 if ($config{HAS_STDINT} eq "true") {
1257 print FILEHANDLE "#define HAS_STDINT\n";
1259 if ($config{IPV6} =~ /y/i) {
1260 print FILEHANDLE "#define IPV6\n";
1262 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1263 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1266 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1267 print FILEHANDLE "#define USE_KQUEUE\n";
1268 $se = "socketengine_kqueue";
1271 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1272 print FILEHANDLE "#define USE_EPOLL\n";
1273 $se = "socketengine_epoll";
1276 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1277 print FILEHANDLE "#define USE_PORTS\n";
1278 $se = "socketengine_ports";
1281 # user didn't choose either epoll or select for their OS.
1282 # default them to USE_SELECT (ewwy puke puke)
1284 print FILEHANDLE "#define USE_SELECT\n";
1285 $se = "socketengine_select";
1287 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1293 open(FILEHANDLE, ">include/inspircd_se_config.h");
1294 print FILEHANDLE <<EOF;
1295 /* Auto generated by configure, do not modify or commit to svn! */
1296 #ifndef __CONFIGURATION_SOCKETENGINE__
1297 #define __CONFIGURATION_SOCKETENGINE__
1299 #include "socketengines/$se.h"
1307 # Create a Modules List..
1309 foreach my $i (@modlist)
1311 $modules .= "m_".$i.".so ";
1313 chomp($modules); # Remove Redundant whitespace..
1315 opendir(DIRHANDLE, "src/modules");
1316 foreach my $name (sort readdir(DIRHANDLE)) {
1317 if ($name =~ /^m_(.+?)$/) {
1318 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1319 closedir(MDIRHANDLE);
1320 $modules .= "$name.so ";
1321 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name.so\n";
1325 closedir(DIRHANDLE);
1328 # Write all .in files.
1331 my $exe = "inspircd";
1333 # Do this once here, and cache it in the .*.inc files,
1334 # rather than attempting to read src/version.sh from
1335 # compiled code -- we might not have the source to hand.
1336 # Fix for bug#177 by Brain.
1338 chomp($version = `sh ./src/version.sh`);
1339 chomp(my $revision = getrevision());
1340 $version = "$version(r$revision)";
1342 # We can actually parse any file starting with . and ending with .inc,
1343 # but right now we only parse .inspircd.inc to form './inspircd'
1345 print "Writing \e[1;32mMakefiles\e[0m\n";
1346 write_dynamic_modules_makefile();
1347 write_dynamic_makefile();
1349 opendir(DIRHANDLE, $this);
1351 foreach my $name (sort readdir(DIRHANDLE)) {
1352 if ($name =~ /^\.(.+)\.inc$/) {
1355 # Bug #353, omit this on non-darwin
1356 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1358 # All .name.inc files need parsing!
1360 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1361 while (<FILEHANDLE>) {
1366 print "Writing \e[1;32m$file\e[0m ...\n";
1367 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1368 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1369 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1370 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1371 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1372 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1373 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1374 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1375 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1376 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1377 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1378 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1379 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1380 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1381 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1382 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1383 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1384 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1385 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1387 open(FILEHANDLE, ">$file");
1388 print FILEHANDLE $tmp;
1391 closedir(DIRHANDLE);
1393 # Make inspircd executable!
1394 chmod 0744, 'inspircd';
1397 sub write_dynamic_modules_makefile {
1398 # Modules Makefile..
1399 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1400 open(FILEHANDLE, ">src/modules/Makefile");
1403 # Module Makefile Header
1405 print FILEHANDLE <<EOF;
1406 ###################################################
1407 # Copyright 2002-2007 The InspIRCd Development Team
1408 # http://www.inspircd.org/wiki/index.php/Credits
1410 # Thanks to Andrew Church <achurch\@achurch.org>
1411 # for assisting with making this work right.
1413 # Automatically Generated by ./configure to add a
1414 # modules please run ./configure -modupdate
1415 ###################################################
1421 if ($config{OSNAME} =~ /darwin/) {
1422 print FILEHANDLE <<EOCHEESE;
1424 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1428 print FILEHANDLE <<EOCHEESE;
1430 PICLDFLAGS = -fPIC -DPIC -shared
1436 # End Module Makefile Header
1439 # Create a Modules List..
1443 foreach my $i (@modlist) {
1445 # Write Entry to the MakeFile
1447 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1448 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1449 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1451 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1454 if (nopedantic("src/modules/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 \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1464 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
1465 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1468 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1469 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1471 # End Write Entry to the MakeFile
1475 opendir(DIRHANDLE, "src/modules");
1476 foreach my $name (sort readdir(DIRHANDLE)) {
1477 if ($name =~ /^m_(.+?)$/) {
1482 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1483 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1484 read_module_directory("src/modules/$name", $name);
1485 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1486 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";
1487 if ($config{IS_DARWIN} eq "YES") {
1488 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1490 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1492 print FILEHANDLE "\n$mfrules\n";
1493 closedir(MDIRHANDLE);
1494 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1498 closedir(DIRHANDLE);
1501 sub read_module_directory {
1502 my ($dpath, $reldpath) = @_;
1504 if (opendir(MDIRHANDLE, $dpath) == 0) {
1508 foreach my $fname (sort readdir(MDIRHANDLE)) {
1509 if ($fname =~ /\.cpp$/) {
1510 my $cmflags = getcompilerflags("$dpath/$fname");
1511 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1512 my $deps = getdependencies("$dpath/$fname");
1514 $oname =~ s/\.cpp$/.o/g;
1515 $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";
1516 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1517 $mobjs = $mobjs . " $reldpath/$oname";
1520 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1521 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1528 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1529 # dependencies which are not relevent in C++.
1533 open (CPP, "<$file") or die("Can't open $file for reading!");
1538 foreach my $d (@ignoredeps)
1544 foreach my $dep (@immutabledeps)
1546 $immutable = $immutable . "../include/$dep ";
1548 $immutable =~ s/ $//g;
1550 while (defined(my $line = <CPP>))
1553 if ($line =~ /#include "(.+\.h)"/)
1555 if (!exists($dupe{$1}))
1557 $retlist = $retlist . "../include/$1 ";
1563 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1566 sub write_dynamic_makefile
1570 my %existing_install_list = ();
1571 opendir(DIRHANDLE, "src/commands");
1572 foreach my $name (sort readdir(DIRHANDLE))
1574 if ($name =~ /^cmd_(.+)\.cpp$/)
1576 $cmdlist[$i++] = $1;
1577 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1578 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1581 closedir(DIRHANDLE);
1585 $config{USE_EPOLL} = 0;
1589 $config{USE_KQUEUE} = 0;
1593 $config{USE_PORTS} = 0;
1596 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1598 print "Scanning \e[1;32m$dir\e[0m for core files ";
1599 opendir(DIRHANDLE, $dir);
1600 foreach my $name (sort readdir(DIRHANDLE))
1602 if ($name =~ /\.cpp$/)
1604 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1606 while (defined(my $line = <CPP>))
1609 if ($line =~ /\/\* \$Core: (\w+) \*\//i)
1611 $filelist{$name} = $1;
1613 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1615 $specialdeps{$name} = $1;
1617 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1619 $extraobjects{$name} = $1;
1621 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1623 $extrabuildlines{$name} = $1;
1625 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1627 $extrasources{$name} = $1;
1629 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1631 if (defined $config{$1})
1633 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1636 while (defined($line = <CPP>))
1639 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1640 last if ($line =~ /\/\* \$EndIf \*\//i);
1645 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1647 if (!exists($existing_install_list{$1}))
1649 $existing_install_list{$1} = 1;
1650 my $idir = (split(' ',$1))[1];
1651 my $ifile = (split(' ',$1))[0];
1652 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1653 $ifile =~ s/.*\///g;
1654 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1657 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1659 if (!exists($existing_install_list{$1}))
1661 $existing_install_list{$1} = 1;
1662 my $idir = (split(' ',$1))[1];
1663 my $ifile = (split(' ',$1))[0];
1664 $install_list = $install_list . " -cp $1\n";
1665 $ifile =~ s/.*\///g;
1666 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1673 closedir(DIRHANDLE);
1677 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1680 my $all_libsonly = "";
1681 my $libraryext = "";
1685 if ($config{IS_DARWIN} eq "YES")
1687 $libraryext = "dylib";
1688 $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 "
1693 $RPATH = "-Wl,--rpath -Wl,$config{LIBRARY_DIR}" unless defined $opt_disablerpath;
1694 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include $RPATH \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1697 foreach my $cpp (sort keys %filelist)
1699 $all = $all . $filelist{$cpp} . "." . $libraryext . " ";
1700 $all_libsonly = $all_libsonly . $filelist{$cpp} . "." . $libraryext . " ";
1701 $install_list = $install_list . " -install -m \$(INSTMODE) src/" . $filelist{$cpp} . "." . $libraryext . " \$(LIBPATH)\n";
1702 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/" . $filelist{$cpp} . "." . $libraryext . "\n";
1704 $all = $all . "moo inspircd\n";
1706 $othercrap = $othercrap . " $all_libsonly\n\n";
1708 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1711 CC = im a cheezeball
1712 CXXFLAGS = -I../include \${FLAGS}
1713 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1714 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1718 print FH "$all\n\n";
1720 my $deps = calcdeps("src/inspircd.cpp");
1721 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1722 print FH "$othercrap\n";
1724 foreach my $cpp (sort keys %filelist)
1726 my $thislib = $filelist{$cpp} . "." . $libraryext;
1730 $objs =~ s/\.cpp$/.o/;
1731 if (exists($extraobjects{$cpp}))
1733 $objs = $objs . " " . $extraobjects{$cpp};
1735 if (exists($extrasources{$cpp}))
1737 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1739 if ($config{IS_DARWIN} eq "YES")
1741 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1745 if (defined $opt_disablerpath)
1747 $libcrap = " -shared";
1751 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1754 $deps = calcdeps("src/$cpp");
1755 if (exists($extrasources{$cpp}))
1757 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1759 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1762 $deps = $deps . $d . " ";
1766 print FH $thislib . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1767 print FH " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1768 if (exists($extrabuildlines{$cpp}))
1770 print FH " " . $extrabuildlines{$cpp} . "\n";
1772 print FH " \@../make/run-cc.pl \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1775 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1777 # close main makefile
1781 # generate a list of .so
1782 foreach my $cmd (@cmdlist) {
1783 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1786 # and now reopen the commands makefile
1787 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1790 CXXFLAGS = -I../../include \${FLAGS}
1797 # now print the command file details.
1798 foreach my $cmd (@cmdlist) {
1800 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
1801 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1807 # Routine to list out the extra/ modules that have been enabled.
1808 # Note: when getting any filenames out and comparing, it's important to lc it if the
1809 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1810 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1811 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1812 sub list_extras () {
1815 my $srcdir = File::Spec->catdir("src", "modules");
1816 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1819 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1820 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1823 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1824 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1827 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1829 EXTRA: for my $extra (@extras) {
1830 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1831 next if ($extra eq '.svn');
1832 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1833 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1834 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1835 if (-l $abs_source) {
1836 # Symlink, is it in the right place?
1837 my $targ = readlink($abs_source);
1838 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1839 if ($abs_targ eq $abs_extra) {
1840 $extras{$extra} = "\e[32;1menabled\e[0m";
1842 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1844 } elsif (-e $abs_source) {
1845 my ($devext, $inoext) = stat($abs_extra);
1846 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1848 if ($devsrc == $devext && $inosrc == $inoext) {
1849 $extras{$extra} = "\e[32;1menabled\e[0m";
1851 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1854 open my $extfd, "<", $abs_extra;
1855 open my $srcfd, "<", $abs_source;
1857 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1858 $extras{$extra} = "\e[32;1menabled\e[0m";
1860 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1864 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1867 # Now let's add dependency info
1868 for my $extra (keys(%extras)) {
1869 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1870 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1871 my @deps = split / +/, getdependencies($abs_extra);
1872 for my $dep (@deps) {
1873 if (exists($extras{$dep})) {
1874 my $ref = \$extras{$dep}; # Take reference.
1875 if ($$ref !~ m/needed by/) {
1876 # First dependency found.
1877 if ($$ref =~ m/enabled/) {
1878 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1880 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1881 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1884 if ($$ref =~ m/enabled/) {
1885 $$ref .= ", \e[32;1m$extra\e[0m";
1887 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1893 for my $extra (sort {$a cmp $b} keys(%extras)) {
1894 my $text = $extras{$extra};
1895 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1896 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1898 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1901 return keys(%extras) if wantarray; # Can be used by manage_extras.
1904 sub enable_extras (@) {
1906 for my $extra (@extras) {
1907 my $extrapath = "src/modules/extra/$extra";
1908 if (!-e $extrapath) {
1909 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1912 my $source = "src/modules/$extra";
1914 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1917 # Get dependencies, and add them to be processed.
1918 my @deps = split / +/, getdependencies($extrapath);
1919 for my $dep (@deps) {
1920 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1921 if (!-e "src/modules/$dep") {
1922 if (-e "src/modules/extra/$dep") {
1923 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1926 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";
1930 print "Enabling $extra ... \n";
1931 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1935 sub disable_extras (@)
1937 opendir my $dd, "src/modules/extra/";
1938 my @files = readdir($dd);
1941 EXTRA: for my $extra (@extras) {
1942 my $extrapath = "src/modules/extra/$extra";
1943 my $source = "src/modules/$extra";
1944 if (!-e $extrapath) {
1945 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1948 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1949 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";
1952 # Check if anything needs this.
1953 for my $file (@files) {
1954 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1955 # File depends on this extra...
1956 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1957 # And is both enabled and not about to be disabled.
1958 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1959 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1965 print "Disabling $extra ... \n";
1966 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";