2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2008 The InspIRCd Development Team
6 # http://www.inspircd.org/wiki/index.php/Credits
8 # Licensed under GPL, please see the COPYING file
13 ###################################################
20 use warnings FATAL => qw(all);
24 $Data::Dumper::Sortkeys = 1;
25 $Data::Dumper::Useqq = 1;
34 # Utility functions for our buildsystem
38 use make::opensslcert;
40 ###############################################################################################
44 ###############################################################################################
46 # If you wish to ignore a dependency throughout the entire core, add it here.
49 "inspircd_win32wrapper.h", # windows has its own configure program
52 # If you wish for all files in the entire core to have a given dependency, insert it here.
53 # You should keep this to an absolute minimum to avoid rebuilds that are not neccessary.
55 our @immutabledeps = (
56 "inspircd_config.h", # auto re-generated by configure
60 ###############################################################################################
62 # NON-EDITABLE VARIABLES
64 ###############################################################################################
66 # List of commands that make up 'make install' and 'make deinstall'
68 our $install_list = "";
69 our $uninstall_list = "";
71 # This is a list of all files in the core. Each cpp file is mapped to a shared object file,
72 # whos file extension is omitted (these can vary from system to system). Auto detected by
73 # scanning the src/*.cpp files for files containing /* $Core */ identifiers.
77 # If you wish for a file to have special dependencies in the makefile, add an entry here.
78 # Auto populated by /* $ExtraDeps: */ instruction
80 our %specialdeps = ();
82 # If you wish for a file to have extra make lines (in between the compile and link steps)
83 # then insert them here.
84 # Auto populated by /* $ExtraBuild: */ instruction
86 our %extrabuildlines = ();
88 # If you wish for a file to be linked against extra objects or arctives, insert them here.
89 # Auto populated by /* $ExtraObjects: */ instruction
91 our %extraobjects = ();
93 # If you wish to compile extra cpp sources into an object, define them here.
94 # NOTE: Certain cpp files such as the socket engines have a value auto calculated
95 # for this table so that their derived class is built.
96 # Auto populated by /* $ExtraSources: */ instruction
98 our %extrasources = ();
100 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
101 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
102 $opt_ipv6, $opt_ipv6links, $opt_noipv6links, $opt_maxbuf, $opt_disable_debug,
105 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
110 sub enable_extras (@);
112 sub disable_extras (@);
114 my @opt_enableextras;
115 my @opt_disableextras;
118 'enable-gnutls' => \$opt_use_gnutls,
119 'rebuild' => \$opt_rebuild,
120 'enable-openssl' => \$opt_use_openssl,
121 'disable-interactive' => \$opt_nointeractive,
122 'enable-ports' => \$opt_ports,
123 'enable-epoll' => \$opt_epoll,
124 'enable-kqueue' => \$opt_kqueue,
125 'disable-ports' => \$opt_noports,
126 'disable-epoll' => \$opt_noepoll,
127 'disable-kqueue' => \$opt_nokqueue,
128 'enable-ipv6' => \$opt_ipv6,
129 'enable-remote-ipv6' => \$opt_ipv6links,
130 'disable-remote-ipv6' => \$opt_noipv6links,
131 'with-cc=s' => \$opt_cc,
132 'with-maxbuf=i' => \$opt_maxbuf,
133 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
134 'prefix=s' => \$opt_base_dir,
135 'config-dir=s' => \$opt_config_dir,
136 'module-dir=s' => \$opt_module_dir,
137 'binary-dir=s' => \$opt_binary_dir,
138 'library-dir=s' => \$opt_library_dir,
139 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
140 'help' => sub { showhelp(); },
141 'modupdate' => sub { modupdate(); },
142 'update' => sub { update(); },
143 'svnupdate' => sub { svnupdate(); },
144 'clean' => sub { clean(); },
145 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
146 'enable-extras=s@' => \@opt_enableextras, # ^
147 'disable-extras=s@' => \@opt_disableextras, # ^
150 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
151 @opt_enableextras = split /,/, join(',', @opt_enableextras);
152 @opt_disableextras = split /,/, join(',', @opt_disableextras);
153 enable_extras(@opt_enableextras);
154 disable_extras(@opt_disableextras);
156 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
157 print "Run $0 -modupdate after you've done this to update the makefiles.\n";
161 our $non_interactive = (
162 (defined $opt_library_dir) ||
163 (defined $opt_base_dir) ||
164 (defined $opt_config_dir) ||
165 (defined $opt_module_dir) ||
166 (defined $opt_base_dir) ||
167 (defined $opt_binary_dir) ||
168 (defined $opt_nointeractive) ||
170 (defined $opt_ipv6) ||
171 (defined $opt_ipv6links) ||
172 (defined $opt_noipv6links) ||
173 (defined $opt_kqueue) ||
174 (defined $opt_epoll) ||
175 (defined $opt_ports) ||
176 (defined $opt_use_openssl) ||
177 (defined $opt_nokqueue) ||
178 (defined $opt_noepoll) ||
179 (defined $opt_noports) ||
180 (defined $opt_maxbuf) ||
181 (defined $opt_use_gnutls) ||
182 (defined $opt_freebsd_port)
184 our $interactive = !$non_interactive;
186 chomp(our $topdir = getcwd());
187 our $this = resolve_directory($topdir); # PWD, Regardless.
188 our @modlist = (); # Declare for Module List..
189 our %config = (); # Initiate Configuration Hash..
190 $config{ME} = resolve_directory($topdir); # Present Working Directory
192 $config{BASE_DIR} = $config{ME};
194 if (defined $opt_base_dir)
196 $config{BASE_DIR} = $opt_base_dir;
199 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
200 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
201 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
202 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
204 if (defined $opt_config_dir)
206 $config{CONFIG_DIR} = $opt_config_dir;
208 if (defined $opt_module_dir)
210 $config{MODULE_DIR} = $opt_module_dir;
212 if (defined $opt_binary_dir)
214 $config{BINARY_DIR} = $opt_binary_dir;
216 if (defined $opt_library_dir)
218 $config{LIBRARY_DIR} = $opt_library_dir;
220 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
222 if (defined $opt_freebsd_port)
224 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
225 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
226 $config{USE_FREEBSD_BASE_SSL} = "n";
230 if ($^O eq "freebsd")
232 # default: use base ssl
233 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
234 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
238 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
239 $config{HAS_OPENSSL_PORT} = "";
243 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
244 chomp(our $openssl_ver = $config{HAS_OPENSSL});
245 $config{USE_GNUTLS} = "n";
246 if (defined $opt_use_gnutls)
248 $config{USE_GNUTLS} = "y"; # Use gnutls.
250 $config{USE_OPENSSL} = "n"; # Use openssl.
251 if (defined $opt_use_openssl)
253 $config{USE_OPENSSL} = "y";
256 # no, let's not change these.
257 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
258 if (!defined $opt_disable_debug)
260 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
264 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
267 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
268 $config{HAS_STDINT} = "false"; # stdint.h check
269 $config{USE_KQUEUE} = "y"; # kqueue enabled
270 if (defined $opt_kqueue)
272 $config{USE_KQUEUE} = "y";
274 if (defined $opt_nokqueue)
276 $config{USE_KQUEUE} = "n";
278 $config{USE_EPOLL} = "y"; # epoll enabled
279 if (defined $opt_epoll)
281 $config{USE_EPOLL} = "y";
283 if (defined $opt_noepoll)
285 $config{USE_EPOLL} = "n";
287 $config{USE_PORTS} = "y"; # epoll enabled
288 if (defined $opt_ports)
290 $config{USE_PORTS} = "y";
292 if (defined $opt_noports)
294 $config{USE_PORTS} = "n";
296 $config{IPV6} = "n"; # IPv6 support (experimental)
297 if (defined $opt_ipv6)
301 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
302 if (defined $opt_ipv6links)
304 $config{SUPPORT_IP6LINKS} = "y";
306 if (defined $opt_noipv6links)
308 $config{SUPPORT_IP6LINKS} = "n";
310 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
311 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
312 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
313 $config{OSNAME} = $^O; # Operating System Name
314 $config{IS_DARWIN} = "NO"; # Is OSX?
315 $config{STARTSCRIPT} = "inspircd"; # start script?
316 $config{DESTINATION} = "BASE"; # Is target path.
317 $config{EXTRA_DIR} = ""; # Is empty.
318 if ($config{OSNAME} =~ /darwin/i)
320 $config{IS_DARWIN} = "YES";
321 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
322 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
323 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
325 $config{CC} = "g++"; # C++ compiler
328 $config{CC} = $opt_cc;
330 our $exec = $config{CC} . " -dumpversion | cut -c 1";
331 chomp($config{GCCVER} = `$exec`); # Major GCC Version
332 $exec = $config{CC} . " -dumpversion | cut -c 3";
333 chomp($config{GCCMINOR} = `$exec`);
334 $config{MAKEORDER} = "ircd mods"; # build order
335 $config{MAXBUF} = "512"; # Max buffer size
337 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
338 $config{HAS_OPENSSL} = $1;
340 $config{HAS_OPENSSL} = "";
343 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
344 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
348 # Get and Set some important vars..
353 unlink(".config.cache");
356 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
361 chomp($topdir = getcwd());
362 $this = resolve_directory($topdir); # PWD, Regardless.
364 # Does the cache file exist?
366 # No, No it doesn't.. *BASH*
367 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
370 # We've Loaded the cache file and all our variables..
371 print "Updating files...\n";
373 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
375 print "Disabling debug information (-g).\n";
376 $config{OPTIMISATI} = "";
379 $has_epoll = $config{HAS_EPOLL};
380 $has_ports = $config{HAS_PORTS};
381 $has_kqueue = $config{HAS_KQUEUE};
390 print "Configure update failed: $@\n";
398 chomp($topdir = getcwd());
399 $this = resolve_directory($topdir); # PWD, Regardless.
401 # Does the cache file exist?
403 # No, No it doesn't.. *BASH*
404 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
407 # We've Loaded the cache file and all our variables..
408 print "Updating files...\n";
410 $has_epoll = $config{HAS_EPOLL};
411 $has_ports = $config{HAS_PORTS};
412 $has_kqueue = $config{HAS_KQUEUE};
421 print "Module update failed: $@\n";
431 open(FH,"<.svn/entries") or $fail = 1;
433 print "This is not an SVN copy of InspIRCd.\n";
440 open my $fd, "-|", "svn update";
441 my $configurechanged = 0; # Needs ./configure -update
442 my $coredirchanged = 0; # Needs ./configure -update
443 my $moduledirchanged = 0; # Needs ./configure -modupdate
444 my $rootincchanged = 0;
446 while (defined(my $line = <$fd>))
450 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
451 ($action, $file) = ($1, $2);
454 push @conflicted, $file;
455 if ($file eq "configure")
457 $configurechanged = 1;
459 elsif ($file =~ m#^src/modules#)
461 $moduledirchanged = 1;
463 elsif ($file =~ m#^src/#)
467 elsif ($file =~ m/^\..*\.inc$/)
472 elsif ($action eq "U" || $action eq "G")
474 if ($file eq "configure")
476 $configurechanged = 1;
478 elsif ($file =~ m/^\..*\.inc$/)
483 elsif ($action eq "A" || $action eq "D")
485 if ($file =~ m#^src/modules#)
487 $moduledirchanged = 1;
489 elsif ($file =~ m#^src/#)
495 unless (close $fd) # close() waits for exit and returns false if the command failed
499 print STDERR "Problem updating from SVN, please check above for errors\n";
503 print STDERR "Failed to run SVN: $!\n";
507 if (scalar(@conflicted) > 0)
509 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
510 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate\n", (($coredirchanged || $configurechanged) ? "" : "mod");
511 print "Conflicted files: " . join ", ", @conflicted . "\n";
514 if ($configurechanged || $coredirchanged)
516 system("perl configure -update");
518 elsif ($moduledirchanged || $rootincchanged)
520 system("perl configure -modupdate");
524 print "No need to update Makefiles.\n";
526 if (defined $opt_rebuild) {
527 system("make install");
532 print "Running non-interactive configure...\n" unless $interactive;
533 print "Checking for cache from previous configure... ";
534 print ((!getcache()) ? "not found\n" : "found\n");
535 print "Checking operating system version... ";
536 print getosflags() . "\n";
538 printf "Checking if stdint.h exists... ";
539 $config{HAS_STDINT} = "true";
541 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
542 if ($config{HAS_STDINT} eq "true") {
545 print "yes\n" if $config{HAS_STDINT} eq "true";
546 print "no\n" if $config{HAS_STDINT} eq "false";
548 printf "Checking if strlcpy exists... ";
549 # Perform the strlcpy() test..
550 $config{HAS_STRLCPY} = "false";
552 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
554 while (defined(my $line = <STRLCPY>)) {
556 # try and find the delcaration of:
557 # size_t strlcpy(...)
558 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
559 $config{HAS_STRLCPY} = "true";
564 print "yes\n" if $config{HAS_STRLCPY} eq "true";
565 print "no\n" if $config{HAS_STRLCPY} eq "false";
567 printf "Checking if kqueue exists... ";
570 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
572 while (defined(my $line = <KQUEUE>)) {
574 # try and find the delcaration of:
576 if ($line =~ /int(\0x9|\s)+kqueue/) {
582 print "yes\n" if $has_kqueue == 1;
583 print "no\n" if $has_kqueue == 0;
585 printf "Checking if epoll exists... ";
588 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
594 my $kernel = `uname -r`;
596 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
601 # Suggestion from nenolod, weed out odd systems which have glibc built
602 # against 2.4 kernels (ick)
603 my $kernel_arch = `uname -p`;
607 if ($kernel_arch =~ /x86_64/) {
608 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
611 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
615 while (defined(my $line = <FH>))
618 if ($line =~ /GNU C Library .* version (.*?) /)
621 $libcv =~ /(\d+\.\d+)/;
624 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
627 # Fix for some retarded libc builds, strip off >> and << etc.
628 $kernelv =~ /(\d+\.\d+)/;
636 printf "libc too old: $libcv... ";
641 printf "libc built against older kernel $kernelv... ";
646 print "yes\n" if $has_epoll == 1;
647 print "no\n" if $has_epoll == 0;
649 printf "Checking if Solaris I/O completion ports are available... ";
651 our $system = `uname -s`;
653 $has_ports = 1 if ($system eq "SunOS");
656 my $kernel = `uname -r`;
658 if (($kernel !~ /^5\.1./)) {
662 print "yes\n" if $has_ports == 1;
663 print "no\n" if $has_ports == 0;
665 $config{HAS_EPOLL} = $has_epoll;
666 $config{HAS_KQUEUE} = $has_kqueue;
668 printf "Checking for libgnutls... ";
669 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
671 $config{HAS_GNUTLS} = "y";
674 $config{HAS_GNUTLS} = "n";
677 printf "Checking for openssl... ";
678 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
680 $config{HAS_OPENSSL} = "y";
683 $config{HAS_OPENSSL} = "n";
686 printf "Checking if you are running an ancient, unsupported OS... ";
687 if ($config{OSNAME} =~ /FreeBSD/i)
689 my $version = `uname -r`;
690 if ($version =~ /^4\./)
692 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
695 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
696 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
701 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
707 print "no ($version)\n";
713 print "no ($config{OSNAME})\n";
716 ################################################################################
717 # BEGIN INTERACTIVE PART #
718 ################################################################################
723 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
726 my $rev = getrevision();
727 # Display Introduction Message..
729 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
730 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
732 *** If you are unsure of any of these values, leave it blank for ***
733 *** standard settings that will work, and your server will run ***
734 *** using them. Please consult your IRC network admin if in doubt. ***
736 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
737 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
738 dir, otherwise you won't have a config file!
740 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
741 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
744 print " (Non-SVN build)";
748 $config{CHANGE_COMPILER} = "n";
749 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";
751 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
752 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
753 should NOT be used. You should probably specify a newer compiler.\n\n";
754 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
755 if ($config{CHANGE_COMPILER} =~ /y/i) {
756 print "What command do you want to use to invoke your compiler?\n";
757 print "[\e[1;32m$config{CC}\e[0m] -> ";
758 chomp($config{CC} = <STDIN>);
759 if ($config{CC} eq "") {
762 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
764 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
765 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
766 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
767 if ($config{GCCVER} < 3) {
768 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
772 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
779 # Directory Settings..
780 my $tmpbase = $config{BASE_DIR};
781 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
782 if ($tmpbase ne $config{BASE_DIR}) {
783 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
784 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
785 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
786 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
789 dir_check("are the configuration files", "CONFIG_DIR");
790 dir_check("are the modules to be compiled to", "MODULE_DIR");
791 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
792 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
795 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?");
799 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?");
803 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?");
806 my $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
807 if (!$chose_hiperf) {
808 print "No high-performance socket engines are available, or you chose\n";
809 print "not to enable one. Defaulting to select() engine.\n\n";
812 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
815 if ($config{IPV6} eq "y") {
816 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";
817 $config{SUPPORT_IP6LINKS} = "y";
819 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?");
823 $config{USE_FREEBSD_BASE_SSL} = "n";
824 $config{USE_FREEBSD_PORTS_SSL} = "n";
825 if ($config{HAS_OPENSSL_PORT} ne "")
827 $config{USE_FREEBSD_PORTS_SSL} = "y";
828 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
829 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";
830 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
832 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
834 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
836 # update to port version
837 $openssl_ver = $config{HAS_OPENSSL_PORT};
842 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
845 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
846 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
847 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
848 print "instead, you should enable the OpenSSL module yourself\n";
849 print "by copying it from src/modules/extra to src/modules.\n\n";
850 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
851 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
854 if ($config{HAS_GNUTLS} eq "y") {
855 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
856 if ($config{USE_GNUTLS} eq "y") {
857 print "\nUsing GnuTLS SSL module.\n";
859 } elsif ($config{HAS_OPENSSL} eq "y") {
860 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
861 if ($config{USE_OPENSSL} eq "y") {
862 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
866 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";
872 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
874 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
877 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
879 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
884 if ($config{USE_GNUTLS} eq "y") {
885 unless (-r "src/modules/m_ssl_gnutls.cpp") {
886 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
887 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
892 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
893 print "SSL Certificates Not found, Generating.. \n\n
894 *************************************************************
895 * Generating the Private Key may take some time, go grab a *
896 * Coffee. Even better, to generate some more entropy if it *
897 * is taking a while, open another console and type du / a *
898 * few times and get that HD going :) Then answer the *
899 * Questions which follow. If you are unsure, just hit enter *
900 *************************************************************\n\n";
901 $failed = make_gnutls_cert();
903 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
905 print "\nCertificate generation complete, copying to config directory... ";
906 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
907 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
912 print "SSL Certificates found, skipping.\n\n";
917 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
919 } elsif ($config{USE_OPENSSL} eq "y") {
920 unless (-r "src/modules/m_ssl_openssl.cpp") {
921 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
922 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
928 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
929 print "SSL Certificates Not found, Generating.. \n\n
930 *************************************************************
931 * Generating the certificates may take some time, go grab a *
932 * coffee, or something. *
933 *************************************************************\n\n";
935 print "\nCertificate generation complete, copying to config directory... ";
936 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
937 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
938 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
941 print "SSL Certificates found, skipping.\n\n"
946 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
949 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
950 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
958 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
959 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
960 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
961 print "modules in your config. This configure script has added those modules to the\n";
962 print "build process. For more info please refer to:\n";
963 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
965 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
966 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
967 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";
970 if ($config{GCCVER} < "3") {
972 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
973 GCC 2.x series compilers only had partial (read as broken) C++ support, and
974 your compile will most likely fail horribly! If you have any problems, do NOT
975 report them to the bugtracker or forums without first upgrading your compiler
976 to a newer 3.x or 4.x (or whatever is available currently) version.
980 ################################################################################
982 ################################################################################
984 # Retrieves the .config.cache file, and loads values into the main config hash.
985 open(CACHE, ".config.cache") or return 0;
988 # Ignore Blank lines, and comments..
991 my ($key, $value) = split("=", $_, 2);
992 $value =~ /^\"(.*)\"$/;
993 # Do something with data here!
1001 # Dump the contents of %config
1002 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1003 open(FILEHANDLE, ">.config.cache");
1004 foreach my $key (keys %config) {
1005 print FILEHANDLE "$key=\"$config{$key}\"\n";
1011 my ($desc, $hash_key) = @_;
1013 while (!$complete) {
1014 print "In what directory $desc?\n";
1015 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1016 chomp(my $var = <STDIN>);
1018 $var = $config{$hash_key};
1020 if ($var =~ /^\~\/(.+)$/) {
1021 # Convert it to a full path..
1022 $var = resolve_directory($ENV{HOME} . "/" . $1);
1024 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1026 # Assume relative Path was given.. fill in the rest.
1027 $var = $this . "/$var";
1030 $var = resolve_directory($var);
1032 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1033 chomp(my $tmp = <STDIN>);
1034 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1035 # Attempt to Create the Dir..
1038 File::Path::mkpath($var, 0, 0777);
1041 unless (defined($chk) && -d $var) {
1042 print "Unable to create directory. ($var)\n\n";
1047 # They said they don't want to create, and we can't install there.
1052 if (!is_dir($var)) {
1053 # Target exists, but is not a directory.
1054 print "File $var exists, but is not a directory.\n\n";
1058 # Either Dir Exists, or was created fine.
1059 $config{$hash_key} = $var;
1069 # Beware: Linux sets it's own cflags below for some retarded reason
1070 $config{LDLIBS} = "-pthread -lstdc++";
1071 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1072 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1073 $SHARED = "-shared";
1074 $config{MAKEPROG} = "make";
1076 if ($config{OSNAME} =~ /darwin/i) {
1077 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1078 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1079 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1082 if ($config{OSNAME} =~ /OpenBSD/i) {
1083 $config{MAKEPROG} = "gmake";
1084 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1085 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1086 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1087 # if theyre not running this, configure lets the build continue but they probably wont manage to
1088 # compile as this standard version is 2.95.3!
1090 $config{CC} = "eg++";
1091 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1092 chomp($config{GCCMINOR} = `eg++ -dumpversion | cut -c 3`);
1097 if ($config{OSNAME} =~ /Linux/i) {
1098 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1099 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1100 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1101 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1102 $config{MAKEPROG} = "make";
1105 if ($config{OSNAME} =~ /FreeBSD/i) {
1106 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1107 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1110 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1112 # solaris/sunos needs these
1113 # socket = bsd sockets api
1115 # rt = POSIX realtime extensions
1116 # resolv = inet_aton only (why isnt this in nsl?!)
1117 $config{MAKEPROG} = "gmake";
1118 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1122 if($config{OSNAME} =~ /MINGW32/i)
1124 # All code is position-independent on windows
1125 $config{FLAGS} =~ s/-fPIC //;
1129 return $config{OSNAME};
1132 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1135 my($writeheader) = @_;
1137 # First File.. inspircd_config.h
1138 chomp(my $incos = `uname -n -s -r`);
1139 chomp(my $version = `sh src/version.sh`);
1140 chomp(my $revision2 = getrevision());
1141 if ($writeheader == 1)
1143 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1144 open(FILEHANDLE, ">include/inspircd_config.h");
1145 print FILEHANDLE <<EOF;
1146 /* Auto generated by configure, do not modify! */
1147 #ifndef __CONFIGURATION_AUTO__
1148 #define __CONFIGURATION_AUTO__
1150 /* this is for windows support. */
1151 #define CoreExport /**/
1152 #define DllExport /**/
1154 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1155 #define MOD_PATH "$config{MODULE_DIR}"
1156 #define VERSION "$version"
1157 #define REVISION "$revision2"
1158 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1159 #define OPTIMISATION $config{OPTIMITEMP}
1160 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1161 #define SYSTEM "$incos"
1164 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1166 if ($config{OSNAME} =~ /SunOS/i) {
1167 print FILEHANDLE "#define IS_SOLARIS\n";
1169 if ($config{OSNAME} =~ /MINGW32/i) {
1170 print FILEHANDLE "#define IS_MINGW\n";
1172 if ($config{GCCVER} >= 3) {
1173 print FILEHANDLE "#define GCC3\n";
1176 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
1178 ($config{GCCVER} > 4)
1180 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
1182 if ($config{HAS_STRLCPY} eq "true") {
1183 print FILEHANDLE "#define HAS_STRLCPY\n";
1185 if ($config{HAS_STDINT} eq "true") {
1186 print FILEHANDLE "#define HAS_STDINT\n";
1188 if ($config{IPV6} =~ /y/i) {
1189 print FILEHANDLE "#define IPV6\n";
1191 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1192 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1195 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1196 print FILEHANDLE "#define USE_KQUEUE\n";
1197 $se = "socketengine_kqueue";
1200 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1201 print FILEHANDLE "#define USE_EPOLL\n";
1202 $se = "socketengine_epoll";
1205 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1206 print FILEHANDLE "#define USE_PORTS\n";
1207 $se = "socketengine_ports";
1210 # user didn't choose either epoll or select for their OS.
1211 # default them to USE_SELECT (ewwy puke puke)
1213 print FILEHANDLE "#define USE_SELECT\n";
1214 $se = "socketengine_select";
1216 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1222 open(FILEHANDLE, ">include/inspircd_se_config.h");
1223 print FILEHANDLE <<EOF;
1224 /* Auto generated by configure, do not modify or commit to svn! */
1225 #ifndef __CONFIGURATION_SOCKETENGINE__
1226 #define __CONFIGURATION_SOCKETENGINE__
1228 #include "socketengines/$se.h"
1236 # Create a Modules List..
1238 foreach my $i (@modlist)
1240 $modules .= "m_".$i.".so ";
1242 chomp($modules); # Remove Redundant whitespace..
1244 opendir(DIRHANDLE, "src/modules");
1245 foreach my $name2 (sort readdir(DIRHANDLE)) {
1246 if ($name2 =~ /^m_(.+?)$/) {
1247 if (defined(opendir(MDIRHANDLE, "src/modules/$name2"))) {
1248 closedir(MDIRHANDLE);
1249 $modules .= "$name2.so ";
1250 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name2.so\n";
1254 closedir(DIRHANDLE);
1257 # Write all .in files.
1260 my $exe = "inspircd";
1262 # Do this once here, and cache it in the .*.inc files,
1263 # rather than attempting to read src/version.sh from
1264 # compiled code -- we might not have the source to hand.
1265 # Fix for bug#177 by Brain.
1267 chomp($version = `sh ./src/version.sh`);
1268 chomp(my $revision = getrevision());
1269 $version = "$version(r$revision)";
1271 # We can actually parse any file starting with . and ending with .inc,
1272 # but right now we only parse .inspircd.inc to form './inspircd'
1274 print "Writing \e[1;32mMakefiles\e[0m\n";
1275 write_dynamic_modules_makefile();
1276 write_dynamic_makefile();
1278 opendir(DIRHANDLE, $this);
1280 foreach my $name (sort readdir(DIRHANDLE)) {
1281 if ($name =~ /^\.(.+)\.inc$/) {
1284 # Bug #353, omit this on non-darwin
1285 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1287 # All .name.inc files need parsing!
1289 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1290 while (<FILEHANDLE>) {
1295 print "Writing \e[1;32m$file\e[0m ...\n";
1296 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1297 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1298 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1299 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1300 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1301 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1302 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1303 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1304 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1305 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1306 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1307 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1308 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1309 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1310 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1311 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1312 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1313 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1314 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1316 open(FILEHANDLE, ">$file");
1317 print FILEHANDLE $tmp;
1320 closedir(DIRHANDLE);
1322 # Make inspircd executable!
1323 chmod 0744, 'inspircd';
1326 sub write_dynamic_modules_makefile {
1327 # Modules Makefile..
1328 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1329 open(FILEHANDLE, ">src/modules/Makefile");
1332 # Module Makefile Header
1334 print FILEHANDLE <<EOF;
1335 ###################################################
1336 # Copyright 2002-2007 The InspIRCd Development Team
1337 # http://www.inspircd.org/wiki/index.php/Credits
1339 # Thanks to Andrew Church <achurch\@achurch.org>
1340 # for assisting with making this work right.
1342 # Automatically Generated by ./configure to add a
1343 # modules please run ./configure -modupdate
1344 ###################################################
1350 if ($config{OSNAME} =~ /darwin/) {
1351 print FILEHANDLE <<EOCHEESE;
1353 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1357 print FILEHANDLE <<EOCHEESE;
1359 PICLDFLAGS = -fPIC -DPIC -shared
1365 # End Module Makefile Header
1368 # Create a Modules List..
1372 foreach my $i (@modlist) {
1374 # Write Entry to the MakeFile
1376 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1377 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1378 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1380 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1383 if (nopedantic("src/modules/m_".$i.".cpp"))
1386 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
1387 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1393 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
1394 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1397 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1398 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1400 # End Write Entry to the MakeFile
1404 opendir(DIRHANDLE, "src/modules");
1405 foreach my $name (sort readdir(DIRHANDLE)) {
1406 if ($name =~ /^m_(.+?)$/) {
1411 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1412 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1413 read_module_directory("src/modules/$name", $name);
1414 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1415 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";
1416 if ($config{IS_DARWIN} eq "YES") {
1417 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1419 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1421 print FILEHANDLE "\n$mfrules\n";
1422 closedir(MDIRHANDLE);
1423 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1427 closedir(DIRHANDLE);
1430 sub read_module_directory {
1431 my ($dpath, $reldpath) = @_;
1433 if (opendir(MDIRHANDLE, $dpath) == 0) {
1437 foreach my $fname (sort readdir(MDIRHANDLE)) {
1438 if ($fname =~ /\.cpp$/) {
1439 my $cmflags = getcompilerflags("$dpath/$fname");
1440 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1441 my $deps = getdependencies("$dpath/$fname");
1443 $oname =~ s/\.cpp$/.o/g;
1444 $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";
1445 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1446 $mobjs = $mobjs . " $reldpath/$oname";
1449 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1450 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1457 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1458 # dependencies which are not relevent in C++.
1462 open (CPP, "<$file") or die("Can't open $file for reading!");
1467 foreach my $d (@ignoredeps)
1473 foreach my $dep (@immutabledeps)
1475 $immutable = $immutable . "../include/$dep ";
1477 $immutable =~ s/ $//g;
1479 while (defined(my $line = <CPP>))
1482 if ($line =~ /#include "(.+\.h)"/)
1484 if (!exists($dupe{$1}))
1486 $retlist = $retlist . "../include/$1 ";
1492 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1495 sub write_dynamic_makefile
1499 my %existing_install_list = ();
1500 my %core_files_list = ();
1502 opendir(DIRHANDLE, "src/commands");
1503 foreach my $name (sort readdir(DIRHANDLE))
1505 if ($name =~ /^cmd_(.+)\.cpp$/)
1507 $cmdlist[$i++] = $1;
1508 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1509 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1512 closedir(DIRHANDLE);
1516 $config{USE_EPOLL} = 0;
1520 $config{USE_KQUEUE} = 0;
1524 $config{USE_PORTS} = 0;
1527 # formerly generated below this foreach, now it's not! magic.
1530 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1532 print "Scanning \e[1;32m$dir\e[0m for core files ";
1533 opendir(DIRHANDLE, $dir);
1534 foreach my $name (sort readdir(DIRHANDLE))
1536 if ($name =~ /\.cpp$/)
1538 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1540 while (defined(my $line = <CPP>))
1543 if ($line =~ /\/\* \$Core \*\//i)
1546 $sname =~ s/\.cpp$/.o/;
1548 # append it to list to be built
1549 $all_core = $all_core . $sname . " ";
1550 $filelist{$name} = $sname;
1552 # mark it as a core file, so it won't get shared object cflags
1553 if (!exists($core_files_list{$name}))
1555 $core_files_list{$name} = 1;
1558 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1560 $specialdeps{$name} = $1;
1562 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1564 $extraobjects{$name} = $1;
1566 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1568 $extrabuildlines{$name} = $1;
1570 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1572 $extrasources{$name} = $1;
1574 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1576 if (defined $config{$1})
1578 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1581 while (defined($line = <CPP>))
1584 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1585 last if ($line =~ /\/\* \$EndIf \*\//i);
1590 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1592 if (!exists($existing_install_list{$1}))
1594 $existing_install_list{$1} = 1;
1595 my $idir = (split(' ',$1))[1];
1596 my $ifile = (split(' ',$1))[0];
1597 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1598 $ifile =~ s/.*\///g;
1599 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1602 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1604 if (!exists($existing_install_list{$1}))
1606 $existing_install_list{$1} = 1;
1607 my $idir = (split(' ',$1))[1];
1608 my $ifile = (split(' ',$1))[0];
1609 $install_list = $install_list . " -cp $1\n";
1610 $ifile =~ s/.*\///g;
1611 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1618 closedir(DIRHANDLE);
1622 # modes need to be compiled in too
1623 $all_core = $all_core . "modes/modeclasses.a";
1625 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1627 my $libraryext = "";
1628 my $binary_rule = "";
1630 if ($config{IS_DARWIN} eq "YES")
1632 $libraryext = "dylib";
1633 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd.cpp\n \@../make/run-cc.pl \$(CC) -pipe -dynamic -bind_at_load -L. -o inspircd \$(LDLIBS) inspircd.o "
1638 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1641 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1644 CC = im a cheezeball
1645 CXXFLAGS = -I../include \${FLAGS}
1646 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1647 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1651 my $buildstring = "";
1654 foreach my $cpp (sort keys %filelist)
1658 $objs =~ s/\.cpp$/.o/;
1659 if (exists($extraobjects{$cpp}))
1661 $objs = $objs . " " . $extraobjects{$cpp};
1662 $all_core = $all_core . " " . $extraobjects{$cpp};
1664 if (exists($extrasources{$cpp}))
1666 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1669 $deps = calcdeps("src/$cpp");
1670 if (exists($extrasources{$cpp}))
1672 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1674 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1677 $deps = $deps . $d . " ";
1681 $buildstring = $buildstring . $objs . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1683 if (exists($core_files_list{$cpp}))
1685 # core files are statically linked into the binary and do not require -export-dynamic
1686 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -c $rawcpp\n";
1690 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1693 if (exists($extrabuildlines{$cpp}))
1695 $buildstring = $buildstring . " " . $extrabuildlines{$cpp} . "\n";
1699 print FH "all: inspircd moo\n\n\n";
1701 $deps = calcdeps("src/inspircd.cpp");
1702 print FH "inspircd: inspircd.cpp $deps $all_core\n";
1703 print FH "$binary_rule $all_core\n\n";
1705 print FH $buildstring;
1706 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1708 # close main makefile
1712 # generate a list of .so
1713 foreach my $cmd (@cmdlist) {
1714 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1717 # and now reopen the commands makefile
1718 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1721 CXXFLAGS = -I../../include \${FLAGS}
1728 # now print the command file details.
1729 foreach my $cmd (@cmdlist) {
1731 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
1732 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1738 # Routine to list out the extra/ modules that have been enabled.
1739 # Note: when getting any filenames out and comparing, it's important to lc it if the
1740 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1741 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1742 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1743 sub list_extras () {
1746 my $srcdir = File::Spec->catdir("src", "modules");
1747 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1750 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1751 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1754 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1755 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1758 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1760 EXTRA: for my $extra (@extras) {
1761 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1762 next if ($extra eq '.svn');
1763 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1764 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1765 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1766 if (-l $abs_source) {
1767 # Symlink, is it in the right place?
1768 my $targ = readlink($abs_source);
1769 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1770 if ($abs_targ eq $abs_extra) {
1771 $extras{$extra} = "\e[32;1menabled\e[0m";
1773 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1775 } elsif (-e $abs_source) {
1776 my ($devext, $inoext) = stat($abs_extra);
1777 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1779 if ($devsrc == $devext && $inosrc == $inoext) {
1780 $extras{$extra} = "\e[32;1menabled\e[0m";
1782 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1785 open my $extfd, "<", $abs_extra;
1786 open my $srcfd, "<", $abs_source;
1788 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1789 $extras{$extra} = "\e[32;1menabled\e[0m";
1791 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1795 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1798 # Now let's add dependency info
1799 for my $extra (keys(%extras)) {
1800 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1801 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1802 my @deps = split / +/, getdependencies($abs_extra);
1803 for my $dep (@deps) {
1804 if (exists($extras{$dep})) {
1805 my $ref = \$extras{$dep}; # Take reference.
1806 if ($$ref !~ m/needed by/) {
1807 # First dependency found.
1808 if ($$ref =~ m/enabled/) {
1809 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1811 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1812 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1815 if ($$ref =~ m/enabled/) {
1816 $$ref .= ", \e[32;1m$extra\e[0m";
1818 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1824 for my $extra (sort {$a cmp $b} keys(%extras)) {
1825 my $text = $extras{$extra};
1826 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1827 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1829 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1832 return keys(%extras) if wantarray; # Can be used by manage_extras.
1835 sub enable_extras (@) {
1837 for my $extra (@extras) {
1838 my $extrapath = "src/modules/extra/$extra";
1839 if (!-e $extrapath) {
1840 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1843 my $source = "src/modules/$extra";
1845 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1848 # Get dependencies, and add them to be processed.
1849 my @deps = split / +/, getdependencies($extrapath);
1850 for my $dep (@deps) {
1851 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1852 if (!-e "src/modules/$dep") {
1853 if (-e "src/modules/extra/$dep") {
1854 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1857 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";
1861 print "Enabling $extra ... \n";
1862 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1866 sub disable_extras (@)
1868 opendir my $dd, "src/modules/extra/";
1869 my @files = readdir($dd);
1872 EXTRA: for my $extra (@extras) {
1873 my $extrapath = "src/modules/extra/$extra";
1874 my $source = "src/modules/$extra";
1875 if (!-e $extrapath) {
1876 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1879 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1880 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";
1883 # Check if anything needs this.
1884 for my $file (@files) {
1885 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1886 # File depends on this extra...
1887 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1888 # And is both enabled and not about to be disabled.
1889 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1890 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1896 print "Disabling $extra ... \n";
1897 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";