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 $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 $config{MAKEORDER} = "ircd mods"; # build order
333 $config{MAXBUF} = "512"; # Max buffer size
335 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
336 $config{HAS_OPENSSL} = $1;
338 $config{HAS_OPENSSL} = "";
341 if ($config{GCCVER} eq "") {
342 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
346 # Get and Set some important vars..
351 unlink(".config.cache");
354 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
359 chomp($topdir = getcwd());
360 $this = resolve_directory($topdir); # PWD, Regardless.
362 # Does the cache file exist?
364 # No, No it doesn't.. *BASH*
365 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
368 # We've Loaded the cache file and all our variables..
369 print "Updating files...\n";
371 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
373 print "Disabling debug information (-g).\n";
374 $config{OPTIMISATI} = "";
377 $has_epoll = $config{HAS_EPOLL};
378 $has_ports = $config{HAS_PORTS};
379 $has_kqueue = $config{HAS_KQUEUE};
388 print "Configure update failed: $@\n";
396 chomp($topdir = getcwd());
397 $this = resolve_directory($topdir); # PWD, Regardless.
399 # Does the cache file exist?
401 # No, No it doesn't.. *BASH*
402 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
405 # We've Loaded the cache file and all our variables..
406 print "Updating files...\n";
408 $has_epoll = $config{HAS_EPOLL};
409 $has_ports = $config{HAS_PORTS};
410 $has_kqueue = $config{HAS_KQUEUE};
419 print "Module update failed: $@\n";
429 open(FH,"<.svn/entries") or $fail = 1;
431 print "This is not an SVN copy of InspIRCd.\n";
438 open my $fd, "-|", "svn update";
439 my $configurechanged = 0; # Needs ./configure -update
440 my $coredirchanged = 0; # Needs ./configure -update
441 my $moduledirchanged = 0; # Needs ./configure -modupdate
442 my $rootincchanged = 0;
444 while (defined(my $line = <$fd>))
448 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
449 ($action, $file) = ($1, $2);
452 push @conflicted, $file;
453 if ($file eq "configure")
455 $configurechanged = 1;
457 elsif ($file =~ m#^src/modules#)
459 $moduledirchanged = 1;
461 elsif ($file =~ m#^src/#)
465 elsif ($file =~ m/^\..*\.inc$/)
470 elsif ($action eq "U" || $action eq "G")
472 if ($file eq "configure")
474 $configurechanged = 1;
476 elsif ($file =~ m/^\..*\.inc$/)
481 elsif ($action eq "A" || $action eq "D")
483 if ($file =~ m#^src/modules#)
485 $moduledirchanged = 1;
487 elsif ($file =~ m#^src/#)
493 unless (close $fd) # close() waits for exit and returns false if the command failed
497 print STDERR "Problem updating from SVN, please check above for errors\n";
501 print STDERR "Failed to run SVN: $!\n";
505 if (scalar(@conflicted) > 0)
507 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
508 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate\n", (($coredirchanged || $configurechanged) ? "" : "mod");
509 print "Conflicted files: " . join ", ", @conflicted . "\n";
512 if ($configurechanged || $coredirchanged)
514 system("perl configure -update");
516 elsif ($moduledirchanged || $rootincchanged)
518 system("perl configure -modupdate");
522 print "No need to update Makefiles.\n";
524 if (defined $opt_rebuild) {
525 system("make install");
530 print "Running non-interactive configure...\n" unless $interactive;
531 print "Checking for cache from previous configure... ";
532 print ((!getcache()) ? "not found\n" : "found\n");
533 print "Checking operating system version... ";
534 print getosflags() . "\n";
536 printf "Checking if stdint.h exists... ";
537 $config{HAS_STDINT} = "true";
539 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
540 if ($config{HAS_STDINT} eq "true") {
543 print "yes\n" if $config{HAS_STDINT} eq "true";
544 print "no\n" if $config{HAS_STDINT} eq "false";
546 printf "Checking if strlcpy exists... ";
547 # Perform the strlcpy() test..
548 $config{HAS_STRLCPY} = "false";
550 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
552 while (defined(my $line = <STRLCPY>)) {
554 # try and find the delcaration of:
555 # size_t strlcpy(...)
556 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
557 $config{HAS_STRLCPY} = "true";
562 print "yes\n" if $config{HAS_STRLCPY} eq "true";
563 print "no\n" if $config{HAS_STRLCPY} eq "false";
565 printf "Checking if kqueue exists... ";
568 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
570 while (defined(my $line = <KQUEUE>)) {
572 # try and find the delcaration of:
574 if ($line =~ /int(\0x9|\s)+kqueue/) {
580 print "yes\n" if $has_kqueue == 1;
581 print "no\n" if $has_kqueue == 0;
583 printf "Checking if epoll exists... ";
586 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
592 my $kernel = `uname -r`;
594 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
599 # Suggestion from nenolod, weed out odd systems which have glibc built
600 # against 2.4 kernels (ick)
601 my $kernel_arch = `uname -p`;
605 if ($kernel_arch =~ /x86_64/) {
606 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
609 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
613 while (defined(my $line = <FH>))
616 if ($line =~ /GNU C Library .* version (.*?) /)
619 $libcv =~ /(\d+\.\d+)/;
622 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
625 # Fix for some retarded libc builds, strip off >> and << etc.
626 $kernelv =~ /(\d+\.\d+)/;
634 printf "libc too old: $libcv... ";
639 printf "libc built against older kernel $kernelv... ";
644 print "yes\n" if $has_epoll == 1;
645 print "no\n" if $has_epoll == 0;
647 printf "Checking if Solaris I/O completion ports are available... ";
649 our $system = `uname -s`;
651 $has_ports = 1 if ($system eq "SunOS");
654 my $kernel = `uname -r`;
656 if (($kernel !~ /^5\.1./)) {
660 print "yes\n" if $has_ports == 1;
661 print "no\n" if $has_ports == 0;
663 $config{HAS_EPOLL} = $has_epoll;
664 $config{HAS_KQUEUE} = $has_kqueue;
666 printf "Checking for libgnutls... ";
667 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
669 $config{HAS_GNUTLS} = "y";
672 $config{HAS_GNUTLS} = "n";
675 printf "Checking for openssl... ";
676 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
678 $config{HAS_OPENSSL} = "y";
681 $config{HAS_OPENSSL} = "n";
684 printf "Checking if you are running an ancient, unsupported OS... ";
685 if ($config{OSNAME} =~ /FreeBSD/i)
687 my $version = `uname -r`;
688 if ($version =~ /^4\./)
690 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
693 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
694 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
699 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
705 print "no ($version)\n";
711 print "no ($config{OSNAME})\n";
714 ################################################################################
715 # BEGIN INTERACTIVE PART #
716 ################################################################################
721 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
724 my $rev = getrevision();
725 # Display Introduction Message..
727 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
728 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
730 *** If you are unsure of any of these values, leave it blank for ***
731 *** standard settings that will work, and your server will run ***
732 *** using them. Please consult your IRC network admin if in doubt. ***
734 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
735 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
736 dir, otherwise you won't have a config file!
738 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
739 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
742 print " (Non-SVN build)";
746 $config{CHANGE_COMPILER} = "n";
747 print "I have detected the following compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
749 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
750 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
751 should NOT be used. You should probably specify a newer compiler.\n\n";
752 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
753 if ($config{CHANGE_COMPILER} =~ /y/i) {
754 print "What command do you want to use to invoke your compiler?\n";
755 print "[\e[1;32m$config{CC}\e[0m] -> ";
756 chomp($config{CC} = <STDIN>);
757 if ($config{CC} eq "") {
760 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
762 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
763 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
764 if ($config{GCCVER} < 3) {
765 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
769 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
776 # Directory Settings..
777 my $tmpbase = $config{BASE_DIR};
778 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
779 if ($tmpbase ne $config{BASE_DIR}) {
780 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
781 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
782 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
783 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
786 dir_check("are the configuration files", "CONFIG_DIR");
787 dir_check("are the modules to be compiled to", "MODULE_DIR");
788 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
789 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
792 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?");
796 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?");
800 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?");
803 my $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
804 if (!$chose_hiperf) {
805 print "No high-performance socket engines are available, or you chose\n";
806 print "not to enable one. Defaulting to select() engine.\n\n";
809 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
812 if ($config{IPV6} eq "y") {
813 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";
814 $config{SUPPORT_IP6LINKS} = "y";
816 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?");
820 $config{USE_FREEBSD_BASE_SSL} = "n";
821 $config{USE_FREEBSD_PORTS_SSL} = "n";
822 if ($config{HAS_OPENSSL_PORT} ne "")
824 $config{USE_FREEBSD_PORTS_SSL} = "y";
825 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
826 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";
827 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
829 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
831 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
833 # update to port version
834 $openssl_ver = $config{HAS_OPENSSL_PORT};
839 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
842 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
843 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
844 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
845 print "instead, you should enable the OpenSSL module yourself\n";
846 print "by copying it from src/modules/extra to src/modules.\n\n";
847 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
848 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
851 if ($config{HAS_GNUTLS} eq "y") {
852 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
853 if ($config{USE_GNUTLS} eq "y") {
854 print "\nUsing GnuTLS SSL module.\n";
856 } elsif ($config{HAS_OPENSSL} eq "y") {
857 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
858 if ($config{USE_OPENSSL} eq "y") {
859 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
863 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";
869 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
871 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
874 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
876 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
881 if ($config{USE_GNUTLS} eq "y") {
882 unless (-r "src/modules/m_ssl_gnutls.cpp") {
883 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
884 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
889 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
890 print "SSL Certificates Not found, Generating.. \n\n
891 *************************************************************
892 * Generating the Private Key may take some time, go grab a *
893 * Coffee. Even better, to generate some more entropy if it *
894 * is taking a while, open another console and type du / a *
895 * few times and get that HD going :) Then answer the *
896 * Questions which follow. If you are unsure, just hit enter *
897 *************************************************************\n\n";
898 $failed = make_gnutls_cert();
900 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
902 print "\nCertificate generation complete, copying to config directory... ";
903 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
904 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
909 print "SSL Certificates found, skipping.\n\n";
914 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
916 } elsif ($config{USE_OPENSSL} eq "y") {
917 unless (-r "src/modules/m_ssl_openssl.cpp") {
918 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
919 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
925 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
926 print "SSL Certificates Not found, Generating.. \n\n
927 *************************************************************
928 * Generating the certificates may take some time, go grab a *
929 * coffee, or something. *
930 *************************************************************\n\n";
932 print "\nCertificate generation complete, copying to config directory... ";
933 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
934 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
935 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
938 print "SSL Certificates found, skipping.\n\n"
943 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
946 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
947 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
955 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
956 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
957 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
958 print "modules in your config. This configure script has added those modules to the\n";
959 print "build process. For more info please refer to:\n";
960 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
962 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
963 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
964 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";
967 if ($config{GCCVER} < "3") {
969 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
970 GCC 2.x series compilers only had partial (read as broken) C++ support, and
971 your compile will most likely fail horribly! If you have any problems, do NOT
972 report them to the bugtracker or forums without first upgrading your compiler
973 to a newer 3.x or 4.x (or whatever is available currently) version.
977 ################################################################################
979 ################################################################################
981 # Retrieves the .config.cache file, and loads values into the main config hash.
982 open(CACHE, ".config.cache") or return 0;
985 # Ignore Blank lines, and comments..
988 my ($key, $value) = split("=", $_, 2);
989 $value =~ /^\"(.*)\"$/;
990 # Do something with data here!
998 # Dump the contents of %config
999 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1000 open(FILEHANDLE, ">.config.cache");
1001 foreach my $key (keys %config) {
1002 print FILEHANDLE "$key=\"$config{$key}\"\n";
1008 my ($desc, $hash_key) = @_;
1010 while (!$complete) {
1011 print "In what directory $desc?\n";
1012 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1013 chomp(my $var = <STDIN>);
1015 $var = $config{$hash_key};
1017 if ($var =~ /^\~\/(.+)$/) {
1018 # Convert it to a full path..
1019 $var = resolve_directory($ENV{HOME} . "/" . $1);
1021 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1023 # Assume relative Path was given.. fill in the rest.
1024 $var = $this . "/$var";
1027 $var = resolve_directory($var);
1029 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1030 chomp(my $tmp = <STDIN>);
1031 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1032 # Attempt to Create the Dir..
1035 File::Path::mkpath($var, 0, 0777);
1038 unless (defined($chk) && -d $var) {
1039 print "Unable to create directory. ($var)\n\n";
1044 # They said they don't want to create, and we can't install there.
1049 if (!is_dir($var)) {
1050 # Target exists, but is not a directory.
1051 print "File $var exists, but is not a directory.\n\n";
1055 # Either Dir Exists, or was created fine.
1056 $config{$hash_key} = $var;
1066 # Beware: Linux sets it's own cflags below for some retarded reason
1067 $config{LDLIBS} = "-pthread -lstdc++";
1068 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1069 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1070 $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared" unless defined $opt_disablerpath;
1071 $config{MAKEPROG} = "make";
1073 if ($config{OSNAME} =~ /darwin/i) {
1074 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1075 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1076 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1079 if ($config{OSNAME} =~ /OpenBSD/i) {
1080 $config{MAKEPROG} = "gmake";
1081 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1082 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1083 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1084 # if theyre not running this, configure lets the build continue but they probably wont manage to
1085 # compile as this standard version is 2.95.3!
1087 $config{CC} = "eg++";
1088 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1093 if ($config{OSNAME} =~ /Linux/i) {
1094 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1095 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1096 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1097 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1098 $config{MAKEPROG} = "make";
1101 if ($config{OSNAME} =~ /FreeBSD/i) {
1102 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1103 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1106 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1108 # solaris/sunos needs these
1109 # socket = bsd sockets api
1111 # rt = POSIX realtime extensions
1112 # resolv = inet_aton only (why isnt this in nsl?!)
1113 $config{MAKEPROG} = "gmake";
1114 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1118 if($config{OSNAME} =~ /MINGW32/i)
1120 # All code is position-independent on windows
1121 $config{FLAGS} =~ s/-fPIC //;
1125 return $config{OSNAME};
1128 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1131 my($writeheader) = @_;
1133 # First File.. inspircd_config.h
1134 chomp(my $incos = `uname -n -s -r`);
1135 chomp(my $version = `sh src/version.sh`);
1136 chomp(my $revision2 = getrevision());
1137 if ($writeheader == 1)
1139 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1140 open(FILEHANDLE, ">include/inspircd_config.h");
1141 print FILEHANDLE <<EOF;
1142 /* Auto generated by configure, do not modify! */
1143 #ifndef __CONFIGURATION_AUTO__
1144 #define __CONFIGURATION_AUTO__
1146 /* this is for windows support. */
1147 #define CoreExport /**/
1148 #define DllExport /**/
1150 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1151 #define MOD_PATH "$config{MODULE_DIR}"
1152 #define VERSION "$version"
1153 #define REVISION "$revision2"
1154 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1155 #define OPTIMISATION $config{OPTIMITEMP}
1156 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1157 #define SYSTEM "$incos"
1160 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1162 if ($config{OSNAME} =~ /SunOS/i) {
1163 print FILEHANDLE "#define IS_SOLARIS\n";
1165 if ($config{OSNAME} =~ /MINGW32/i) {
1166 print FILEHANDLE "#define IS_MINGW\n";
1168 if ($config{GCCVER} >= 3) {
1169 print FILEHANDLE "#define GCC3\n";
1171 if ($config{HAS_STRLCPY} eq "true") {
1172 print FILEHANDLE "#define HAS_STRLCPY\n";
1174 if ($config{HAS_STDINT} eq "true") {
1175 print FILEHANDLE "#define HAS_STDINT\n";
1177 if ($config{IPV6} =~ /y/i) {
1178 print FILEHANDLE "#define IPV6\n";
1180 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1181 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1184 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1185 print FILEHANDLE "#define USE_KQUEUE\n";
1186 $se = "socketengine_kqueue";
1189 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1190 print FILEHANDLE "#define USE_EPOLL\n";
1191 $se = "socketengine_epoll";
1194 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1195 print FILEHANDLE "#define USE_PORTS\n";
1196 $se = "socketengine_ports";
1199 # user didn't choose either epoll or select for their OS.
1200 # default them to USE_SELECT (ewwy puke puke)
1202 print FILEHANDLE "#define USE_SELECT\n";
1203 $se = "socketengine_select";
1205 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1211 open(FILEHANDLE, ">include/inspircd_se_config.h");
1212 print FILEHANDLE <<EOF;
1213 /* Auto generated by configure, do not modify or commit to svn! */
1214 #ifndef __CONFIGURATION_SOCKETENGINE__
1215 #define __CONFIGURATION_SOCKETENGINE__
1217 #include "socketengines/$se.h"
1225 # Create a Modules List..
1227 foreach my $i (@modlist)
1229 $modules .= "m_".$i.".so ";
1231 chomp($modules); # Remove Redundant whitespace..
1233 opendir(DIRHANDLE, "src/modules");
1234 foreach my $name (sort readdir(DIRHANDLE)) {
1235 if ($name =~ /^m_(.+?)$/) {
1236 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1237 closedir(MDIRHANDLE);
1238 $modules .= "$name.so ";
1239 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name.so\n";
1243 closedir(DIRHANDLE);
1246 # Write all .in files.
1249 my $exe = "inspircd";
1251 # Do this once here, and cache it in the .*.inc files,
1252 # rather than attempting to read src/version.sh from
1253 # compiled code -- we might not have the source to hand.
1254 # Fix for bug#177 by Brain.
1256 chomp($version = `sh ./src/version.sh`);
1257 chomp(my $revision = getrevision());
1258 $version = "$version(r$revision)";
1260 # We can actually parse any file starting with . and ending with .inc,
1261 # but right now we only parse .inspircd.inc to form './inspircd'
1263 print "Writing \e[1;32mMakefiles\e[0m\n";
1264 write_dynamic_modules_makefile();
1265 write_dynamic_makefile();
1267 opendir(DIRHANDLE, $this);
1269 foreach my $name (sort readdir(DIRHANDLE)) {
1270 if ($name =~ /^\.(.+)\.inc$/) {
1273 # Bug #353, omit this on non-darwin
1274 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1276 # All .name.inc files need parsing!
1278 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1279 while (<FILEHANDLE>) {
1284 print "Writing \e[1;32m$file\e[0m ...\n";
1285 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1286 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1287 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1288 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1289 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1290 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1291 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1292 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1293 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1294 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1295 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1296 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1297 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1298 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1299 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1300 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1301 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1302 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1303 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1305 open(FILEHANDLE, ">$file");
1306 print FILEHANDLE $tmp;
1309 closedir(DIRHANDLE);
1311 # Make inspircd executable!
1312 chmod 0744, 'inspircd';
1315 sub write_dynamic_modules_makefile {
1316 # Modules Makefile..
1317 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1318 open(FILEHANDLE, ">src/modules/Makefile");
1321 # Module Makefile Header
1323 print FILEHANDLE <<EOF;
1324 ###################################################
1325 # Copyright 2002-2007 The InspIRCd Development Team
1326 # http://www.inspircd.org/wiki/index.php/Credits
1328 # Thanks to Andrew Church <achurch\@achurch.org>
1329 # for assisting with making this work right.
1331 # Automatically Generated by ./configure to add a
1332 # modules please run ./configure -modupdate
1333 ###################################################
1339 if ($config{OSNAME} =~ /darwin/) {
1340 print FILEHANDLE <<EOCHEESE;
1342 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1346 print FILEHANDLE <<EOCHEESE;
1348 PICLDFLAGS = -fPIC -DPIC -shared
1354 # End Module Makefile Header
1357 # Create a Modules List..
1361 foreach my $i (@modlist) {
1363 # Write Entry to the MakeFile
1365 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1366 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1367 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1369 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1372 if (nopedantic("src/modules/m_".$i.".cpp"))
1375 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
1376 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1382 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
1383 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1386 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1387 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1389 # End Write Entry to the MakeFile
1393 opendir(DIRHANDLE, "src/modules");
1394 foreach my $name (sort readdir(DIRHANDLE)) {
1395 if ($name =~ /^m_(.+?)$/) {
1400 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1401 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1402 read_module_directory("src/modules/$name", $name);
1403 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1404 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";
1405 if ($config{IS_DARWIN} eq "YES") {
1406 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1408 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1410 print FILEHANDLE "\n$mfrules\n";
1411 closedir(MDIRHANDLE);
1412 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1416 closedir(DIRHANDLE);
1419 sub read_module_directory {
1420 my ($dpath, $reldpath) = @_;
1422 if (opendir(MDIRHANDLE, $dpath) == 0) {
1426 foreach my $fname (sort readdir(MDIRHANDLE)) {
1427 if ($fname =~ /\.cpp$/) {
1428 my $cmflags = getcompilerflags("$dpath/$fname");
1429 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1430 my $deps = getdependencies("$dpath/$fname");
1432 $oname =~ s/\.cpp$/.o/g;
1433 $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";
1434 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1435 $mobjs = $mobjs . " $reldpath/$oname";
1438 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1439 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1446 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1447 # dependencies which are not relevent in C++.
1451 open (CPP, "<$file") or die("Can't open $file for reading!");
1456 foreach my $d (@ignoredeps)
1462 foreach my $dep (@immutabledeps)
1464 $immutable = $immutable . "../include/$dep ";
1466 $immutable =~ s/ $//g;
1468 while (defined(my $line = <CPP>))
1471 if ($line =~ /#include "(.+\.h)"/)
1473 if (!exists($dupe{$1}))
1475 $retlist = $retlist . "../include/$1 ";
1481 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1484 sub write_dynamic_makefile
1488 my %existing_install_list = ();
1489 opendir(DIRHANDLE, "src/commands");
1490 foreach my $name (sort readdir(DIRHANDLE))
1492 if ($name =~ /^cmd_(.+)\.cpp$/)
1494 $cmdlist[$i++] = $1;
1495 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1496 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1499 closedir(DIRHANDLE);
1503 $config{USE_EPOLL} = 0;
1507 $config{USE_KQUEUE} = 0;
1511 $config{USE_PORTS} = 0;
1514 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1516 print "Scanning \e[1;32m$dir\e[0m for core files ";
1517 opendir(DIRHANDLE, $dir);
1518 foreach my $name (sort readdir(DIRHANDLE))
1520 if ($name =~ /\.cpp$/)
1522 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1524 while (defined(my $line = <CPP>))
1527 if ($line =~ /\/\* \$Core: (\w+) \*\//i)
1529 $filelist{$name} = $1;
1531 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1533 $specialdeps{$name} = $1;
1535 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1537 $extraobjects{$name} = $1;
1539 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1541 $extrabuildlines{$name} = $1;
1543 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1545 $extrasources{$name} = $1;
1547 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1549 if (defined $config{$1})
1551 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1554 while (defined($line = <CPP>))
1557 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1558 last if ($line =~ /\/\* \$EndIf \*\//i);
1563 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1565 if (!exists($existing_install_list{$1}))
1567 $existing_install_list{$1} = 1;
1568 my $idir = (split(' ',$1))[1];
1569 my $ifile = (split(' ',$1))[0];
1570 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1571 $ifile =~ s/.*\///g;
1572 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1575 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//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 . " -cp $1\n";
1583 $ifile =~ s/.*\///g;
1584 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1591 closedir(DIRHANDLE);
1595 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1598 my $all_libsonly = "";
1599 my $libraryext = "";
1603 if ($config{IS_DARWIN} eq "YES")
1605 $libraryext = "dylib";
1606 $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 "
1611 $RPATH = "-Wl,--rpath -Wl,$config{LIBRARY_DIR}" unless defined $opt_disablerpath;
1612 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include $RPATH \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1615 foreach my $cpp (sort keys %filelist)
1617 $all = $all . $filelist{$cpp} . "." . $libraryext . " ";
1618 $all_libsonly = $all_libsonly . $filelist{$cpp} . "." . $libraryext . " ";
1619 $install_list = $install_list . " -install -m \$(INSTMODE) src/" . $filelist{$cpp} . "." . $libraryext . " \$(LIBPATH)\n";
1620 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/" . $filelist{$cpp} . "." . $libraryext . "\n";
1622 $all = $all . "moo inspircd\n";
1624 $othercrap = $othercrap . " $all_libsonly\n\n";
1626 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1629 CC = im a cheezeball
1630 CXXFLAGS = -I../include \${FLAGS}
1631 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1632 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1636 print FH "$all\n\n";
1638 my $deps = calcdeps("src/inspircd.cpp");
1639 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1640 print FH "$othercrap\n";
1642 foreach my $cpp (sort keys %filelist)
1644 my $thislib = $filelist{$cpp} . "." . $libraryext;
1648 $objs =~ s/\.cpp$/.o/;
1649 if (exists($extraobjects{$cpp}))
1651 $objs = $objs . " " . $extraobjects{$cpp};
1653 if (exists($extrasources{$cpp}))
1655 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1657 if ($config{IS_DARWIN} eq "YES")
1659 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1663 if (defined $opt_disablerpath)
1665 $libcrap = " -shared";
1669 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1672 $deps = calcdeps("src/$cpp");
1673 if (exists($extrasources{$cpp}))
1675 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1677 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1680 $deps = $deps . $d . " ";
1684 print FH $thislib . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1685 print FH " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1686 if (exists($extrabuildlines{$cpp}))
1688 print FH " " . $extrabuildlines{$cpp} . "\n";
1690 print FH " \@../make/run-cc.pl \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1693 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1695 # close main makefile
1699 # generate a list of .so
1700 foreach my $cmd (@cmdlist) {
1701 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1704 # and now reopen the commands makefile
1705 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1708 CXXFLAGS = -I../../include \${FLAGS}
1715 # now print the command file details.
1716 foreach my $cmd (@cmdlist) {
1718 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
1719 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1725 # Routine to list out the extra/ modules that have been enabled.
1726 # Note: when getting any filenames out and comparing, it's important to lc it if the
1727 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1728 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1729 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1730 sub list_extras () {
1733 my $srcdir = File::Spec->catdir("src", "modules");
1734 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1737 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1738 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1741 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1742 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1745 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1747 EXTRA: for my $extra (@extras) {
1748 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1749 next if ($extra eq '.svn');
1750 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1751 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1752 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1753 if (-l $abs_source) {
1754 # Symlink, is it in the right place?
1755 my $targ = readlink($abs_source);
1756 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1757 if ($abs_targ eq $abs_extra) {
1758 $extras{$extra} = "\e[32;1menabled\e[0m";
1760 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1762 } elsif (-e $abs_source) {
1763 my ($devext, $inoext) = stat($abs_extra);
1764 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1766 if ($devsrc == $devext && $inosrc == $inoext) {
1767 $extras{$extra} = "\e[32;1menabled\e[0m";
1769 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1772 open my $extfd, "<", $abs_extra;
1773 open my $srcfd, "<", $abs_source;
1775 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1776 $extras{$extra} = "\e[32;1menabled\e[0m";
1778 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1782 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1785 # Now let's add dependency info
1786 for my $extra (keys(%extras)) {
1787 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1788 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1789 my @deps = split / +/, getdependencies($abs_extra);
1790 for my $dep (@deps) {
1791 if (exists($extras{$dep})) {
1792 my $ref = \$extras{$dep}; # Take reference.
1793 if ($$ref !~ m/needed by/) {
1794 # First dependency found.
1795 if ($$ref =~ m/enabled/) {
1796 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1798 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1799 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1802 if ($$ref =~ m/enabled/) {
1803 $$ref .= ", \e[32;1m$extra\e[0m";
1805 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1811 for my $extra (sort {$a cmp $b} keys(%extras)) {
1812 my $text = $extras{$extra};
1813 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1814 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1816 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1819 return keys(%extras) if wantarray; # Can be used by manage_extras.
1822 sub enable_extras (@) {
1824 for my $extra (@extras) {
1825 my $extrapath = "src/modules/extra/$extra";
1826 if (!-e $extrapath) {
1827 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1830 my $source = "src/modules/$extra";
1832 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1835 # Get dependencies, and add them to be processed.
1836 my @deps = split / +/, getdependencies($extrapath);
1837 for my $dep (@deps) {
1838 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1839 if (!-e "src/modules/$dep") {
1840 if (-e "src/modules/extra/$dep") {
1841 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1844 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";
1848 print "Enabling $extra ... \n";
1849 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1853 sub disable_extras (@)
1855 opendir my $dd, "src/modules/extra/";
1856 my @files = readdir($dd);
1859 EXTRA: for my $extra (@extras) {
1860 my $extrapath = "src/modules/extra/$extra";
1861 my $source = "src/modules/$extra";
1862 if (!-e $extrapath) {
1863 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1866 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1867 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";
1870 # Check if anything needs this.
1871 for my $file (@files) {
1872 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1873 # File depends on this extra...
1874 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1875 # And is both enabled and not about to be disabled.
1876 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1877 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1883 print "Disabling $extra ... \n";
1884 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";