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_ports,
101 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
102 $opt_ipv6, $opt_ipv6links, $opt_noipv6links, $opt_maxbuf, $opt_disable_debug,
105 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
110 sub enable_extras (@);
112 sub disable_extras (@);
114 my @opt_enableextras;
115 my @opt_disableextras;
118 'enable-gnutls' => \$opt_use_gnutls,
119 'rebuild' => \$opt_rebuild,
120 'enable-openssl' => \$opt_use_openssl,
121 'disable-interactive' => \$opt_nointeractive,
122 'enable-ports' => \$opt_ports,
123 'enable-epoll' => \$opt_epoll,
124 'enable-kqueue' => \$opt_kqueue,
125 'disable-ports' => \$opt_noports,
126 'disable-epoll' => \$opt_noepoll,
127 'disable-kqueue' => \$opt_nokqueue,
128 'enable-ipv6' => \$opt_ipv6,
129 'enable-remote-ipv6' => \$opt_ipv6links,
130 'disable-remote-ipv6' => \$opt_noipv6links,
131 'with-cc=s' => \$opt_cc,
132 'with-maxbuf=i' => \$opt_maxbuf,
133 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
134 'prefix=s' => \$opt_base_dir,
135 'config-dir=s' => \$opt_config_dir,
136 'module-dir=s' => \$opt_module_dir,
137 'binary-dir=s' => \$opt_binary_dir,
138 'library-dir=s' => \$opt_library_dir,
139 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
140 'help' => sub { showhelp(); },
141 'modupdate' => sub { modupdate(); },
142 'update' => sub { update(); },
143 'svnupdate' => sub { svnupdate(); },
144 'clean' => sub { clean(); },
145 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
146 'enable-extras=s@' => \@opt_enableextras, # ^
147 'disable-extras=s@' => \@opt_disableextras, # ^
150 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
151 @opt_enableextras = split /,/, join(',', @opt_enableextras);
152 @opt_disableextras = split /,/, join(',', @opt_disableextras);
153 enable_extras(@opt_enableextras);
154 disable_extras(@opt_disableextras);
156 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
157 print "Run $0 -modupdate after you've done this to update the makefiles.\n";
161 our $non_interactive = (
162 (defined $opt_library_dir) ||
163 (defined $opt_base_dir) ||
164 (defined $opt_config_dir) ||
165 (defined $opt_module_dir) ||
166 (defined $opt_base_dir) ||
167 (defined $opt_binary_dir) ||
168 (defined $opt_nointeractive) ||
170 (defined $opt_ipv6) ||
171 (defined $opt_ipv6links) ||
172 (defined $opt_noipv6links) ||
173 (defined $opt_kqueue) ||
174 (defined $opt_epoll) ||
175 (defined $opt_ports) ||
176 (defined $opt_use_openssl) ||
177 (defined $opt_nokqueue) ||
178 (defined $opt_noepoll) ||
179 (defined $opt_noports) ||
180 (defined $opt_maxbuf) ||
181 (defined $opt_use_gnutls) ||
182 (defined $opt_freebsd_port)
184 our $interactive = !$non_interactive;
186 chomp(our $topdir = getcwd());
187 our $this = resolve_directory($topdir); # PWD, Regardless.
188 our @modlist = (); # Declare for Module List..
189 our %config = (); # Initiate Configuration Hash..
190 $config{ME} = resolve_directory($topdir); # Present Working Directory
192 $config{BASE_DIR} = $config{ME};
194 if (defined $opt_base_dir)
196 $config{BASE_DIR} = $opt_base_dir;
199 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
200 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
201 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
202 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
204 if (defined $opt_config_dir)
206 $config{CONFIG_DIR} = $opt_config_dir;
208 if (defined $opt_module_dir)
210 $config{MODULE_DIR} = $opt_module_dir;
212 if (defined $opt_binary_dir)
214 $config{BINARY_DIR} = $opt_binary_dir;
216 if (defined $opt_library_dir)
218 $config{LIBRARY_DIR} = $opt_library_dir;
220 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
222 if (defined $opt_freebsd_port)
224 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
225 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
226 $config{USE_FREEBSD_BASE_SSL} = "n";
230 if ($^O eq "freebsd")
232 # default: use base ssl
233 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
234 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
238 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
239 $config{HAS_OPENSSL_PORT} = "";
243 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
244 chomp(our $openssl_ver = $config{HAS_OPENSSL});
245 $config{USE_GNUTLS} = "n";
246 if (defined $opt_use_gnutls)
248 $config{USE_GNUTLS} = "y"; # Use gnutls.
250 $config{USE_OPENSSL} = "n"; # Use openssl.
251 if (defined $opt_use_openssl)
253 $config{USE_OPENSSL} = "y";
256 # no, let's not change these.
257 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
258 if (!defined $opt_disable_debug)
260 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
264 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
267 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
268 $config{HAS_STDINT} = "false"; # stdint.h check
269 $config{USE_KQUEUE} = "y"; # kqueue enabled
270 if (defined $opt_kqueue)
272 $config{USE_KQUEUE} = "y";
274 if (defined $opt_nokqueue)
276 $config{USE_KQUEUE} = "n";
278 $config{USE_POLL} = "y"; # poll enabled
279 $config{USE_EPOLL} = "y"; # epoll enabled
280 if (defined $opt_epoll)
282 $config{USE_EPOLL} = "y";
284 if (defined $opt_noepoll)
286 $config{USE_EPOLL} = "n";
288 $config{USE_PORTS} = "y"; # epoll enabled
289 if (defined $opt_ports)
291 $config{USE_PORTS} = "y";
293 if (defined $opt_noports)
295 $config{USE_PORTS} = "n";
297 $config{IPV6} = "n"; # IPv6 support (experimental)
298 if (defined $opt_ipv6)
302 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
303 if (defined $opt_ipv6links)
305 $config{SUPPORT_IP6LINKS} = "y";
307 if (defined $opt_noipv6links)
309 $config{SUPPORT_IP6LINKS} = "n";
311 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
312 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
313 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
314 $config{OSNAME} = $^O; # Operating System Name
315 $config{IS_DARWIN} = "NO"; # Is OSX?
316 $config{STARTSCRIPT} = "inspircd"; # start script?
317 $config{DESTINATION} = "BASE"; # Is target path.
318 $config{EXTRA_DIR} = ""; # Is empty.
319 if ($config{OSNAME} =~ /darwin/i)
321 $config{IS_DARWIN} = "YES";
322 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
323 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
324 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
326 $config{CC} = "g++"; # C++ compiler
329 $config{CC} = $opt_cc;
331 our $exec = $config{CC} . " -dumpversion | cut -c 1";
332 chomp($config{GCCVER} = `$exec`); # Major GCC Version
333 $exec = $config{CC} . " -dumpversion | cut -c 3";
334 chomp($config{GCCMINOR} = `$exec`);
335 $config{MAKEORDER} = "ircd mods"; # build order
336 $config{MAXBUF} = "512"; # Max buffer size
338 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
339 $config{HAS_OPENSSL} = $1;
341 $config{HAS_OPENSSL} = "";
344 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
345 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
349 # Get and Set some important vars..
354 unlink(".config.cache");
357 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
362 chomp($topdir = getcwd());
363 $this = resolve_directory($topdir); # PWD, Regardless.
365 # Does the cache file exist?
367 # No, No it doesn't.. *BASH*
368 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
371 # We've Loaded the cache file and all our variables..
372 print "Updating files...\n";
374 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
376 print "Disabling debug information (-g).\n";
377 $config{OPTIMISATI} = "";
380 $has_epoll = $config{HAS_EPOLL};
381 $has_ports = $config{HAS_PORTS};
382 $has_kqueue = $config{HAS_KQUEUE};
391 print "Configure update failed: $@\n";
399 chomp($topdir = getcwd());
400 $this = resolve_directory($topdir); # PWD, Regardless.
402 # Does the cache file exist?
404 # No, No it doesn't.. *BASH*
405 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
408 # We've Loaded the cache file and all our variables..
409 print "Updating files...\n";
411 $has_epoll = $config{HAS_EPOLL};
412 $has_ports = $config{HAS_PORTS};
413 $has_kqueue = $config{HAS_KQUEUE};
422 print "Module update failed: $@\n";
432 open(FH,"<.svn/entries") or $fail = 1;
434 print "This is not an SVN copy of InspIRCd.\n";
441 open my $fd, "-|", "svn update";
442 my $configurechanged = 0; # Needs ./configure -update
443 my $coredirchanged = 0; # Needs ./configure -update
444 my $moduledirchanged = 0; # Needs ./configure -modupdate
445 my $rootincchanged = 0;
447 while (defined(my $line = <$fd>))
451 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
452 ($action, $file) = ($1, $2);
455 push @conflicted, $file;
456 if ($file eq "configure")
458 $configurechanged = 1;
460 elsif ($file =~ m#^src/modules#)
462 $moduledirchanged = 1;
464 elsif ($file =~ m#^src/#)
468 elsif ($file =~ m/^\..*\.inc$/)
473 elsif ($action eq "U" || $action eq "G")
475 if ($file eq "configure")
477 $configurechanged = 1;
479 elsif ($file =~ m/^\..*\.inc$/)
484 elsif ($action eq "A" || $action eq "D")
486 if ($file =~ m#^src/modules#)
488 $moduledirchanged = 1;
490 elsif ($file =~ m#^src/#)
496 unless (close $fd) # close() waits for exit and returns false if the command failed
500 print STDERR "Problem updating from SVN, please check above for errors\n";
504 print STDERR "Failed to run SVN: $!\n";
508 if (scalar(@conflicted) > 0)
510 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
511 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate\n", (($coredirchanged || $configurechanged) ? "" : "mod");
512 print "Conflicted files: " . join ", ", @conflicted . "\n";
515 if ($configurechanged || $coredirchanged)
517 system("perl configure -update");
519 elsif ($moduledirchanged || $rootincchanged)
521 system("perl configure -modupdate");
525 print "No need to update Makefiles.\n";
527 if (defined $opt_rebuild) {
528 system("make install");
533 print "Running non-interactive configure...\n" unless $interactive;
534 print "Checking for cache from previous configure... ";
535 print ((!getcache()) ? "not found\n" : "found\n");
536 print "Checking operating system version... ";
537 print getosflags() . "\n";
539 printf "Checking if stdint.h exists... ";
540 $config{HAS_STDINT} = "true";
542 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
543 if ($config{HAS_STDINT} eq "true") {
546 print "yes\n" if $config{HAS_STDINT} eq "true";
547 print "no\n" if $config{HAS_STDINT} eq "false";
549 printf "Checking if strlcpy exists... ";
550 # Perform the strlcpy() test..
551 $config{HAS_STRLCPY} = "false";
553 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
555 while (defined(my $line = <STRLCPY>)) {
557 # try and find the delcaration of:
558 # size_t strlcpy(...)
559 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
560 $config{HAS_STRLCPY} = "true";
565 print "yes\n" if $config{HAS_STRLCPY} eq "true";
566 print "no\n" if $config{HAS_STRLCPY} eq "false";
568 printf "Checking if kqueue exists... ";
571 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
573 while (defined(my $line = <KQUEUE>)) {
575 # try and find the delcaration of:
577 if ($line =~ /int(\0x9|\s)+kqueue/) {
583 print "yes\n" if $has_kqueue == 1;
584 print "no\n" if $has_kqueue == 0;
586 printf "Checking if epoll exists... ";
589 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
595 my $kernel = `uname -r`;
597 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
602 # Suggestion from nenolod, weed out odd systems which have glibc built
603 # against 2.4 kernels (ick)
604 my $kernel_arch = `uname -p`;
608 if ($kernel_arch =~ /x86_64/) {
609 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
612 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
616 while (defined(my $line = <FH>))
619 if ($line =~ /GNU C Library .* version (.*?) /)
622 $libcv =~ /(\d+\.\d+)/;
625 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
628 # Fix for some retarded libc builds, strip off >> and << etc.
629 $kernelv =~ /(\d+\.\d+)/;
637 printf "libc too old: $libcv... ";
642 printf "libc built against older kernel $kernelv... ";
647 print "yes\n" if $has_epoll == 1;
648 print "no\n" if $has_epoll == 0;
650 printf "Checking if Solaris I/O completion ports are available... ";
652 our $system = `uname -s`;
654 $has_ports = 1 if ($system eq "SunOS");
657 my $kernel = `uname -r`;
659 if (($kernel !~ /^5\.1./)) {
663 print "yes\n" if $has_ports == 1;
664 print "no\n" if $has_ports == 0;
666 $config{HAS_EPOLL} = $has_epoll;
667 $config{HAS_KQUEUE} = $has_kqueue;
669 printf "Checking for libgnutls... ";
670 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
671 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
673 $config{HAS_GNUTLS} = "y";
676 $config{HAS_GNUTLS} = "n";
680 $config{HAS_GNUTLS} = "n";
683 printf "Checking for openssl... ";
684 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
685 if (defined($openssl_ver) && ($openssl_ver ne "")) {
687 $config{HAS_OPENSSL} = "y";
690 $config{HAS_OPENSSL} = "n";
694 $config{HAS_OPENSSL} = "n";
697 printf "Checking if you are running an ancient, unsupported OS... ";
698 if ($config{OSNAME} =~ /FreeBSD/i)
700 my $version = `uname -r`;
701 if ($version =~ /^4\./)
703 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
706 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
707 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
712 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
718 print "no ($version)\n";
724 print "no ($config{OSNAME})\n";
727 ################################################################################
728 # BEGIN INTERACTIVE PART #
729 ################################################################################
734 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
737 my $rev = getrevision();
738 # Display Introduction Message..
740 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
741 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
743 *** If you are unsure of any of these values, leave it blank for ***
744 *** standard settings that will work, and your server will run ***
745 *** using them. Please consult your IRC network admin if in doubt. ***
747 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
748 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
749 dir, otherwise you won't have a config file!
751 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
752 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
755 print " (Non-SVN build)";
759 $config{CHANGE_COMPILER} = "n";
760 print "I have detected the following compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
762 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
763 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
764 should NOT be used. You should probably specify a newer compiler.\n\n";
765 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
766 if ($config{CHANGE_COMPILER} =~ /y/i) {
767 print "What command do you want to use to invoke your compiler?\n";
768 print "[\e[1;32m$config{CC}\e[0m] -> ";
769 chomp($config{CC} = <STDIN>);
770 if ($config{CC} eq "") {
773 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
775 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
776 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
777 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
778 if ($config{GCCVER} < 3) {
779 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
783 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
790 # Directory Settings..
791 my $tmpbase = $config{BASE_DIR};
792 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
793 if ($tmpbase ne $config{BASE_DIR}) {
794 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
795 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
796 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
797 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
800 dir_check("are the configuration files", "CONFIG_DIR");
801 dir_check("are the modules to be compiled to", "MODULE_DIR");
802 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
803 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
805 my $chose_hiperf = 0;
807 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?");
809 if ($config{USE_KQUEUE} eq "y") {
814 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?");
816 if ($config{USE_EPOLL} eq "y") {
821 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?");
823 if ($config{USE_PORTS} eq "y") {
828 if (!$chose_hiperf) {
829 yesno('USE_POLL', "Would you like to use poll?\n This is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable poll?\n");
830 if ($config{USE_POLL} ne "y")
832 print "No high-performance socket engines are available, or you chose\n";
833 print "not to enable one. Defaulting to select() engine.\n\n";
837 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
840 if ($config{IPV6} eq "y") {
841 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";
842 $config{SUPPORT_IP6LINKS} = "y";
844 yesno('SUPPORT_IP6LINKS',"You have chosen to build an \e[1;32mIPV4-only\e[0m server.\nWould you like to enable support for linking to IPV6-enabled\nInspIRCd servers? If you are using a recent operating system and are\nunsure, answer yes. If you answer 'no' here, your InspIRCd server will\nbe unable to parse IPV6 addresses (e.g. for CIDR bans)\n\nEnable linking to servers which have IPV6 enabled?");
848 $config{USE_FREEBSD_BASE_SSL} = "n";
849 $config{USE_FREEBSD_PORTS_SSL} = "n";
850 if ($config{HAS_OPENSSL_PORT} ne "")
852 $config{USE_FREEBSD_PORTS_SSL} = "y";
853 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
854 print "version \e[1;32m".$config{HAS_OPENSSL_PORT}."\e[0m. Your base system OpenSSL is version \e[1;32m".$openssl_ver."\e[0m.\n\n";
855 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
857 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
859 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
861 # update to port version
862 $openssl_ver = $config{HAS_OPENSSL_PORT};
867 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
870 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
871 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
872 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
873 print "instead, you should enable the OpenSSL module yourself\n";
874 print "by copying it from src/modules/extra to src/modules.\n\n";
875 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
876 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
879 if ($config{HAS_GNUTLS} eq "y") {
880 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
881 if ($config{USE_GNUTLS} eq "y") {
882 print "\nUsing GnuTLS SSL module.\n";
884 } elsif ($config{HAS_OPENSSL} eq "y") {
885 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
886 if ($config{USE_OPENSSL} eq "y") {
887 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
891 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";
897 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
899 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
902 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
904 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
909 if ($config{USE_GNUTLS} eq "y") {
910 unless (-r "src/modules/m_ssl_gnutls.cpp") {
911 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
912 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
917 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
918 print "SSL Certificates Not found, Generating.. \n\n
919 *************************************************************
920 * Generating the Private Key may take some time, go grab a *
921 * Coffee. Even better, to generate some more entropy if it *
922 * is taking a while, open another console and type du / a *
923 * few times and get that HD going :) Then answer the *
924 * Questions which follow. If you are unsure, just hit enter *
925 *************************************************************\n\n";
926 $failed = make_gnutls_cert();
928 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
930 print "\nCertificate generation complete, copying to config directory... ";
931 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
932 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
937 print "SSL Certificates found, skipping.\n\n";
942 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
944 } elsif ($config{USE_OPENSSL} eq "y") {
945 unless (-r "src/modules/m_ssl_openssl.cpp") {
946 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
947 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.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 certificates may take some time, go grab a *
957 * coffee, or something. *
958 *************************************************************\n\n";
960 print "\nCertificate generation complete, copying to config directory... ";
961 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
962 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
963 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
966 print "SSL Certificates found, skipping.\n\n"
971 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
974 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
975 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
983 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
984 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
985 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
986 print "modules in your config. This configure script has added those modules to the\n";
987 print "build process. For more info please refer to:\n";
988 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
990 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
991 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
992 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";
995 if ($config{GCCVER} < "3") {
997 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
998 GCC 2.x series compilers only had partial (read as broken) C++ support, and
999 your compile will most likely fail horribly! If you have any problems, do NOT
1000 report them to the bugtracker or forums without first upgrading your compiler
1001 to a newer 3.x or 4.x (or whatever is available currently) version.
1005 ################################################################################
1006 # HELPER FUNCTIONS #
1007 ################################################################################
1009 # Retrieves the .config.cache file, and loads values into the main config hash.
1010 open(CACHE, ".config.cache") or return 0;
1013 # Ignore Blank lines, and comments..
1016 my ($key, $value) = split("=", $_, 2);
1017 $value =~ /^\"(.*)\"$/;
1018 # Do something with data here!
1026 # Dump the contents of %config
1027 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1028 open(FILEHANDLE, ">.config.cache");
1029 foreach my $key (keys %config) {
1030 print FILEHANDLE "$key=\"$config{$key}\"\n";
1036 my ($desc, $hash_key) = @_;
1038 while (!$complete) {
1039 print "In what directory $desc?\n";
1040 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1041 chomp(my $var = <STDIN>);
1043 $var = $config{$hash_key};
1045 if ($var =~ /^\~\/(.+)$/) {
1046 # Convert it to a full path..
1047 $var = resolve_directory($ENV{HOME} . "/" . $1);
1049 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1051 # Assume relative Path was given.. fill in the rest.
1052 $var = $this . "/$var";
1055 $var = resolve_directory($var);
1057 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1058 chomp(my $tmp = <STDIN>);
1059 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1060 # Attempt to Create the Dir..
1063 File::Path::mkpath($var, 0, 0777);
1066 unless (defined($chk) && -d $var) {
1067 print "Unable to create directory. ($var)\n\n";
1072 # They said they don't want to create, and we can't install there.
1077 if (!is_dir($var)) {
1078 # Target exists, but is not a directory.
1079 print "File $var exists, but is not a directory.\n\n";
1083 # Either Dir Exists, or was created fine.
1084 $config{$hash_key} = $var;
1094 # Beware: Linux sets it's own cflags below for some retarded reason
1095 $config{LDLIBS} = "-pthread -lstdc++";
1096 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1097 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1098 $SHARED = "-shared";
1099 $config{MAKEPROG} = "make";
1101 if ($config{OSNAME} =~ /darwin/i) {
1102 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1103 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1104 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1107 if ($config{OSNAME} =~ /OpenBSD/i) {
1108 $config{MAKEPROG} = "gmake";
1109 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1110 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1111 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1112 # if theyre not running this, configure lets the build continue but they probably wont manage to
1113 # compile as this standard version is 2.95.3!
1115 $config{CC} = "eg++";
1116 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1117 chomp($config{GCCMINOR} = `eg++ -dumpversion | cut -c 3`);
1122 if ($config{OSNAME} =~ /Linux/i) {
1123 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1124 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1125 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1126 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1127 $config{MAKEPROG} = "make";
1130 if ($config{OSNAME} =~ /FreeBSD/i) {
1131 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1132 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1135 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1137 # solaris/sunos needs these
1138 # socket = bsd sockets api
1140 # rt = POSIX realtime extensions
1141 # resolv = inet_aton only (why isnt this in nsl?!)
1142 $config{MAKEPROG} = "gmake";
1143 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1147 if($config{OSNAME} =~ /MINGW32/i)
1149 # All code is position-independent on windows
1150 $config{FLAGS} =~ s/-fPIC //;
1154 return $config{OSNAME};
1157 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1160 my($writeheader) = @_;
1162 # First File.. inspircd_config.h
1163 chomp(my $incos = `uname -n -s -r`);
1164 chomp(my $version = `sh src/version.sh`);
1165 chomp(my $revision2 = getrevision());
1166 if ($writeheader == 1)
1168 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1169 open(FILEHANDLE, ">include/inspircd_config.h");
1170 print FILEHANDLE <<EOF;
1171 /* Auto generated by configure, do not modify! */
1172 #ifndef __CONFIGURATION_AUTO__
1173 #define __CONFIGURATION_AUTO__
1175 /* this is for windows support. */
1176 #define CoreExport /**/
1177 #define DllExport /**/
1179 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1180 #define MOD_PATH "$config{MODULE_DIR}"
1181 #define VERSION "$version"
1182 #define REVISION "$revision2"
1183 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1184 #define OPTIMISATION $config{OPTIMITEMP}
1185 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1186 #define SYSTEM "$incos"
1187 #define ENTRYPOINT int main(int argc, char** argv)
1190 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1192 if ($config{OSNAME} =~ /SunOS/i) {
1193 print FILEHANDLE "#define IS_SOLARIS\n";
1195 if ($config{OSNAME} =~ /MINGW32/i) {
1196 print FILEHANDLE "#define IS_MINGW\n";
1198 if ($config{GCCVER} >= 3) {
1199 print FILEHANDLE "#define GCC3\n";
1202 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
1204 ($config{GCCVER} > 4)
1206 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
1208 if ($config{HAS_STRLCPY} eq "true") {
1209 print FILEHANDLE "#define HAS_STRLCPY\n";
1211 if ($config{HAS_STDINT} eq "true") {
1212 print FILEHANDLE "#define HAS_STDINT\n";
1214 if ($config{IPV6} =~ /y/i) {
1215 print FILEHANDLE "#define IPV6\n";
1217 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1218 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1221 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1222 print FILEHANDLE "#define USE_KQUEUE\n";
1223 $se = "socketengine_kqueue";
1226 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1227 print FILEHANDLE "#define USE_EPOLL\n";
1228 $se = "socketengine_epoll";
1231 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1232 print FILEHANDLE "#define USE_PORTS\n";
1233 $se = "socketengine_ports";
1236 # user didn't choose either epoll or select for their OS.
1237 # default them to USE_SELECT (ewwy puke puke)
1239 print "no hi-perf, " . $config{USE_POLL};
1240 if ($config{USE_POLL} eq "y")
1242 print FILEHANDLE "#define USE_POLL\n";
1243 $se = "socketengine_poll";
1247 print FILEHANDLE "#define USE_SELECT\n";
1248 $se = "socketengine_select";
1251 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1257 open(FILEHANDLE, ">include/inspircd_se_config.h");
1258 print FILEHANDLE <<EOF;
1259 /* Auto generated by configure, do not modify or commit to svn! */
1260 #ifndef __CONFIGURATION_SOCKETENGINE__
1261 #define __CONFIGURATION_SOCKETENGINE__
1263 #include "socketengines/$se.h"
1271 # Create a Modules List..
1273 foreach my $i (@modlist)
1275 $modules .= "m_".$i.".so ";
1277 chomp($modules); # Remove Redundant whitespace..
1279 opendir(DIRHANDLE, "src/modules");
1280 foreach my $name2 (sort readdir(DIRHANDLE)) {
1281 if ($name2 =~ /^m_(.+?)$/) {
1282 if (defined(opendir(MDIRHANDLE, "src/modules/$name2"))) {
1283 closedir(MDIRHANDLE);
1284 $modules .= "$name2.so ";
1285 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name2.so\n";
1289 closedir(DIRHANDLE);
1292 # Write all .in files.
1295 my $exe = "inspircd";
1297 # Do this once here, and cache it in the .*.inc files,
1298 # rather than attempting to read src/version.sh from
1299 # compiled code -- we might not have the source to hand.
1300 # Fix for bug#177 by Brain.
1302 chomp($version = `sh ./src/version.sh`);
1303 chomp(my $revision = getrevision());
1304 $version = "$version(r$revision)";
1306 # We can actually parse any file starting with . and ending with .inc,
1307 # but right now we only parse .inspircd.inc to form './inspircd'
1309 print "Writing \e[1;32mMakefiles\e[0m\n";
1310 write_dynamic_modules_makefile();
1311 write_dynamic_makefile();
1313 opendir(DIRHANDLE, $this);
1315 foreach my $name (sort readdir(DIRHANDLE)) {
1316 if ($name =~ /^\.(.+)\.inc$/) {
1319 # Bug #353, omit this on non-darwin
1320 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1322 # All .name.inc files need parsing!
1324 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1325 while (<FILEHANDLE>) {
1330 print "Writing \e[1;32m$file\e[0m ...\n";
1331 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1332 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1333 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1334 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1335 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1336 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1337 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1338 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1339 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1340 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1341 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1342 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1343 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1344 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1345 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1346 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1347 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1348 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1349 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1351 open(FILEHANDLE, ">$file");
1352 print FILEHANDLE $tmp;
1355 closedir(DIRHANDLE);
1357 # Make inspircd executable!
1358 chmod 0744, 'inspircd';
1361 sub write_dynamic_modules_makefile {
1362 # Modules Makefile..
1363 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1364 open(FILEHANDLE, ">src/modules/Makefile");
1367 # Module Makefile Header
1369 print FILEHANDLE <<EOF;
1370 ###################################################
1371 # Copyright 2002-2007 The InspIRCd Development Team
1372 # http://www.inspircd.org/wiki/index.php/Credits
1374 # Thanks to Andrew Church <achurch\@achurch.org>
1375 # for assisting with making this work right.
1377 # Automatically Generated by ./configure to add a
1378 # modules please run ./configure -modupdate
1379 ###################################################
1385 if ($config{OSNAME} =~ /darwin/) {
1386 print FILEHANDLE <<EOCHEESE;
1388 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1392 print FILEHANDLE <<EOCHEESE;
1394 PICLDFLAGS = -fPIC -DPIC -shared
1400 # End Module Makefile Header
1403 # Create a Modules List..
1407 foreach my $i (@modlist) {
1409 # Write Entry to the MakeFile
1411 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1412 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1413 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1415 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1418 if (nopedantic("src/modules/m_".$i.".cpp"))
1421 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
1422 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1428 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
1429 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1432 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1433 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1435 # End Write Entry to the MakeFile
1439 opendir(DIRHANDLE, "src/modules");
1440 foreach my $name (sort readdir(DIRHANDLE)) {
1441 if ($name =~ /^m_(.+?)$/) {
1446 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1447 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1448 read_module_directory("src/modules/$name", $name);
1449 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1450 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";
1451 if ($config{IS_DARWIN} eq "YES") {
1452 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1454 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1456 print FILEHANDLE "\n$mfrules\n";
1457 closedir(MDIRHANDLE);
1458 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1462 closedir(DIRHANDLE);
1465 sub read_module_directory {
1466 my ($dpath, $reldpath) = @_;
1468 if (opendir(MDIRHANDLE, $dpath) == 0) {
1472 foreach my $fname (sort readdir(MDIRHANDLE)) {
1473 if ($fname =~ /\.cpp$/) {
1474 my $cmflags = getcompilerflags("$dpath/$fname");
1475 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1476 my $deps = getdependencies("$dpath/$fname");
1478 $oname =~ s/\.cpp$/.o/g;
1479 $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";
1480 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1481 $mobjs = $mobjs . " $reldpath/$oname";
1484 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1485 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1492 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1493 # dependencies which are not relevent in C++.
1497 open (CPP, "<$file") or die("Can't open $file for reading!");
1502 foreach my $d (@ignoredeps)
1508 foreach my $dep (@immutabledeps)
1510 $immutable = $immutable . "../include/$dep ";
1512 $immutable =~ s/ $//g;
1514 while (defined(my $line = <CPP>))
1517 if ($line =~ /#include "(.+\.h)"/)
1519 if (!exists($dupe{$1}))
1521 $retlist = $retlist . "../include/$1 ";
1527 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1530 sub write_dynamic_makefile
1534 my %existing_install_list = ();
1535 my %core_files_list = ();
1537 opendir(DIRHANDLE, "src/commands");
1538 foreach my $name (sort readdir(DIRHANDLE))
1540 if ($name =~ /^cmd_(.+)\.cpp$/)
1542 $cmdlist[$i++] = $1;
1543 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1544 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1547 closedir(DIRHANDLE);
1551 $config{USE_EPOLL} = 0;
1555 $config{USE_KQUEUE} = 0;
1559 $config{USE_PORTS} = 0;
1562 # formerly generated below this foreach, now it's not! magic.
1565 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1567 print "Scanning \e[1;32m$dir\e[0m for core files ";
1568 opendir(DIRHANDLE, $dir);
1569 foreach my $name (sort readdir(DIRHANDLE))
1571 if ($name =~ /\.cpp$/)
1573 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1575 while (defined(my $line = <CPP>))
1578 if ($line =~ /\/\* \$Core \*\//i)
1581 $sname =~ s/\.cpp$/.o/;
1583 # append it to list to be built
1584 $all_core = $all_core . $sname . " ";
1585 $filelist{$name} = $sname;
1587 # mark it as a core file, so it won't get shared object cflags
1588 if (!exists($core_files_list{$name}))
1590 $core_files_list{$name} = 1;
1593 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1595 $specialdeps{$name} = $1;
1597 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1599 $extraobjects{$name} = $1;
1601 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1603 $extrabuildlines{$name} = $1;
1605 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1607 $extrasources{$name} = $1;
1609 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1611 if (defined $config{$1})
1613 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1616 while (defined($line = <CPP>))
1619 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1620 last if ($line =~ /\/\* \$EndIf \*\//i);
1625 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1627 if (!exists($existing_install_list{$1}))
1629 $existing_install_list{$1} = 1;
1630 my $idir = (split(' ',$1))[1];
1631 my $ifile = (split(' ',$1))[0];
1632 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1633 $ifile =~ s/.*\///g;
1634 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1637 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1639 if (!exists($existing_install_list{$1}))
1641 $existing_install_list{$1} = 1;
1642 my $idir = (split(' ',$1))[1];
1643 my $ifile = (split(' ',$1))[0];
1644 $install_list = $install_list . " -cp $1\n";
1645 $ifile =~ s/.*\///g;
1646 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1653 closedir(DIRHANDLE);
1657 # modes need to be compiled in too
1658 $all_core = $all_core . "modes/modeclasses.a";
1660 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1662 my $libraryext = "";
1663 my $binary_rule = "";
1665 if ($config{IS_DARWIN} eq "YES")
1667 $libraryext = "dylib";
1668 $binary_rule = " \@../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 "
1673 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1676 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1679 CC = im a cheezeball
1680 CXXFLAGS = -I../include \${FLAGS}
1681 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1682 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1686 my $buildstring = "";
1689 foreach my $cpp (sort keys %filelist)
1693 $objs =~ s/\.cpp$/.o/;
1694 if (exists($extraobjects{$cpp}))
1696 $objs = $objs . " " . $extraobjects{$cpp};
1697 $all_core = $all_core . " " . $extraobjects{$cpp};
1699 if (exists($extrasources{$cpp}))
1701 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1704 $deps = calcdeps("src/$cpp");
1705 if (exists($extrasources{$cpp}))
1707 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1709 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1712 $deps = $deps . $d . " ";
1716 $buildstring = $buildstring . $objs . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1718 if (exists($core_files_list{$cpp}))
1720 # core files are statically linked into the binary and do not require -export-dynamic
1721 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -c $rawcpp\n";
1725 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1728 if (exists($extrabuildlines{$cpp}))
1730 $buildstring = $buildstring . " " . $extrabuildlines{$cpp} . "\n";
1734 print FH "all: inspircd moo\n\n\n";
1736 $deps = calcdeps("src/inspircd.cpp");
1737 print FH "inspircd: inspircd.cpp $deps $all_core\n";
1738 print FH "$binary_rule $all_core\n\n";
1740 print FH $buildstring;
1741 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1743 # close main makefile
1747 # generate a list of .so
1748 foreach my $cmd (@cmdlist) {
1749 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1752 # and now reopen the commands makefile
1753 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1756 CXXFLAGS = -I../../include \${FLAGS}
1763 # now print the command file details.
1764 foreach my $cmd (@cmdlist) {
1766 cmd_$cmd.so: cmd_$cmd.cpp ../../include/base.h ../../include/modules.h ../../include/inspircd.h ../../include/channels.h ../../include/users.h ../../include/inspircd_config.h ../../include/commands/cmd_$cmd.h
1767 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1773 # Routine to list out the extra/ modules that have been enabled.
1774 # Note: when getting any filenames out and comparing, it's important to lc it if the
1775 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1776 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1777 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1778 sub list_extras () {
1781 my $srcdir = File::Spec->catdir("src", "modules");
1782 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1785 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1786 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1789 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1790 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1793 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1795 EXTRA: for my $extra (@extras) {
1796 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1797 next if ($extra eq '.svn');
1798 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1799 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1800 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1801 if (-l $abs_source) {
1802 # Symlink, is it in the right place?
1803 my $targ = readlink($abs_source);
1804 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1805 if ($abs_targ eq $abs_extra) {
1806 $extras{$extra} = "\e[32;1menabled\e[0m";
1808 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1810 } elsif (-e $abs_source) {
1811 my ($devext, $inoext) = stat($abs_extra);
1812 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1814 if ($devsrc == $devext && $inosrc == $inoext) {
1815 $extras{$extra} = "\e[32;1menabled\e[0m";
1817 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1820 open my $extfd, "<", $abs_extra;
1821 open my $srcfd, "<", $abs_source;
1823 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1824 $extras{$extra} = "\e[32;1menabled\e[0m";
1826 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1830 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1833 # Now let's add dependency info
1834 for my $extra (keys(%extras)) {
1835 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1836 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1837 my @deps = split / +/, getdependencies($abs_extra);
1838 for my $dep (@deps) {
1839 if (exists($extras{$dep})) {
1840 my $ref = \$extras{$dep}; # Take reference.
1841 if ($$ref !~ m/needed by/) {
1842 # First dependency found.
1843 if ($$ref =~ m/enabled/) {
1844 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1846 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1847 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1850 if ($$ref =~ m/enabled/) {
1851 $$ref .= ", \e[32;1m$extra\e[0m";
1853 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1859 for my $extra (sort {$a cmp $b} keys(%extras)) {
1860 my $text = $extras{$extra};
1861 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1862 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1864 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1867 return keys(%extras) if wantarray; # Can be used by manage_extras.
1870 sub enable_extras (@) {
1872 for my $extra (@extras) {
1873 my $extrapath = "src/modules/extra/$extra";
1874 if (!-e $extrapath) {
1875 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1878 my $source = "src/modules/$extra";
1880 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1883 # Get dependencies, and add them to be processed.
1884 my @deps = split / +/, getdependencies($extrapath);
1885 for my $dep (@deps) {
1886 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1887 if (!-e "src/modules/$dep") {
1888 if (-e "src/modules/extra/$dep") {
1889 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1892 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";
1896 print "Enabling $extra ... \n";
1897 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1901 sub disable_extras (@)
1903 opendir my $dd, "src/modules/extra/";
1904 my @files = readdir($dd);
1907 EXTRA: for my $extra (@extras) {
1908 my $extrapath = "src/modules/extra/$extra";
1909 my $source = "src/modules/$extra";
1910 if (!-e $extrapath) {
1911 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1914 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1915 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";
1918 # Check if anything needs this.
1919 for my $file (@files) {
1920 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1921 # File depends on this extra...
1922 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1923 # And is both enabled and not about to be disabled.
1924 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1925 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1931 print "Disabling $extra ... \n";
1932 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";