2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2009 The InspIRCd Development Team
6 # http://wiki.inspircd.org/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;
33 # Utility functions for our buildsystem
37 use make::opensslcert;
39 ###############################################################################################
43 ###############################################################################################
45 # If you wish to ignore a dependency throughout the entire core, add it here.
48 "inspircd_win32wrapper.h", # windows has its own configure program
51 # If you wish for all files in the entire core to have a given dependency, insert it here.
52 # You should keep this to an absolute minimum to avoid rebuilds that are not neccessary.
54 our @immutabledeps = (
55 "inspircd_config.h", # auto re-generated by configure
59 ###############################################################################################
61 # NON-EDITABLE VARIABLES
63 ###############################################################################################
65 # List of commands that make up 'make install' and 'make deinstall'
67 our $install_list = "";
68 our $uninstall_list = "";
70 # This is a list of all files in the core. Each cpp file is mapped to a shared object file,
71 # whos file extension is omitted (these can vary from system to system). Auto detected by
72 # scanning the src/*.cpp files for files containing /* $Core */ identifiers.
76 # If you wish for a file to have special dependencies in the makefile, add an entry here.
77 # Auto populated by /* $ExtraDeps: */ instruction
79 our %specialdeps = ();
81 # If you wish for a file to have extra make lines (in between the compile and link steps)
82 # then insert them here.
83 # Auto populated by /* $ExtraBuild: */ instruction
85 our %extrabuildlines = ();
87 # If you wish for a file to be linked against extra objects or arctives, insert them here.
88 # Auto populated by /* $ExtraObjects: */ instruction
90 our %extraobjects = ();
92 # If you wish to compile extra cpp sources into an object, define them here.
93 # NOTE: Certain cpp files such as the socket engines have a value auto calculated
94 # for this table so that their derived class is built.
95 # Auto populated by /* $ExtraSources: */ instruction
97 our %extrasources = ();
99 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
100 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
101 $opt_ipv6, $opt_ipv6links, $opt_noipv6links, $opt_maxbuf, $opt_disable_debug,
104 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
109 sub enable_extras (@);
111 sub disable_extras (@);
113 my @opt_enableextras;
114 my @opt_disableextras;
117 'enable-gnutls' => \$opt_use_gnutls,
118 'rebuild' => \$opt_rebuild,
119 'enable-openssl' => \$opt_use_openssl,
120 'disable-interactive' => \$opt_nointeractive,
121 'enable-ports' => \$opt_ports,
122 'enable-epoll' => \$opt_epoll,
123 'enable-kqueue' => \$opt_kqueue,
124 'disable-ports' => \$opt_noports,
125 'disable-epoll' => \$opt_noepoll,
126 'disable-kqueue' => \$opt_nokqueue,
127 'enable-ipv6' => \$opt_ipv6,
128 'enable-remote-ipv6' => \$opt_ipv6links,
129 'disable-remote-ipv6' => \$opt_noipv6links,
130 'with-cc=s' => \$opt_cc,
131 'with-maxbuf=i' => \$opt_maxbuf,
132 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
133 'prefix=s' => \$opt_base_dir,
134 'config-dir=s' => \$opt_config_dir,
135 'module-dir=s' => \$opt_module_dir,
136 'binary-dir=s' => \$opt_binary_dir,
137 'library-dir=s' => \$opt_library_dir,
138 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
139 'help' => sub { showhelp(); },
140 'modupdate' => sub { modupdate(); },
141 'update' => sub { update(); },
142 'svnupdate' => sub { svnupdate(); },
143 'clean' => sub { clean(); },
144 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
145 'enable-extras=s@' => \@opt_enableextras, # ^
146 'disable-extras=s@' => \@opt_disableextras, # ^
147 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
148 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
151 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
152 @opt_enableextras = split /,/, join(',', @opt_enableextras);
153 @opt_disableextras = split /,/, join(',', @opt_disableextras);
154 enable_extras(@opt_enableextras);
155 disable_extras(@opt_disableextras);
157 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
158 print "Run $0 -modupdate after you've done this to update the makefiles.\n";
162 our $non_interactive = (
163 (defined $opt_library_dir) ||
164 (defined $opt_base_dir) ||
165 (defined $opt_config_dir) ||
166 (defined $opt_module_dir) ||
167 (defined $opt_base_dir) ||
168 (defined $opt_binary_dir) ||
169 (defined $opt_nointeractive) ||
171 (defined $opt_ipv6) ||
172 (defined $opt_ipv6links) ||
173 (defined $opt_noipv6links) ||
174 (defined $opt_kqueue) ||
175 (defined $opt_epoll) ||
176 (defined $opt_ports) ||
177 (defined $opt_use_openssl) ||
178 (defined $opt_nokqueue) ||
179 (defined $opt_noepoll) ||
180 (defined $opt_noports) ||
181 (defined $opt_maxbuf) ||
182 (defined $opt_use_gnutls) ||
183 (defined $opt_freebsd_port)
185 our $interactive = !$non_interactive;
187 chomp(our $topdir = getcwd());
188 our $this = resolve_directory($topdir); # PWD, Regardless.
189 our @modlist = (); # Declare for Module List..
190 our %config = (); # Initiate Configuration Hash..
191 $config{ME} = resolve_directory($topdir); # Present Working Directory
193 $config{BASE_DIR} = $config{ME};
195 if (defined $opt_base_dir)
197 $config{BASE_DIR} = $opt_base_dir;
200 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
201 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
202 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
203 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
205 if (defined $opt_config_dir)
207 $config{CONFIG_DIR} = $opt_config_dir;
209 if (defined $opt_module_dir)
211 $config{MODULE_DIR} = $opt_module_dir;
213 if (defined $opt_binary_dir)
215 $config{BINARY_DIR} = $opt_binary_dir;
217 if (defined $opt_library_dir)
219 $config{LIBRARY_DIR} = $opt_library_dir;
221 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
223 if (defined $opt_freebsd_port)
225 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
226 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
227 $config{USE_FREEBSD_BASE_SSL} = "n";
231 if ($^O eq "freebsd")
233 # default: use base ssl
234 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
235 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
239 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
240 $config{HAS_OPENSSL_PORT} = "";
244 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
245 chomp(our $openssl_ver = $config{HAS_OPENSSL});
246 $config{USE_GNUTLS} = "n";
247 if (defined $opt_use_gnutls)
249 $config{USE_GNUTLS} = "y"; # Use gnutls.
251 $config{USE_OPENSSL} = "n"; # Use openssl.
252 if (defined $opt_use_openssl)
254 $config{USE_OPENSSL} = "y";
257 # no, let's not change these.
258 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
259 if (!defined $opt_disable_debug)
261 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
265 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
268 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
269 $config{HAS_STDINT} = "false"; # stdint.h check
270 $config{USE_KQUEUE} = "y"; # kqueue enabled
271 if (defined $opt_kqueue)
273 $config{USE_KQUEUE} = "y";
275 if (defined $opt_nokqueue)
277 $config{USE_KQUEUE} = "n";
279 $config{USE_POLL} = "y"; # poll enabled
280 $config{USE_EPOLL} = "y"; # epoll enabled
281 if (defined $opt_epoll)
283 $config{USE_EPOLL} = "y";
285 if (defined $opt_noepoll)
287 $config{USE_EPOLL} = "n";
289 $config{USE_PORTS} = "y"; # epoll enabled
290 if (defined $opt_ports)
292 $config{USE_PORTS} = "y";
294 if (defined $opt_noports)
296 $config{USE_PORTS} = "n";
298 $config{IPV6} = "n"; # IPv6 support (experimental)
299 if (defined $opt_ipv6)
303 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
304 if (defined $opt_ipv6links)
306 $config{SUPPORT_IP6LINKS} = "y";
308 if (defined $opt_noipv6links)
310 $config{SUPPORT_IP6LINKS} = "n";
312 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
313 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
314 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
315 $config{OSNAME} = $^O; # Operating System Name
316 $config{IS_DARWIN} = "NO"; # Is OSX?
317 $config{STARTSCRIPT} = "inspircd"; # start script?
318 $config{DESTINATION} = "BASE"; # Is target path.
319 $config{EXTRA_DIR} = ""; # Is empty.
320 if ($config{OSNAME} =~ /darwin/i)
322 $config{IS_DARWIN} = "YES";
323 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
324 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
325 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
327 $config{CC} = "g++"; # C++ compiler
330 $config{CC} = $opt_cc;
332 our $exec = $config{CC} . " -dumpversion | cut -c 1";
333 chomp($config{GCCVER} = `$exec`); # Major GCC Version
334 $exec = $config{CC} . " -dumpversion | cut -c 3";
335 chomp($config{GCCMINOR} = `$exec`);
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");
536 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
537 $fail ||= system "./test_$feature";
538 unlink "test_$feature";
542 print "Running non-interactive configure...\n" unless $interactive;
543 print "Checking for cache from previous configure... ";
544 print ((!getcache()) ? "not found\n" : "found\n");
545 print "Checking operating system version... ";
546 print getosflags() . "\n";
548 printf "Checking if stdint.h exists... ";
549 $config{HAS_STDINT} = "true";
551 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
552 if ($config{HAS_STDINT} eq "true") {
555 print "yes\n" if $config{HAS_STDINT} eq "true";
556 print "no\n" if $config{HAS_STDINT} eq "false";
558 printf "Checking if strlcpy exists... ";
559 # Perform the strlcpy() test..
560 $config{HAS_STRLCPY} = "false";
562 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
564 while (defined(my $line = <STRLCPY>)) {
566 # try and find the delcaration of:
567 # size_t strlcpy(...)
568 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
569 $config{HAS_STRLCPY} = "true";
574 print "yes\n" if $config{HAS_STRLCPY} eq "true";
575 print "no\n" if $config{HAS_STRLCPY} eq "false";
577 printf "Checking if kqueue exists... ";
580 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
582 while (defined(my $line = <KQUEUE>)) {
584 # try and find the delcaration of:
586 if ($line =~ /int(\0x9|\s)+kqueue/) {
592 print "yes\n" if $has_kqueue == 1;
593 print "no\n" if $has_kqueue == 0;
595 printf "Checking for epoll support... ";
596 $has_epoll = test_compile('epoll');
597 print $has_epoll ? "yes\n" : "no\n";
599 printf "Checking for eventfd support... ";
600 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
601 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
603 printf "Checking if Solaris I/O completion ports are available... ";
605 our $system = `uname -s`;
607 $has_ports = 1 if ($system eq "SunOS");
610 my $kernel = `uname -r`;
612 if (($kernel !~ /^5\.1./)) {
616 print "yes\n" if $has_ports == 1;
617 print "no\n" if $has_ports == 0;
619 $config{HAS_EPOLL} = $has_epoll;
620 $config{HAS_KQUEUE} = $has_kqueue;
622 printf "Checking for libgnutls... ";
623 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
624 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
626 $config{HAS_GNUTLS} = "y";
629 $config{HAS_GNUTLS} = "n";
633 $config{HAS_GNUTLS} = "n";
636 printf "Checking for openssl... ";
637 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
638 if (defined($openssl_ver) && ($openssl_ver ne "")) {
640 $config{HAS_OPENSSL} = "y";
643 $config{HAS_OPENSSL} = "n";
647 $config{HAS_OPENSSL} = "n";
650 printf "Checking if you are running an ancient, unsupported OS... ";
651 if ($config{OSNAME} =~ /FreeBSD/i)
653 my $version = `uname -r`;
654 if ($version =~ /^4\./)
656 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
659 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
660 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
661 print "yes (upgrade ffs, freebsd 4 is *way* out of date)\n";
665 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
671 print "no ($version)\n";
677 print "no ($config{OSNAME})\n";
680 ################################################################################
681 # BEGIN INTERACTIVE PART #
682 ################################################################################
687 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
690 my $rev = getrevision();
691 # Display Introduction Message..
693 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
694 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
696 *** If you are unsure of any of these values, leave it blank for ***
697 *** standard settings that will work, and your server will run ***
698 *** using them. Please consult your IRC network admin if in doubt. ***
700 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
701 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
702 dir, otherwise you won't have a config file!
704 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
705 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
708 print " (Non-SVN build)";
712 $config{CHANGE_COMPILER} = "n";
713 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";
715 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
716 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
717 should NOT be used. You should probably specify a newer compiler.\n\n";
718 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
719 if ($config{CHANGE_COMPILER} =~ /y/i) {
720 print "What command do you want to use to invoke your compiler?\n";
721 print "[\e[1;32m$config{CC}\e[0m] -> ";
722 chomp($config{CC} = <STDIN>);
723 if ($config{CC} eq "") {
726 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
728 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
729 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
730 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
731 if ($config{GCCVER} < 3) {
732 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
736 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
743 # Directory Settings..
744 my $tmpbase = $config{BASE_DIR};
745 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
746 if ($tmpbase ne $config{BASE_DIR}) {
747 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
748 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
749 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
750 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
753 dir_check("are the configuration files", "CONFIG_DIR");
754 dir_check("are the modules to be compiled to", "MODULE_DIR");
755 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
756 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
758 my $chose_hiperf = 0;
760 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?");
762 if ($config{USE_KQUEUE} eq "y") {
767 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?");
769 if ($config{USE_EPOLL} eq "y") {
774 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?");
776 if ($config{USE_PORTS} eq "y") {
781 if (!$chose_hiperf) {
782 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");
783 if ($config{USE_POLL} ne "y")
785 print "No high-performance socket engines are available, or you chose\n";
786 print "not to enable one. Defaulting to select() engine.\n\n";
790 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
793 if ($config{IPV6} eq "y") {
794 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";
795 $config{SUPPORT_IP6LINKS} = "y";
797 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?");
801 $config{USE_FREEBSD_BASE_SSL} = "n";
802 $config{USE_FREEBSD_PORTS_SSL} = "n";
803 if ($config{HAS_OPENSSL_PORT} ne "")
805 $config{USE_FREEBSD_PORTS_SSL} = "y";
806 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
807 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";
808 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
810 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
812 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
814 # update to port version
815 $openssl_ver = $config{HAS_OPENSSL_PORT};
820 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
823 $config{USE_SSL} = "n";
825 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
827 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
828 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
830 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
831 if ($config{USE_SSL} eq "y")
833 if ($config{HAS_GNUTLS} eq "y")
835 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
836 if ($config{USE_GNUTLS} eq "y")
838 print "\nUsing GnuTLS SSL module.\n";
842 if ($config{HAS_OPENSSL} eq "y")
844 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
845 if ($config{USE_OPENSSL} eq "y")
847 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
854 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
855 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
861 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
863 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
866 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
868 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
873 if ($config{USE_GNUTLS} eq "y") {
874 unless (-r "src/modules/m_ssl_gnutls.cpp") {
875 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
876 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
881 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
882 print "SSL Certificates Not found, Generating.. \n\n
883 *************************************************************
884 * Generating the Private Key may take some time, go grab a *
885 * Coffee. Even better, to generate some more entropy if it *
886 * is taking a while, open another console and type du / a *
887 * few times and get that HD going :) Then answer the *
888 * Questions which follow. If you are unsure, just hit enter *
889 *************************************************************\n\n";
890 $failed = make_gnutls_cert();
892 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
894 print "\nCertificate generation complete, copying to config directory... ";
895 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
896 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
901 print "SSL Certificates found, skipping.\n\n";
906 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
908 } elsif ($config{USE_OPENSSL} eq "y") {
909 unless (-r "src/modules/m_ssl_openssl.cpp") {
910 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
911 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.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 certificates may take some time, go grab a *
921 * coffee, or something. *
922 *************************************************************\n\n";
924 print "\nCertificate generation complete, copying to config directory... ";
925 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
926 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
927 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
930 print "SSL Certificates found, skipping.\n\n"
935 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
938 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
939 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
947 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
948 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
949 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
950 print "modules in your config. This configure script has added those modules to the\n";
951 print "build process. For more info please refer to:\n";
952 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
954 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
955 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
956 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";
959 if ($config{GCCVER} < "3") {
961 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
962 GCC 2.x series compilers only had partial (read as broken) C++ support, and
963 your compile will most likely fail horribly! If you have any problems, do NOT
964 report them to the bugtracker or forums without first upgrading your compiler
965 to a newer 3.x or 4.x (or whatever is available currently) version.
969 ################################################################################
971 ################################################################################
973 # Retrieves the .config.cache file, and loads values into the main config hash.
974 open(CACHE, ".config.cache") or return 0;
977 # Ignore Blank lines, and comments..
980 my ($key, $value) = split("=", $_, 2);
981 $value =~ /^\"(.*)\"$/;
982 # Do something with data here!
990 # Dump the contents of %config
991 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
992 open(FILEHANDLE, ">.config.cache");
993 foreach my $key (keys %config) {
994 print FILEHANDLE "$key=\"$config{$key}\"\n";
1000 my ($desc, $hash_key) = @_;
1002 while (!$complete) {
1003 print "In what directory $desc?\n";
1004 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1005 chomp(my $var = <STDIN>);
1007 $var = $config{$hash_key};
1009 if ($var =~ /^\~\/(.+)$/) {
1010 # Convert it to a full path..
1011 $var = resolve_directory($ENV{HOME} . "/" . $1);
1013 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1015 # Assume relative Path was given.. fill in the rest.
1016 $var = $this . "/$var";
1019 $var = resolve_directory($var);
1021 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1022 chomp(my $tmp = <STDIN>);
1023 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1024 # Attempt to Create the Dir..
1027 File::Path::mkpath($var, 0, 0777);
1030 unless (defined($chk) && -d $var) {
1031 print "Unable to create directory. ($var)\n\n";
1036 # They said they don't want to create, and we can't install there.
1041 if (!is_dir($var)) {
1042 # Target exists, but is not a directory.
1043 print "File $var exists, but is not a directory.\n\n";
1047 # Either Dir Exists, or was created fine.
1048 $config{$hash_key} = $var;
1058 # Beware: Linux sets it's own cflags below for some retarded reason
1059 $config{LDLIBS} = "-pthread -lstdc++";
1060 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1061 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1062 $SHARED = "-shared -export-dynamic";
1063 $config{MAKEPROG} = "make";
1065 if ($config{OSNAME} =~ /darwin/i) {
1066 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1067 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1068 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1071 if ($config{OSNAME} =~ /OpenBSD/i) {
1072 $config{MAKEPROG} = "gmake";
1073 # apparantly (Dagonet says) that this causes problems, so let's try without it.
1074 # $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1075 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1076 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1077 # if theyre not running this, configure lets the build continue but they probably wont manage to
1078 # compile as this standard version is 2.95.3!
1080 $config{CC} = "eg++";
1081 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1082 chomp($config{GCCMINOR} = `eg++ -dumpversion | cut -c 3`);
1087 if ($config{OSNAME} =~ /Linux/i) {
1088 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1089 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1090 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1091 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1092 $config{MAKEPROG} = "make";
1095 if ($config{OSNAME} =~ /FreeBSD/i) {
1096 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1097 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1100 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1102 # solaris/sunos needs these
1103 # socket = bsd sockets api
1105 # rt = POSIX realtime extensions
1106 # resolv = inet_aton only (why isnt this in nsl?!)
1107 $config{MAKEPROG} = "gmake";
1108 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1112 if($config{OSNAME} =~ /MINGW32/i)
1114 # All code is position-independent on windows
1115 $config{FLAGS} =~ s/-fPIC //;
1119 return $config{OSNAME};
1122 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1125 my($writeheader) = @_;
1127 # First File.. inspircd_config.h
1128 chomp(my $incos = `uname -n -s -r`);
1129 chomp(my $version = `sh src/version.sh`);
1130 chomp(my $revision2 = getrevision());
1131 if ($writeheader == 1)
1133 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1134 open(FILEHANDLE, ">include/inspircd_config.h");
1135 print FILEHANDLE <<EOF;
1136 /* Auto generated by configure, do not modify! */
1137 #ifndef __CONFIGURATION_AUTO__
1138 #define __CONFIGURATION_AUTO__
1140 /* this is for windows support. */
1141 #define CoreExport /**/
1142 #define DllExport /**/
1144 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1145 #define MOD_PATH "$config{MODULE_DIR}"
1146 #define VERSION "$version"
1147 #define REVISION "$revision2"
1148 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1149 #define OPTIMISATION $config{OPTIMITEMP}
1150 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1151 #define SYSTEM "$incos"
1152 #define ENTRYPOINT int main(int argc, char** argv)
1155 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1157 if ($config{OSNAME} =~ /SunOS/i) {
1158 print FILEHANDLE "#define IS_SOLARIS\n";
1160 if ($config{OSNAME} =~ /MINGW32/i) {
1161 print FILEHANDLE "#define IS_MINGW\n";
1163 if ($config{GCCVER} >= 3) {
1164 print FILEHANDLE "#define GCC3\n";
1167 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
1169 ($config{GCCVER} > 4)
1171 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
1173 if ($config{HAS_STRLCPY} eq "true") {
1174 print FILEHANDLE "#define HAS_STRLCPY\n";
1176 if ($config{HAS_STDINT} eq "true") {
1177 print FILEHANDLE "#define HAS_STDINT\n";
1179 if ($config{IPV6} =~ /y/i) {
1180 print FILEHANDLE "#define IPV6\n";
1182 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1183 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1185 if ($config{HAS_EVENTFD} eq 'true') {
1186 print FILEHANDLE "#define HAS_EVENTFD\n";
1189 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1190 print FILEHANDLE "#define USE_KQUEUE\n";
1191 $se = "socketengine_kqueue";
1194 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1195 print FILEHANDLE "#define USE_EPOLL\n";
1196 $se = "socketengine_epoll";
1199 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1200 print FILEHANDLE "#define USE_PORTS\n";
1201 $se = "socketengine_ports";
1204 # user didn't choose either epoll or select for their OS.
1205 # default them to USE_SELECT (ewwy puke puke)
1207 print "no hi-perf, " . $config{USE_POLL};
1208 if ($config{USE_POLL} eq "y")
1210 print FILEHANDLE "#define USE_POLL\n";
1211 $se = "socketengine_poll";
1215 print FILEHANDLE "#define USE_SELECT\n";
1216 $se = "socketengine_select";
1219 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1225 open(FILEHANDLE, ">include/inspircd_se_config.h");
1226 print FILEHANDLE <<EOF;
1227 /* Auto generated by configure, do not modify or commit to svn! */
1228 #ifndef __CONFIGURATION_SOCKETENGINE__
1229 #define __CONFIGURATION_SOCKETENGINE__
1231 #include "socketengines/$se.h"
1239 # Create a Modules List..
1241 foreach my $i (@modlist)
1243 $modules .= "m_".$i.".so ";
1245 chomp($modules); # Remove Redundant whitespace..
1247 opendir(DIRHANDLE, "src/modules");
1248 foreach my $name2 (sort readdir(DIRHANDLE)) {
1249 if ($name2 =~ /^m_(.+?)$/) {
1250 if (defined(opendir(MDIRHANDLE, "src/modules/$name2"))) {
1251 closedir(MDIRHANDLE);
1252 $modules .= "$name2.so ";
1253 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name2.so\n";
1257 closedir(DIRHANDLE);
1260 # Write all .in files.
1263 my $exe = "inspircd";
1265 # Do this once here, and cache it in the .*.inc files,
1266 # rather than attempting to read src/version.sh from
1267 # compiled code -- we might not have the source to hand.
1268 # Fix for bug#177 by Brain.
1270 chomp($version = `sh ./src/version.sh`);
1271 chomp(my $revision = getrevision());
1272 $version = "$version(r$revision)";
1274 # We can actually parse any file starting with . and ending with .inc,
1275 # but right now we only parse .inspircd.inc to form './inspircd'
1277 print "Writing \e[1;32mMakefiles\e[0m\n";
1278 write_dynamic_modules_makefile();
1279 write_dynamic_makefile();
1281 opendir(DIRHANDLE, $this);
1283 foreach my $name (sort readdir(DIRHANDLE)) {
1284 if ($name =~ /^\.(.+)\.inc$/) {
1287 # Bug #353, omit this on non-darwin
1288 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1290 # All .name.inc files need parsing!
1292 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1293 while (<FILEHANDLE>) {
1298 print "Writing \e[1;32m$file\e[0m ...\n";
1299 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1300 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1301 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1302 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1303 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1304 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1305 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1306 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1307 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1308 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1309 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1310 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1311 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1312 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1313 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1314 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1315 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1317 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1318 print FILEHANDLE $tmp;
1321 closedir(DIRHANDLE);
1323 # Make inspircd executable!
1324 chmod 0744, 'inspircd';
1327 sub write_dynamic_modules_makefile {
1328 # Modules Makefile..
1329 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1330 open(FILEHANDLE, ">src/modules/Makefile");
1333 # Module Makefile Header
1335 print FILEHANDLE <<EOF;
1336 ###################################################
1337 # Copyright 2002-2009 The InspIRCd Development Team
1338 # http://wiki.inspircd.org/Credits
1340 # Thanks to Andrew Church <achurch\@achurch.org>
1341 # for assisting with making this work right.
1343 # Automatically Generated by ./configure to add a
1344 # modules please run ./configure -modupdate
1345 ###################################################
1351 if ($config{OSNAME} =~ /darwin/) {
1352 print FILEHANDLE <<EOCHEESE;
1354 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1358 print FILEHANDLE <<EOCHEESE;
1360 PICLDFLAGS = -fPIC -DPIC -shared
1366 # End Module Makefile Header
1369 # Create a Modules List..
1373 foreach my $i (@modlist) {
1375 # Write Entry to the MakeFile
1377 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1378 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1379 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1381 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1384 if (nopedantic("src/modules/m_".$i.".cpp"))
1387 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
1388 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags $SHARED -o m_$i.so m_$i.cpp
1394 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
1395 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags $SHARED -o m_$i.so m_$i.cpp
1398 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1399 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1401 # End Write Entry to the MakeFile
1405 opendir(DIRHANDLE, "src/modules");
1406 foreach my $name (sort readdir(DIRHANDLE)) {
1407 if ($name =~ /^m_(.+?)$/) {
1412 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1413 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1414 read_module_directory("src/modules/$name", $name);
1415 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1416 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";
1417 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) $SHARED $mliflags -o $name.so $mobjs\n";
1418 print FILEHANDLE "\n$mfrules\n";
1419 closedir(MDIRHANDLE);
1420 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1424 closedir(DIRHANDLE);
1427 sub read_module_directory {
1428 my ($dpath, $reldpath) = @_;
1430 if (opendir(MDIRHANDLE, $dpath) == 0) {
1434 foreach my $fname (sort readdir(MDIRHANDLE)) {
1435 if ($fname =~ /\.cpp$/) {
1436 my $cmflags = getcompilerflags("$dpath/$fname");
1437 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1438 my $deps = getdependencies("$dpath/$fname");
1440 $oname =~ s/\.cpp$/.o/g;
1441 $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";
1442 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags $SHARED -o $reldpath/$oname -c $reldpath/$fname\n\n";
1443 $mobjs = $mobjs . " $reldpath/$oname";
1446 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1447 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1454 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1455 # dependencies which are not relevent in C++.
1459 open (CPP, "<$file") or die("Can't open $file for reading!");
1464 foreach my $d (@ignoredeps)
1470 foreach my $dep (@immutabledeps)
1472 $immutable = $immutable . "../include/$dep ";
1474 $immutable =~ s/ $//g;
1476 while (defined(my $line = <CPP>))
1479 if ($line =~ /#include "(.+\.h)"/)
1481 if (!exists($dupe{$1}))
1483 $retlist = $retlist . "../include/$1 ";
1489 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1492 sub write_dynamic_makefile
1496 my %existing_install_list = ();
1497 my %core_files_list = ();
1499 opendir(DIRHANDLE, "src/commands");
1500 foreach my $name (sort readdir(DIRHANDLE))
1502 if ($name =~ /^cmd_(.+)\.cpp$/)
1504 $cmdlist[$i++] = $1;
1505 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1506 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1509 closedir(DIRHANDLE);
1513 $config{USE_EPOLL} = 0;
1517 $config{USE_KQUEUE} = 0;
1521 $config{USE_PORTS} = 0;
1524 # formerly generated below this foreach, now it's not! magic.
1527 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1529 print "Scanning \e[1;32m$dir\e[0m for core files ";
1530 opendir(DIRHANDLE, $dir);
1531 foreach my $name (sort readdir(DIRHANDLE))
1533 if ($name =~ /\.cpp$/)
1535 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1537 while (defined(my $line = <CPP>))
1540 if ($line =~ /\/\* \$Core \*\//i)
1543 $sname =~ s/\.cpp$/.o/;
1545 # append it to list to be built
1546 $all_core = $all_core . $sname . " ";
1547 $filelist{$name} = $sname;
1549 # mark it as a core file, so it won't get shared object cflags
1550 if (!exists($core_files_list{$name}))
1552 $core_files_list{$name} = 1;
1555 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1557 $specialdeps{$name} = $1;
1559 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1561 $extraobjects{$name} = $1;
1563 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1565 $extrabuildlines{$name} = $1;
1567 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1569 $extrasources{$name} = $1;
1571 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1573 if (defined $config{$1})
1575 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1578 while (defined($line = <CPP>))
1581 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1582 last if ($line =~ /\/\* \$EndIf \*\//i);
1587 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1589 if (!exists($existing_install_list{$1}))
1591 $existing_install_list{$1} = 1;
1592 my $idir = (split(' ',$1))[1];
1593 my $ifile = (split(' ',$1))[0];
1594 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1595 $ifile =~ s/.*\///g;
1596 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1599 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1601 if (!exists($existing_install_list{$1}))
1603 $existing_install_list{$1} = 1;
1604 my $idir = (split(' ',$1))[1];
1605 my $ifile = (split(' ',$1))[0];
1606 $install_list = $install_list . " -cp $1\n";
1607 $ifile =~ s/.*\///g;
1608 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1615 closedir(DIRHANDLE);
1619 # modes need to be compiled in too
1620 $all_core = $all_core . "modes/modeclasses.a";
1622 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1624 my $libraryext = "";
1625 my $binary_rule = "";
1627 if ($config{IS_DARWIN} eq "YES")
1629 $libraryext = "dylib";
1630 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -c inspircd.cpp\n \@../make/run-cc.pl \$(CC) -pipe -dynamic -bind_at_load -L. -o inspircd \$(LDLIBS) inspircd.o "
1635 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1638 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1641 CC = im a cheezeball
1642 CXXFLAGS = -I../include \${FLAGS}
1643 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1644 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1648 my $buildstring = "";
1651 foreach my $cpp (sort keys %filelist)
1655 $objs =~ s/\.cpp$/.o/;
1656 if (exists($extraobjects{$cpp}))
1658 $objs = $objs . " " . $extraobjects{$cpp};
1659 $all_core = $all_core . " " . $extraobjects{$cpp};
1661 if (exists($extrasources{$cpp}))
1663 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1666 $deps = calcdeps("src/$cpp");
1667 if (exists($extrasources{$cpp}))
1669 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1671 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1674 $deps = $deps . $d . " ";
1678 $buildstring = $buildstring . $objs . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1680 if (exists($core_files_list{$cpp}))
1682 # core files are statically linked into the binary and do not require $SHARED shared libs switches
1683 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -c $rawcpp\n";
1687 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) $SHARED -c $rawcpp\n";
1690 if (exists($extrabuildlines{$cpp}))
1692 $buildstring = $buildstring . " " . $extrabuildlines{$cpp} . "\n";
1696 print FH "all: inspircd moo\n\n\n";
1698 $deps = calcdeps("src/inspircd.cpp");
1699 print FH "inspircd: inspircd.cpp $deps $all_core\n";
1700 print FH "$binary_rule $all_core\n\n";
1702 print FH $buildstring;
1703 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1705 # close main makefile
1709 # generate a list of .so
1710 foreach my $cmd (@cmdlist) {
1711 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1714 # and now reopen the commands makefile
1715 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1718 CXXFLAGS = -I../../include \${FLAGS}
1725 # now print the command file detail
1726 foreach my $cmd (@cmdlist) {
1728 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
1729 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1735 # Routine to list out the extra/ modules that have been enabled.
1736 # Note: when getting any filenames out and comparing, it's important to lc it if the
1737 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1738 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1739 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1740 sub list_extras () {
1743 my $srcdir = File::Spec->catdir("src", "modules");
1744 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1747 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1748 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1751 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1752 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1755 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1757 EXTRA: for my $extra (@extras) {
1758 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1759 next if ($extra eq '.svn');
1760 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1761 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1762 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1763 if (-l $abs_source) {
1764 # Symlink, is it in the right place?
1765 my $targ = readlink($abs_source);
1766 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1767 if ($abs_targ eq $abs_extra) {
1768 $extras{$extra} = "\e[32;1menabled\e[0m";
1770 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1772 } elsif (-e $abs_source) {
1773 my ($devext, $inoext) = stat($abs_extra);
1774 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1776 if ($devsrc == $devext && $inosrc == $inoext) {
1777 $extras{$extra} = "\e[32;1menabled\e[0m";
1779 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1782 open my $extfd, "<", $abs_extra;
1783 open my $srcfd, "<", $abs_source;
1785 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1786 $extras{$extra} = "\e[32;1menabled\e[0m";
1788 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1792 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1795 # Now let's add dependency info
1796 for my $extra (keys(%extras)) {
1797 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1798 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1799 my @deps = split / +/, getdependencies($abs_extra);
1800 for my $dep (@deps) {
1801 if (exists($extras{$dep})) {
1802 my $ref = \$extras{$dep}; # Take reference.
1803 if ($$ref !~ m/needed by/) {
1804 # First dependency found.
1805 if ($$ref =~ m/enabled/) {
1806 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1808 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1809 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1812 if ($$ref =~ m/enabled/) {
1813 $$ref .= ", \e[32;1m$extra\e[0m";
1815 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1821 for my $extra (sort {$a cmp $b} keys(%extras)) {
1822 my $text = $extras{$extra};
1823 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1824 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1826 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1829 return keys(%extras) if wantarray; # Can be used by manage_extras.
1832 sub enable_extras (@) {
1834 for my $extra (@extras) {
1835 my $extrapath = "src/modules/extra/$extra";
1836 if (!-e $extrapath) {
1837 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1840 my $source = "src/modules/$extra";
1842 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1845 # Get dependencies, and add them to be processed.
1846 my @deps = split / +/, getdependencies($extrapath);
1847 for my $dep (@deps) {
1848 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1849 if (!-e "src/modules/$dep") {
1850 if (-e "src/modules/extra/$dep") {
1851 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1854 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";
1858 print "Enabling $extra ... \n";
1859 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1863 sub disable_extras (@)
1865 opendir my $dd, "src/modules/extra/";
1866 my @files = readdir($dd);
1869 EXTRA: for my $extra (@extras) {
1870 my $extrapath = "src/modules/extra/$extra";
1871 my $source = "src/modules/$extra";
1872 if (!-e $extrapath) {
1873 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1876 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1877 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";
1880 # Check if anything needs this.
1881 for my $file (@files) {
1882 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1883 # File depends on this extra...
1884 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1885 # And is both enabled and not about to be disabled.
1886 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1887 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1893 print "Disabling $extra ... \n";
1894 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";