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, $opt_disablerpath,
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 'disable-rpath' => \$opt_disablerpath,
129 'enable-ipv6' => \$opt_ipv6,
130 'enable-remote-ipv6' => \$opt_ipv6links,
131 'disable-remote-ipv6' => \$opt_noipv6links,
132 'with-cc=s' => \$opt_cc,
133 'with-maxbuf=i' => \$opt_maxbuf,
134 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
135 'prefix=s' => \$opt_base_dir,
136 'config-dir=s' => \$opt_config_dir,
137 'module-dir=s' => \$opt_module_dir,
138 'binary-dir=s' => \$opt_binary_dir,
139 'library-dir=s' => \$opt_library_dir,
140 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
141 'help' => sub { showhelp(); },
142 'modupdate' => sub { modupdate(); },
143 'update' => sub { update(); },
144 'svnupdate' => sub { svnupdate(); },
145 'clean' => sub { clean(); },
146 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
147 'enable-extras=s@' => \@opt_enableextras, # ^
148 'disable-extras=s@' => \@opt_disableextras, # ^
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_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"))) {
672 $config{HAS_GNUTLS} = "y";
675 $config{HAS_GNUTLS} = "n";
678 printf "Checking for openssl... ";
679 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
681 $config{HAS_OPENSSL} = "y";
684 $config{HAS_OPENSSL} = "n";
687 printf "Checking if you are running an ancient, unsupported OS... ";
688 if ($config{OSNAME} =~ /FreeBSD/i)
690 my $version = `uname -r`;
691 if ($version =~ /^4\./)
693 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
696 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
697 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
702 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
708 print "no ($version)\n";
714 print "no ($config{OSNAME})\n";
717 ################################################################################
718 # BEGIN INTERACTIVE PART #
719 ################################################################################
724 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
727 my $rev = getrevision();
728 # Display Introduction Message..
730 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
731 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
733 *** If you are unsure of any of these values, leave it blank for ***
734 *** standard settings that will work, and your server will run ***
735 *** using them. Please consult your IRC network admin if in doubt. ***
737 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
738 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
739 dir, otherwise you won't have a config file!
741 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
742 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
745 print " (Non-SVN build)";
749 $config{CHANGE_COMPILER} = "n";
750 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";
752 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
753 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
754 should NOT be used. You should probably specify a newer compiler.\n\n";
755 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
756 if ($config{CHANGE_COMPILER} =~ /y/i) {
757 print "What command do you want to use to invoke your compiler?\n";
758 print "[\e[1;32m$config{CC}\e[0m] -> ";
759 chomp($config{CC} = <STDIN>);
760 if ($config{CC} eq "") {
763 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
765 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
766 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
767 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
768 if ($config{GCCVER} < 3) {
769 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
773 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
780 # Directory Settings..
781 my $tmpbase = $config{BASE_DIR};
782 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
783 if ($tmpbase ne $config{BASE_DIR}) {
784 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
785 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
786 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
787 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
790 dir_check("are the configuration files", "CONFIG_DIR");
791 dir_check("are the modules to be compiled to", "MODULE_DIR");
792 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
793 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
796 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?");
800 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?");
804 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?");
807 my $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
808 if (!$chose_hiperf) {
809 print "No high-performance socket engines are available, or you chose\n";
810 print "not to enable one. Defaulting to select() engine.\n\n";
813 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
816 if ($config{IPV6} eq "y") {
817 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";
818 $config{SUPPORT_IP6LINKS} = "y";
820 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?");
824 $config{USE_FREEBSD_BASE_SSL} = "n";
825 $config{USE_FREEBSD_PORTS_SSL} = "n";
826 if ($config{HAS_OPENSSL_PORT} ne "")
828 $config{USE_FREEBSD_PORTS_SSL} = "y";
829 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
830 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";
831 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
833 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
835 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
837 # update to port version
838 $openssl_ver = $config{HAS_OPENSSL_PORT};
843 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
846 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
847 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
848 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
849 print "instead, you should enable the OpenSSL module yourself\n";
850 print "by copying it from src/modules/extra to src/modules.\n\n";
851 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
852 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
855 if ($config{HAS_GNUTLS} eq "y") {
856 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
857 if ($config{USE_GNUTLS} eq "y") {
858 print "\nUsing GnuTLS SSL module.\n";
860 } elsif ($config{HAS_OPENSSL} eq "y") {
861 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
862 if ($config{USE_OPENSSL} eq "y") {
863 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
867 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";
873 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
875 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
878 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
880 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
885 if ($config{USE_GNUTLS} eq "y") {
886 unless (-r "src/modules/m_ssl_gnutls.cpp") {
887 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
888 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
893 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
894 print "SSL Certificates Not found, Generating.. \n\n
895 *************************************************************
896 * Generating the Private Key may take some time, go grab a *
897 * Coffee. Even better, to generate some more entropy if it *
898 * is taking a while, open another console and type du / a *
899 * few times and get that HD going :) Then answer the *
900 * Questions which follow. If you are unsure, just hit enter *
901 *************************************************************\n\n";
902 $failed = make_gnutls_cert();
904 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
906 print "\nCertificate generation complete, copying to config directory... ";
907 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
908 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
913 print "SSL Certificates found, skipping.\n\n";
918 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
920 } elsif ($config{USE_OPENSSL} eq "y") {
921 unless (-r "src/modules/m_ssl_openssl.cpp") {
922 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
923 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
929 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
930 print "SSL Certificates Not found, Generating.. \n\n
931 *************************************************************
932 * Generating the certificates may take some time, go grab a *
933 * coffee, or something. *
934 *************************************************************\n\n";
936 print "\nCertificate generation complete, copying to config directory... ";
937 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
938 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
939 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
942 print "SSL Certificates found, skipping.\n\n"
947 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
950 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
951 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
959 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
960 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
961 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
962 print "modules in your config. This configure script has added those modules to the\n";
963 print "build process. For more info please refer to:\n";
964 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
966 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
967 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
968 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";
971 if ($config{GCCVER} < "3") {
973 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
974 GCC 2.x series compilers only had partial (read as broken) C++ support, and
975 your compile will most likely fail horribly! If you have any problems, do NOT
976 report them to the bugtracker or forums without first upgrading your compiler
977 to a newer 3.x or 4.x (or whatever is available currently) version.
981 ################################################################################
983 ################################################################################
985 # Retrieves the .config.cache file, and loads values into the main config hash.
986 open(CACHE, ".config.cache") or return 0;
989 # Ignore Blank lines, and comments..
992 my ($key, $value) = split("=", $_, 2);
993 $value =~ /^\"(.*)\"$/;
994 # Do something with data here!
1002 # Dump the contents of %config
1003 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1004 open(FILEHANDLE, ">.config.cache");
1005 foreach my $key (keys %config) {
1006 print FILEHANDLE "$key=\"$config{$key}\"\n";
1012 my ($desc, $hash_key) = @_;
1014 while (!$complete) {
1015 print "In what directory $desc?\n";
1016 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1017 chomp(my $var = <STDIN>);
1019 $var = $config{$hash_key};
1021 if ($var =~ /^\~\/(.+)$/) {
1022 # Convert it to a full path..
1023 $var = resolve_directory($ENV{HOME} . "/" . $1);
1025 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1027 # Assume relative Path was given.. fill in the rest.
1028 $var = $this . "/$var";
1031 $var = resolve_directory($var);
1033 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1034 chomp(my $tmp = <STDIN>);
1035 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1036 # Attempt to Create the Dir..
1039 File::Path::mkpath($var, 0, 0777);
1042 unless (defined($chk) && -d $var) {
1043 print "Unable to create directory. ($var)\n\n";
1048 # They said they don't want to create, and we can't install there.
1053 if (!is_dir($var)) {
1054 # Target exists, but is not a directory.
1055 print "File $var exists, but is not a directory.\n\n";
1059 # Either Dir Exists, or was created fine.
1060 $config{$hash_key} = $var;
1070 # Beware: Linux sets it's own cflags below for some retarded reason
1071 $config{LDLIBS} = "-pthread -lstdc++";
1072 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1073 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1074 $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared" unless defined $opt_disablerpath;
1075 $config{MAKEPROG} = "make";
1077 if ($config{OSNAME} =~ /darwin/i) {
1078 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1079 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1080 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1083 if ($config{OSNAME} =~ /OpenBSD/i) {
1084 $config{MAKEPROG} = "gmake";
1085 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1086 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1087 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1088 # if theyre not running this, configure lets the build continue but they probably wont manage to
1089 # compile as this standard version is 2.95.3!
1091 $config{CC} = "eg++";
1092 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1093 chomp($config{GCCMINOR} = `eg++ -dumpversion | cut -c 3`);
1098 if ($config{OSNAME} =~ /Linux/i) {
1099 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1100 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1101 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1102 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1103 $config{MAKEPROG} = "make";
1106 if ($config{OSNAME} =~ /FreeBSD/i) {
1107 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1108 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1111 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1113 # solaris/sunos needs these
1114 # socket = bsd sockets api
1116 # rt = POSIX realtime extensions
1117 # resolv = inet_aton only (why isnt this in nsl?!)
1118 $config{MAKEPROG} = "gmake";
1119 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1123 if($config{OSNAME} =~ /MINGW32/i)
1125 # All code is position-independent on windows
1126 $config{FLAGS} =~ s/-fPIC //;
1130 return $config{OSNAME};
1133 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1136 my($writeheader) = @_;
1138 # First File.. inspircd_config.h
1139 chomp(my $incos = `uname -n -s -r`);
1140 chomp(my $version = `sh src/version.sh`);
1141 chomp(my $revision2 = getrevision());
1142 if ($writeheader == 1)
1144 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1145 open(FILEHANDLE, ">include/inspircd_config.h");
1146 print FILEHANDLE <<EOF;
1147 /* Auto generated by configure, do not modify! */
1148 #ifndef __CONFIGURATION_AUTO__
1149 #define __CONFIGURATION_AUTO__
1151 /* this is for windows support. */
1152 #define CoreExport /**/
1153 #define DllExport /**/
1155 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1156 #define MOD_PATH "$config{MODULE_DIR}"
1157 #define VERSION "$version"
1158 #define REVISION "$revision2"
1159 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1160 #define OPTIMISATION $config{OPTIMITEMP}
1161 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1162 #define SYSTEM "$incos"
1165 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1167 if ($config{OSNAME} =~ /SunOS/i) {
1168 print FILEHANDLE "#define IS_SOLARIS\n";
1170 if ($config{OSNAME} =~ /MINGW32/i) {
1171 print FILEHANDLE "#define IS_MINGW\n";
1173 if ($config{GCCVER} >= 3) {
1174 print FILEHANDLE "#define GCC3\n";
1177 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
1179 ($config{GCCVER} > 4)
1181 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
1183 if ($config{HAS_STRLCPY} eq "true") {
1184 print FILEHANDLE "#define HAS_STRLCPY\n";
1186 if ($config{HAS_STDINT} eq "true") {
1187 print FILEHANDLE "#define HAS_STDINT\n";
1189 if ($config{IPV6} =~ /y/i) {
1190 print FILEHANDLE "#define IPV6\n";
1192 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1193 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1196 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1197 print FILEHANDLE "#define USE_KQUEUE\n";
1198 $se = "socketengine_kqueue";
1201 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1202 print FILEHANDLE "#define USE_EPOLL\n";
1203 $se = "socketengine_epoll";
1206 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1207 print FILEHANDLE "#define USE_PORTS\n";
1208 $se = "socketengine_ports";
1211 # user didn't choose either epoll or select for their OS.
1212 # default them to USE_SELECT (ewwy puke puke)
1214 print FILEHANDLE "#define USE_SELECT\n";
1215 $se = "socketengine_select";
1217 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1223 open(FILEHANDLE, ">include/inspircd_se_config.h");
1224 print FILEHANDLE <<EOF;
1225 /* Auto generated by configure, do not modify or commit to svn! */
1226 #ifndef __CONFIGURATION_SOCKETENGINE__
1227 #define __CONFIGURATION_SOCKETENGINE__
1229 #include "socketengines/$se.h"
1237 # Create a Modules List..
1239 foreach my $i (@modlist)
1241 $modules .= "m_".$i.".so ";
1243 chomp($modules); # Remove Redundant whitespace..
1245 opendir(DIRHANDLE, "src/modules");
1246 foreach my $name2 (sort readdir(DIRHANDLE)) {
1247 if ($name2 =~ /^m_(.+?)$/) {
1248 if (defined(opendir(MDIRHANDLE, "src/modules/$name2"))) {
1249 closedir(MDIRHANDLE);
1250 $modules .= "$name2.so ";
1251 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name2.so\n";
1255 closedir(DIRHANDLE);
1258 # Write all .in files.
1261 my $exe = "inspircd";
1263 # Do this once here, and cache it in the .*.inc files,
1264 # rather than attempting to read src/version.sh from
1265 # compiled code -- we might not have the source to hand.
1266 # Fix for bug#177 by Brain.
1268 chomp($version = `sh ./src/version.sh`);
1269 chomp(my $revision = getrevision());
1270 $version = "$version(r$revision)";
1272 # We can actually parse any file starting with . and ending with .inc,
1273 # but right now we only parse .inspircd.inc to form './inspircd'
1275 print "Writing \e[1;32mMakefiles\e[0m\n";
1276 write_dynamic_modules_makefile();
1277 write_dynamic_makefile();
1279 opendir(DIRHANDLE, $this);
1281 foreach my $name (sort readdir(DIRHANDLE)) {
1282 if ($name =~ /^\.(.+)\.inc$/) {
1285 # Bug #353, omit this on non-darwin
1286 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1288 # All .name.inc files need parsing!
1290 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1291 while (<FILEHANDLE>) {
1296 print "Writing \e[1;32m$file\e[0m ...\n";
1297 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1298 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1299 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1300 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1301 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1302 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1303 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1304 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1305 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1306 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1307 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1308 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1309 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1310 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1311 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1312 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
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");
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-2007 The InspIRCd Development Team
1338 # http://www.inspircd.org/wiki/index.php/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 -export-dynamic -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 -export-dynamic -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 if ($config{IS_DARWIN} eq "YES") {
1418 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1420 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1422 print FILEHANDLE "\n$mfrules\n";
1423 closedir(MDIRHANDLE);
1424 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1428 closedir(DIRHANDLE);
1431 sub read_module_directory {
1432 my ($dpath, $reldpath) = @_;
1434 if (opendir(MDIRHANDLE, $dpath) == 0) {
1438 foreach my $fname (sort readdir(MDIRHANDLE)) {
1439 if ($fname =~ /\.cpp$/) {
1440 my $cmflags = getcompilerflags("$dpath/$fname");
1441 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1442 my $deps = getdependencies("$dpath/$fname");
1444 $oname =~ s/\.cpp$/.o/g;
1445 $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";
1446 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1447 $mobjs = $mobjs . " $reldpath/$oname";
1450 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1451 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1458 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1459 # dependencies which are not relevent in C++.
1463 open (CPP, "<$file") or die("Can't open $file for reading!");
1468 foreach my $d (@ignoredeps)
1474 foreach my $dep (@immutabledeps)
1476 $immutable = $immutable . "../include/$dep ";
1478 $immutable =~ s/ $//g;
1480 while (defined(my $line = <CPP>))
1483 if ($line =~ /#include "(.+\.h)"/)
1485 if (!exists($dupe{$1}))
1487 $retlist = $retlist . "../include/$1 ";
1493 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1496 sub write_dynamic_makefile
1500 my %existing_install_list = ();
1501 opendir(DIRHANDLE, "src/commands");
1502 foreach my $name (sort readdir(DIRHANDLE))
1504 if ($name =~ /^cmd_(.+)\.cpp$/)
1506 $cmdlist[$i++] = $1;
1507 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1508 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1511 closedir(DIRHANDLE);
1515 $config{USE_EPOLL} = 0;
1519 $config{USE_KQUEUE} = 0;
1523 $config{USE_PORTS} = 0;
1526 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1528 print "Scanning \e[1;32m$dir\e[0m for core files ";
1529 opendir(DIRHANDLE, $dir);
1530 foreach my $name (sort readdir(DIRHANDLE))
1532 if ($name =~ /\.cpp$/)
1534 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1536 while (defined(my $line = <CPP>))
1539 if ($line =~ /\/\* \$Core: (\w+) \*\//i)
1541 $filelist{$name} = $1;
1543 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1545 $specialdeps{$name} = $1;
1547 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1549 $extraobjects{$name} = $1;
1551 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1553 $extrabuildlines{$name} = $1;
1555 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1557 $extrasources{$name} = $1;
1559 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1561 if (defined $config{$1})
1563 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1566 while (defined($line = <CPP>))
1569 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1570 last if ($line =~ /\/\* \$EndIf \*\//i);
1575 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1577 if (!exists($existing_install_list{$1}))
1579 $existing_install_list{$1} = 1;
1580 my $idir = (split(' ',$1))[1];
1581 my $ifile = (split(' ',$1))[0];
1582 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1583 $ifile =~ s/.*\///g;
1584 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1587 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//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 . " -cp $1\n";
1595 $ifile =~ s/.*\///g;
1596 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1603 closedir(DIRHANDLE);
1607 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1610 my $all_libsonly = "";
1611 my $libraryext = "";
1615 if ($config{IS_DARWIN} eq "YES")
1617 $libraryext = "dylib";
1618 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd.cpp\n \@../make/run-cc.pl \$(CC) -pipe -dynamic -bind_at_load -L. -o inspircd \$(LDLIBS) inspircd.o "
1623 $RPATH = "-Wl,--rpath -Wl,$config{LIBRARY_DIR}" unless defined $opt_disablerpath;
1624 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include $RPATH \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1627 foreach my $cpp (sort keys %filelist)
1629 $all = $all . $filelist{$cpp} . "." . $libraryext . " ";
1630 $all_libsonly = $all_libsonly . $filelist{$cpp} . "." . $libraryext . " ";
1631 $install_list = $install_list . " -install -m \$(INSTMODE) src/" . $filelist{$cpp} . "." . $libraryext . " \$(LIBPATH)\n";
1632 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/" . $filelist{$cpp} . "." . $libraryext . "\n";
1634 $all = $all . "moo inspircd\n";
1636 $othercrap = $othercrap . " $all_libsonly\n\n";
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 print FH "$all\n\n";
1650 my $deps = calcdeps("src/inspircd.cpp");
1651 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1652 print FH "$othercrap\n";
1654 foreach my $cpp (sort keys %filelist)
1656 my $thislib = $filelist{$cpp} . "." . $libraryext;
1660 $objs =~ s/\.cpp$/.o/;
1661 if (exists($extraobjects{$cpp}))
1663 $objs = $objs . " " . $extraobjects{$cpp};
1665 if (exists($extrasources{$cpp}))
1667 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1669 if ($config{IS_DARWIN} eq "YES")
1671 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1675 if (defined $opt_disablerpath)
1677 $libcrap = " -shared";
1681 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1684 $deps = calcdeps("src/$cpp");
1685 if (exists($extrasources{$cpp}))
1687 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1689 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1692 $deps = $deps . $d . " ";
1696 print FH $thislib . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1697 print FH " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1698 if (exists($extrabuildlines{$cpp}))
1700 print FH " " . $extrabuildlines{$cpp} . "\n";
1702 print FH " \@../make/run-cc.pl \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1705 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1707 # close main makefile
1711 # generate a list of .so
1712 foreach my $cmd (@cmdlist) {
1713 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1716 # and now reopen the commands makefile
1717 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1720 CXXFLAGS = -I../../include \${FLAGS}
1727 # now print the command file details.
1728 foreach my $cmd (@cmdlist) {
1730 cmd_$cmd.so: cmd_$cmd.cpp ../../include/base.h ../../include/modules.h ../../include/inspircd.h ../../include/channels.h ../../include/users.h ../../include/globals.h ../../include/inspircd_config.h ../../include/commands/cmd_$cmd.h
1731 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1737 # Routine to list out the extra/ modules that have been enabled.
1738 # Note: when getting any filenames out and comparing, it's important to lc it if the
1739 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1740 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1741 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1742 sub list_extras () {
1745 my $srcdir = File::Spec->catdir("src", "modules");
1746 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1749 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1750 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1753 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1754 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1757 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1759 EXTRA: for my $extra (@extras) {
1760 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1761 next if ($extra eq '.svn');
1762 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1763 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1764 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1765 if (-l $abs_source) {
1766 # Symlink, is it in the right place?
1767 my $targ = readlink($abs_source);
1768 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1769 if ($abs_targ eq $abs_extra) {
1770 $extras{$extra} = "\e[32;1menabled\e[0m";
1772 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1774 } elsif (-e $abs_source) {
1775 my ($devext, $inoext) = stat($abs_extra);
1776 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1778 if ($devsrc == $devext && $inosrc == $inoext) {
1779 $extras{$extra} = "\e[32;1menabled\e[0m";
1781 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1784 open my $extfd, "<", $abs_extra;
1785 open my $srcfd, "<", $abs_source;
1787 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1788 $extras{$extra} = "\e[32;1menabled\e[0m";
1790 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1794 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1797 # Now let's add dependency info
1798 for my $extra (keys(%extras)) {
1799 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1800 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1801 my @deps = split / +/, getdependencies($abs_extra);
1802 for my $dep (@deps) {
1803 if (exists($extras{$dep})) {
1804 my $ref = \$extras{$dep}; # Take reference.
1805 if ($$ref !~ m/needed by/) {
1806 # First dependency found.
1807 if ($$ref =~ m/enabled/) {
1808 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1810 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1811 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1814 if ($$ref =~ m/enabled/) {
1815 $$ref .= ", \e[32;1m$extra\e[0m";
1817 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1823 for my $extra (sort {$a cmp $b} keys(%extras)) {
1824 my $text = $extras{$extra};
1825 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1826 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1828 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1831 return keys(%extras) if wantarray; # Can be used by manage_extras.
1834 sub enable_extras (@) {
1836 for my $extra (@extras) {
1837 my $extrapath = "src/modules/extra/$extra";
1838 if (!-e $extrapath) {
1839 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1842 my $source = "src/modules/$extra";
1844 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1847 # Get dependencies, and add them to be processed.
1848 my @deps = split / +/, getdependencies($extrapath);
1849 for my $dep (@deps) {
1850 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1851 if (!-e "src/modules/$dep") {
1852 if (-e "src/modules/extra/$dep") {
1853 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1856 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";
1860 print "Enabling $extra ... \n";
1861 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1865 sub disable_extras (@)
1867 opendir my $dd, "src/modules/extra/";
1868 my @files = readdir($dd);
1871 EXTRA: for my $extra (@extras) {
1872 my $extrapath = "src/modules/extra/$extra";
1873 my $source = "src/modules/$extra";
1874 if (!-e $extrapath) {
1875 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1878 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1879 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";
1882 # Check if anything needs this.
1883 for my $file (@files) {
1884 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1885 # File depends on this extra...
1886 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1887 # And is both enabled and not about to be disabled.
1888 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1889 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1895 print "Disabling $extra ... \n";
1896 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";