2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2009 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;
33 # Utility functions for our buildsystem
37 use make::opensslcert;
39 ###############################################################################################
43 ###############################################################################################
45 # If you wish to ignore a dependency throughout the entire core, add it here.
48 "inspircd_win32wrapper.h", # windows has its own configure program
51 # If you wish for all files in the entire core to have a given dependency, insert it here.
52 # You should keep this to an absolute minimum to avoid rebuilds that are not neccessary.
54 our @immutabledeps = (
55 "inspircd_config.h", # auto re-generated by configure
59 ###############################################################################################
61 # NON-EDITABLE VARIABLES
63 ###############################################################################################
65 # List of commands that make up 'make install' and 'make deinstall'
67 our $install_list = "";
68 our $uninstall_list = "";
70 # This is a list of all files in the core. Each cpp file is mapped to a shared object file,
71 # whos file extension is omitted (these can vary from system to system). Auto detected by
72 # scanning the src/*.cpp files for files containing /* $Core */ identifiers.
76 # If you wish for a file to have special dependencies in the makefile, add an entry here.
77 # Auto populated by /* $ExtraDeps: */ instruction
79 our %specialdeps = ();
81 # If you wish for a file to have extra make lines (in between the compile and link steps)
82 # then insert them here.
83 # Auto populated by /* $ExtraBuild: */ instruction
85 our %extrabuildlines = ();
87 # If you wish for a file to be linked against extra objects or arctives, insert them here.
88 # Auto populated by /* $ExtraObjects: */ instruction
90 our %extraobjects = ();
92 # If you wish to compile extra cpp sources into an object, define them here.
93 # NOTE: Certain cpp files such as the socket engines have a value auto calculated
94 # for this table so that their derived class is built.
95 # Auto populated by /* $ExtraSources: */ instruction
97 our %extrasources = ();
99 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
100 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
101 $opt_ipv6, $opt_ipv6links, $opt_noipv6links, $opt_maxbuf, $opt_disable_debug,
104 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
109 sub enable_extras (@);
111 sub disable_extras (@);
113 my @opt_enableextras;
114 my @opt_disableextras;
117 'enable-gnutls' => \$opt_use_gnutls,
118 'rebuild' => \$opt_rebuild,
119 'enable-openssl' => \$opt_use_openssl,
120 'disable-interactive' => \$opt_nointeractive,
121 'enable-ports' => \$opt_ports,
122 'enable-epoll' => \$opt_epoll,
123 'enable-kqueue' => \$opt_kqueue,
124 'disable-ports' => \$opt_noports,
125 'disable-epoll' => \$opt_noepoll,
126 'disable-kqueue' => \$opt_nokqueue,
127 'enable-ipv6' => \$opt_ipv6,
128 'enable-remote-ipv6' => \$opt_ipv6links,
129 'disable-remote-ipv6' => \$opt_noipv6links,
130 'with-cc=s' => \$opt_cc,
131 'with-maxbuf=i' => \$opt_maxbuf,
132 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
133 'prefix=s' => \$opt_base_dir,
134 'config-dir=s' => \$opt_config_dir,
135 'module-dir=s' => \$opt_module_dir,
136 'binary-dir=s' => \$opt_binary_dir,
137 'library-dir=s' => \$opt_library_dir,
138 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
139 'help' => sub { showhelp(); },
140 'modupdate' => sub { modupdate(); },
141 'update' => sub { update(); },
142 'svnupdate' => sub { svnupdate(); },
143 'clean' => sub { clean(); },
144 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
145 'enable-extras=s@' => \@opt_enableextras, # ^
146 'disable-extras=s@' => \@opt_disableextras, # ^
147 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
148 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
151 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
152 @opt_enableextras = split /,/, join(',', @opt_enableextras);
153 @opt_disableextras = split /,/, join(',', @opt_disableextras);
154 enable_extras(@opt_enableextras);
155 disable_extras(@opt_disableextras);
157 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
158 print "Run $0 -modupdate after you've done this to update the makefiles.\n";
162 our $non_interactive = (
163 (defined $opt_library_dir) ||
164 (defined $opt_base_dir) ||
165 (defined $opt_config_dir) ||
166 (defined $opt_module_dir) ||
167 (defined $opt_base_dir) ||
168 (defined $opt_binary_dir) ||
169 (defined $opt_nointeractive) ||
171 (defined $opt_ipv6) ||
172 (defined $opt_ipv6links) ||
173 (defined $opt_noipv6links) ||
174 (defined $opt_kqueue) ||
175 (defined $opt_epoll) ||
176 (defined $opt_ports) ||
177 (defined $opt_use_openssl) ||
178 (defined $opt_nokqueue) ||
179 (defined $opt_noepoll) ||
180 (defined $opt_noports) ||
181 (defined $opt_maxbuf) ||
182 (defined $opt_use_gnutls) ||
183 (defined $opt_freebsd_port)
185 our $interactive = !$non_interactive;
187 chomp(our $topdir = getcwd());
188 our $this = resolve_directory($topdir); # PWD, Regardless.
189 our @modlist = (); # Declare for Module List..
190 our %config = (); # Initiate Configuration Hash..
191 $config{ME} = resolve_directory($topdir); # Present Working Directory
193 $config{BASE_DIR} = $config{ME};
195 if (defined $opt_base_dir)
197 $config{BASE_DIR} = $opt_base_dir;
200 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
201 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
202 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
203 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
205 if (defined $opt_config_dir)
207 $config{CONFIG_DIR} = $opt_config_dir;
209 if (defined $opt_module_dir)
211 $config{MODULE_DIR} = $opt_module_dir;
213 if (defined $opt_binary_dir)
215 $config{BINARY_DIR} = $opt_binary_dir;
217 if (defined $opt_library_dir)
219 $config{LIBRARY_DIR} = $opt_library_dir;
221 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
223 if (defined $opt_freebsd_port)
225 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
226 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
227 $config{USE_FREEBSD_BASE_SSL} = "n";
231 if ($^O eq "freebsd")
233 # default: use base ssl
234 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
235 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
239 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
240 $config{HAS_OPENSSL_PORT} = "";
244 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
245 chomp(our $openssl_ver = $config{HAS_OPENSSL});
246 $config{USE_GNUTLS} = "n";
247 if (defined $opt_use_gnutls)
249 $config{USE_GNUTLS} = "y"; # Use gnutls.
251 $config{USE_OPENSSL} = "n"; # Use openssl.
252 if (defined $opt_use_openssl)
254 $config{USE_OPENSSL} = "y";
257 # no, let's not change these.
258 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
259 if (!defined $opt_disable_debug)
261 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
265 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
268 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
269 $config{HAS_STDINT} = "false"; # stdint.h check
270 $config{USE_KQUEUE} = "y"; # kqueue enabled
271 if (defined $opt_kqueue)
273 $config{USE_KQUEUE} = "y";
275 if (defined $opt_nokqueue)
277 $config{USE_KQUEUE} = "n";
279 $config{USE_POLL} = "y"; # poll enabled
280 $config{USE_EPOLL} = "y"; # epoll enabled
281 if (defined $opt_epoll)
283 $config{USE_EPOLL} = "y";
285 if (defined $opt_noepoll)
287 $config{USE_EPOLL} = "n";
289 $config{USE_PORTS} = "y"; # epoll enabled
290 if (defined $opt_ports)
292 $config{USE_PORTS} = "y";
294 if (defined $opt_noports)
296 $config{USE_PORTS} = "n";
298 $config{IPV6} = "n"; # IPv6 support (experimental)
299 if (defined $opt_ipv6)
303 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
304 if (defined $opt_ipv6links)
306 $config{SUPPORT_IP6LINKS} = "y";
308 if (defined $opt_noipv6links)
310 $config{SUPPORT_IP6LINKS} = "n";
312 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
313 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
314 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
315 $config{OSNAME} = $^O; # Operating System Name
316 $config{IS_DARWIN} = "NO"; # Is OSX?
317 $config{STARTSCRIPT} = "inspircd"; # start script?
318 $config{DESTINATION} = "BASE"; # Is target path.
319 $config{EXTRA_DIR} = ""; # Is empty.
320 if ($config{OSNAME} =~ /darwin/i)
322 $config{IS_DARWIN} = "YES";
323 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
324 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
325 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
327 $config{CC} = "g++"; # C++ compiler
330 $config{CC} = $opt_cc;
332 our $exec = $config{CC} . " -dumpversion | cut -c 1";
333 chomp($config{GCCVER} = `$exec`); # Major GCC Version
334 $exec = $config{CC} . " -dumpversion | cut -c 3";
335 chomp($config{GCCMINOR} = `$exec`);
336 $config{MAKEORDER} = "ircd mods"; # build order
337 $config{MAXBUF} = "512"; # Max buffer size
339 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
340 $config{HAS_OPENSSL} = $1;
342 $config{HAS_OPENSSL} = "";
345 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
346 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
350 # Get and Set some important vars..
355 unlink(".config.cache");
358 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
363 chomp($topdir = getcwd());
364 $this = resolve_directory($topdir); # PWD, Regardless.
366 # Does the cache file exist?
368 # No, No it doesn't.. *BASH*
369 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
372 # We've Loaded the cache file and all our variables..
373 print "Updating files...\n";
375 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
377 print "Disabling debug information (-g).\n";
378 $config{OPTIMISATI} = "";
381 $has_epoll = $config{HAS_EPOLL};
382 $has_ports = $config{HAS_PORTS};
383 $has_kqueue = $config{HAS_KQUEUE};
392 print "Configure update failed: $@\n";
400 chomp($topdir = getcwd());
401 $this = resolve_directory($topdir); # PWD, Regardless.
403 # Does the cache file exist?
405 # No, No it doesn't.. *BASH*
406 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
409 # We've Loaded the cache file and all our variables..
410 print "Updating files...\n";
412 $has_epoll = $config{HAS_EPOLL};
413 $has_ports = $config{HAS_PORTS};
414 $has_kqueue = $config{HAS_KQUEUE};
423 print "Module update failed: $@\n";
433 open(FH,"<.svn/entries") or $fail = 1;
435 print "This is not an SVN copy of InspIRCd.\n";
442 open my $fd, "-|", "svn update";
443 my $configurechanged = 0; # Needs ./configure -update
444 my $coredirchanged = 0; # Needs ./configure -update
445 my $moduledirchanged = 0; # Needs ./configure -modupdate
446 my $rootincchanged = 0;
448 while (defined(my $line = <$fd>))
452 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
453 ($action, $file) = ($1, $2);
456 push @conflicted, $file;
457 if ($file eq "configure")
459 $configurechanged = 1;
461 elsif ($file =~ m#^src/modules#)
463 $moduledirchanged = 1;
465 elsif ($file =~ m#^src/#)
469 elsif ($file =~ m/^\..*\.inc$/)
474 elsif ($action eq "U" || $action eq "G")
476 if ($file eq "configure")
478 $configurechanged = 1;
480 elsif ($file =~ m/^\..*\.inc$/)
485 elsif ($action eq "A" || $action eq "D")
487 if ($file =~ m#^src/modules#)
489 $moduledirchanged = 1;
491 elsif ($file =~ m#^src/#)
497 unless (close $fd) # close() waits for exit and returns false if the command failed
501 print STDERR "Problem updating from SVN, please check above for errors\n";
505 print STDERR "Failed to run SVN: $!\n";
509 if (scalar(@conflicted) > 0)
511 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
512 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate\n", (($coredirchanged || $configurechanged) ? "" : "mod");
513 print "Conflicted files: " . join ", ", @conflicted . "\n";
516 if ($configurechanged || $coredirchanged)
518 system("perl configure -update");
520 elsif ($moduledirchanged || $rootincchanged)
522 system("perl configure -modupdate");
526 print "No need to update Makefiles.\n";
528 if (defined $opt_rebuild) {
529 system("make install");
534 print "Running non-interactive configure...\n" unless $interactive;
535 print "Checking for cache from previous configure... ";
536 print ((!getcache()) ? "not found\n" : "found\n");
537 print "Checking operating system version... ";
538 print getosflags() . "\n";
540 printf "Checking if stdint.h exists... ";
541 $config{HAS_STDINT} = "true";
543 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
544 if ($config{HAS_STDINT} eq "true") {
547 print "yes\n" if $config{HAS_STDINT} eq "true";
548 print "no\n" if $config{HAS_STDINT} eq "false";
550 printf "Checking if strlcpy exists... ";
551 # Perform the strlcpy() test..
552 $config{HAS_STRLCPY} = "false";
554 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
556 while (defined(my $line = <STRLCPY>)) {
558 # try and find the delcaration of:
559 # size_t strlcpy(...)
560 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
561 $config{HAS_STRLCPY} = "true";
566 print "yes\n" if $config{HAS_STRLCPY} eq "true";
567 print "no\n" if $config{HAS_STRLCPY} eq "false";
569 printf "Checking if kqueue exists... ";
572 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
574 while (defined(my $line = <KQUEUE>)) {
576 # try and find the delcaration of:
578 if ($line =~ /int(\0x9|\s)+kqueue/) {
584 print "yes\n" if $has_kqueue == 1;
585 print "no\n" if $has_kqueue == 0;
587 printf "Checking if epoll exists... ";
590 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
596 my $kernel = `uname -r`;
598 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
603 # Suggestion from nenolod, weed out odd systems which have glibc built
604 # against 2.4 kernels (ick)
605 my $kernel_arch = `uname -p`;
609 if ($kernel_arch =~ /x86_64/) {
610 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
613 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
617 while (defined(my $line = <FH>))
620 if ($line =~ /GNU C Library .* version (.*?) /)
623 $libcv =~ /(\d+\.\d+)/;
626 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
629 # Fix for some retarded libc builds, strip off >> and << etc.
630 $kernelv =~ /(\d+\.\d+)/;
638 printf "libc too old: $libcv... ";
643 printf "libc built against older kernel $kernelv... ";
648 print "yes\n" if $has_epoll == 1;
649 print "no\n" if $has_epoll == 0;
651 printf "Checking if Solaris I/O completion ports are available... ";
653 our $system = `uname -s`;
655 $has_ports = 1 if ($system eq "SunOS");
658 my $kernel = `uname -r`;
660 if (($kernel !~ /^5\.1./)) {
664 print "yes\n" if $has_ports == 1;
665 print "no\n" if $has_ports == 0;
667 $config{HAS_EPOLL} = $has_epoll;
668 $config{HAS_KQUEUE} = $has_kqueue;
670 printf "Checking for libgnutls... ";
671 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
672 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
674 $config{HAS_GNUTLS} = "y";
677 $config{HAS_GNUTLS} = "n";
681 $config{HAS_GNUTLS} = "n";
684 printf "Checking for openssl... ";
685 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
686 if (defined($openssl_ver) && ($openssl_ver ne "")) {
688 $config{HAS_OPENSSL} = "y";
691 $config{HAS_OPENSSL} = "n";
695 $config{HAS_OPENSSL} = "n";
698 printf "Checking if you are running an ancient, unsupported OS... ";
699 if ($config{OSNAME} =~ /FreeBSD/i)
701 my $version = `uname -r`;
702 if ($version =~ /^4\./)
704 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
707 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
708 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
709 print "yes (upgrade ffs, freebsd 4 is *way* out of date)\n";
713 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
719 print "no ($version)\n";
725 print "no ($config{OSNAME})\n";
728 ################################################################################
729 # BEGIN INTERACTIVE PART #
730 ################################################################################
735 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
738 my $rev = getrevision();
739 # Display Introduction Message..
741 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
742 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
744 *** If you are unsure of any of these values, leave it blank for ***
745 *** standard settings that will work, and your server will run ***
746 *** using them. Please consult your IRC network admin if in doubt. ***
748 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
749 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
750 dir, otherwise you won't have a config file!
752 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
753 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
756 print " (Non-SVN build)";
760 $config{CHANGE_COMPILER} = "n";
761 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";
763 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
764 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
765 should NOT be used. You should probably specify a newer compiler.\n\n";
766 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
767 if ($config{CHANGE_COMPILER} =~ /y/i) {
768 print "What command do you want to use to invoke your compiler?\n";
769 print "[\e[1;32m$config{CC}\e[0m] -> ";
770 chomp($config{CC} = <STDIN>);
771 if ($config{CC} eq "") {
774 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
776 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
777 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
778 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
779 if ($config{GCCVER} < 3) {
780 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
784 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
791 # Directory Settings..
792 my $tmpbase = $config{BASE_DIR};
793 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
794 if ($tmpbase ne $config{BASE_DIR}) {
795 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
796 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
797 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
798 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
801 dir_check("are the configuration files", "CONFIG_DIR");
802 dir_check("are the modules to be compiled to", "MODULE_DIR");
803 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
804 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
806 my $chose_hiperf = 0;
808 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?");
810 if ($config{USE_KQUEUE} eq "y") {
815 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?");
817 if ($config{USE_EPOLL} eq "y") {
822 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?");
824 if ($config{USE_PORTS} eq "y") {
829 if (!$chose_hiperf) {
830 yesno('USE_POLL', "Would you like to use poll?\n This is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable poll?\n");
831 if ($config{USE_POLL} ne "y")
833 print "No high-performance socket engines are available, or you chose\n";
834 print "not to enable one. Defaulting to select() engine.\n\n";
838 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
841 if ($config{IPV6} eq "y") {
842 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";
843 $config{SUPPORT_IP6LINKS} = "y";
845 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?");
849 $config{USE_FREEBSD_BASE_SSL} = "n";
850 $config{USE_FREEBSD_PORTS_SSL} = "n";
851 if ($config{HAS_OPENSSL_PORT} ne "")
853 $config{USE_FREEBSD_PORTS_SSL} = "y";
854 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
855 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";
856 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
858 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
860 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
862 # update to port version
863 $openssl_ver = $config{HAS_OPENSSL_PORT};
868 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
871 $config{USE_SSL} = "n";
873 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
875 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
876 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
878 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
879 if ($config{USE_SSL} eq "y")
881 if ($config{HAS_GNUTLS} eq "y")
883 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
884 if ($config{USE_GNUTLS} eq "y")
886 print "\nUsing GnuTLS SSL module.\n";
890 if ($config{HAS_OPENSSL} eq "y")
892 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
893 if ($config{USE_OPENSSL} eq "y")
895 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
902 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
903 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
909 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
911 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
914 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
916 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
921 if ($config{USE_GNUTLS} eq "y") {
922 unless (-r "src/modules/m_ssl_gnutls.cpp") {
923 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
924 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
929 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
930 print "SSL Certificates Not found, Generating.. \n\n
931 *************************************************************
932 * Generating the Private Key may take some time, go grab a *
933 * Coffee. Even better, to generate some more entropy if it *
934 * is taking a while, open another console and type du / a *
935 * few times and get that HD going :) Then answer the *
936 * Questions which follow. If you are unsure, just hit enter *
937 *************************************************************\n\n";
938 $failed = make_gnutls_cert();
940 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
942 print "\nCertificate generation complete, copying to config directory... ";
943 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
944 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
949 print "SSL Certificates found, skipping.\n\n";
954 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
956 } elsif ($config{USE_OPENSSL} eq "y") {
957 unless (-r "src/modules/m_ssl_openssl.cpp") {
958 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
959 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
965 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
966 print "SSL Certificates Not found, Generating.. \n\n
967 *************************************************************
968 * Generating the certificates may take some time, go grab a *
969 * coffee, or something. *
970 *************************************************************\n\n";
972 print "\nCertificate generation complete, copying to config directory... ";
973 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
974 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
975 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
978 print "SSL Certificates found, skipping.\n\n"
983 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
986 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
987 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
995 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
996 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
997 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
998 print "modules in your config. This configure script has added those modules to the\n";
999 print "build process. For more info please refer to:\n";
1000 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
1002 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
1003 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
1004 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";
1007 if ($config{GCCVER} < "3") {
1009 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
1010 GCC 2.x series compilers only had partial (read as broken) C++ support, and
1011 your compile will most likely fail horribly! If you have any problems, do NOT
1012 report them to the bugtracker or forums without first upgrading your compiler
1013 to a newer 3.x or 4.x (or whatever is available currently) version.
1017 ################################################################################
1018 # HELPER FUNCTIONS #
1019 ################################################################################
1021 # Retrieves the .config.cache file, and loads values into the main config hash.
1022 open(CACHE, ".config.cache") or return 0;
1025 # Ignore Blank lines, and comments..
1028 my ($key, $value) = split("=", $_, 2);
1029 $value =~ /^\"(.*)\"$/;
1030 # Do something with data here!
1038 # Dump the contents of %config
1039 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1040 open(FILEHANDLE, ">.config.cache");
1041 foreach my $key (keys %config) {
1042 print FILEHANDLE "$key=\"$config{$key}\"\n";
1048 my ($desc, $hash_key) = @_;
1050 while (!$complete) {
1051 print "In what directory $desc?\n";
1052 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1053 chomp(my $var = <STDIN>);
1055 $var = $config{$hash_key};
1057 if ($var =~ /^\~\/(.+)$/) {
1058 # Convert it to a full path..
1059 $var = resolve_directory($ENV{HOME} . "/" . $1);
1061 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1063 # Assume relative Path was given.. fill in the rest.
1064 $var = $this . "/$var";
1067 $var = resolve_directory($var);
1069 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1070 chomp(my $tmp = <STDIN>);
1071 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1072 # Attempt to Create the Dir..
1075 File::Path::mkpath($var, 0, 0777);
1078 unless (defined($chk) && -d $var) {
1079 print "Unable to create directory. ($var)\n\n";
1084 # They said they don't want to create, and we can't install there.
1089 if (!is_dir($var)) {
1090 # Target exists, but is not a directory.
1091 print "File $var exists, but is not a directory.\n\n";
1095 # Either Dir Exists, or was created fine.
1096 $config{$hash_key} = $var;
1106 # Beware: Linux sets it's own cflags below for some retarded reason
1107 $config{LDLIBS} = "-pthread -lstdc++";
1108 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1109 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1110 $SHARED = "-shared -export-dynamic";
1111 $config{MAKEPROG} = "make";
1113 if ($config{OSNAME} =~ /darwin/i) {
1114 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1115 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1116 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1119 if ($config{OSNAME} =~ /OpenBSD/i) {
1120 $config{MAKEPROG} = "gmake";
1121 # apparantly (Dagonet says) that this causes problems, so let's try without it.
1122 # $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1123 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1124 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1125 # if theyre not running this, configure lets the build continue but they probably wont manage to
1126 # compile as this standard version is 2.95.3!
1128 $config{CC} = "eg++";
1129 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1130 chomp($config{GCCMINOR} = `eg++ -dumpversion | cut -c 3`);
1135 if ($config{OSNAME} =~ /Linux/i) {
1136 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1137 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1138 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1139 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1140 $config{MAKEPROG} = "make";
1143 if ($config{OSNAME} =~ /FreeBSD/i) {
1144 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1145 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1148 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1150 # solaris/sunos needs these
1151 # socket = bsd sockets api
1153 # rt = POSIX realtime extensions
1154 # resolv = inet_aton only (why isnt this in nsl?!)
1155 $config{MAKEPROG} = "gmake";
1156 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1160 if($config{OSNAME} =~ /MINGW32/i)
1162 # All code is position-independent on windows
1163 $config{FLAGS} =~ s/-fPIC //;
1167 return $config{OSNAME};
1170 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1173 my($writeheader) = @_;
1175 # First File.. inspircd_config.h
1176 chomp(my $incos = `uname -n -s -r`);
1177 chomp(my $version = `sh src/version.sh`);
1178 chomp(my $revision2 = getrevision());
1179 if ($writeheader == 1)
1181 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1182 open(FILEHANDLE, ">include/inspircd_config.h");
1183 print FILEHANDLE <<EOF;
1184 /* Auto generated by configure, do not modify! */
1185 #ifndef __CONFIGURATION_AUTO__
1186 #define __CONFIGURATION_AUTO__
1188 /* this is for windows support. */
1189 #define CoreExport /**/
1190 #define DllExport /**/
1192 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1193 #define MOD_PATH "$config{MODULE_DIR}"
1194 #define VERSION "$version"
1195 #define REVISION "$revision2"
1196 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1197 #define OPTIMISATION $config{OPTIMITEMP}
1198 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1199 #define SYSTEM "$incos"
1200 #define ENTRYPOINT int main(int argc, char** argv)
1203 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1205 if ($config{OSNAME} =~ /SunOS/i) {
1206 print FILEHANDLE "#define IS_SOLARIS\n";
1208 if ($config{OSNAME} =~ /MINGW32/i) {
1209 print FILEHANDLE "#define IS_MINGW\n";
1211 if ($config{GCCVER} >= 3) {
1212 print FILEHANDLE "#define GCC3\n";
1215 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
1217 ($config{GCCVER} > 4)
1219 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
1221 if ($config{HAS_STRLCPY} eq "true") {
1222 print FILEHANDLE "#define HAS_STRLCPY\n";
1224 if ($config{HAS_STDINT} eq "true") {
1225 print FILEHANDLE "#define HAS_STDINT\n";
1227 if ($config{IPV6} =~ /y/i) {
1228 print FILEHANDLE "#define IPV6\n";
1230 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1231 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1234 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1235 print FILEHANDLE "#define USE_KQUEUE\n";
1236 $se = "socketengine_kqueue";
1239 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1240 print FILEHANDLE "#define USE_EPOLL\n";
1241 $se = "socketengine_epoll";
1244 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1245 print FILEHANDLE "#define USE_PORTS\n";
1246 $se = "socketengine_ports";
1249 # user didn't choose either epoll or select for their OS.
1250 # default them to USE_SELECT (ewwy puke puke)
1252 print "no hi-perf, " . $config{USE_POLL};
1253 if ($config{USE_POLL} eq "y")
1255 print FILEHANDLE "#define USE_POLL\n";
1256 $se = "socketengine_poll";
1260 print FILEHANDLE "#define USE_SELECT\n";
1261 $se = "socketengine_select";
1264 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1270 open(FILEHANDLE, ">include/inspircd_se_config.h");
1271 print FILEHANDLE <<EOF;
1272 /* Auto generated by configure, do not modify or commit to svn! */
1273 #ifndef __CONFIGURATION_SOCKETENGINE__
1274 #define __CONFIGURATION_SOCKETENGINE__
1276 #include "socketengines/$se.h"
1284 # Create a Modules List..
1286 foreach my $i (@modlist)
1288 $modules .= "m_".$i.".so ";
1290 chomp($modules); # Remove Redundant whitespace..
1292 opendir(DIRHANDLE, "src/modules");
1293 foreach my $name2 (sort readdir(DIRHANDLE)) {
1294 if ($name2 =~ /^m_(.+?)$/) {
1295 if (defined(opendir(MDIRHANDLE, "src/modules/$name2"))) {
1296 closedir(MDIRHANDLE);
1297 $modules .= "$name2.so ";
1298 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name2.so\n";
1302 closedir(DIRHANDLE);
1305 # Write all .in files.
1308 my $exe = "inspircd";
1310 # Do this once here, and cache it in the .*.inc files,
1311 # rather than attempting to read src/version.sh from
1312 # compiled code -- we might not have the source to hand.
1313 # Fix for bug#177 by Brain.
1315 chomp($version = `sh ./src/version.sh`);
1316 chomp(my $revision = getrevision());
1317 $version = "$version(r$revision)";
1319 # We can actually parse any file starting with . and ending with .inc,
1320 # but right now we only parse .inspircd.inc to form './inspircd'
1322 print "Writing \e[1;32mMakefiles\e[0m\n";
1323 write_dynamic_modules_makefile();
1324 write_dynamic_makefile();
1326 opendir(DIRHANDLE, $this);
1328 foreach my $name (sort readdir(DIRHANDLE)) {
1329 if ($name =~ /^\.(.+)\.inc$/) {
1332 # Bug #353, omit this on non-darwin
1333 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1335 # All .name.inc files need parsing!
1337 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1338 while (<FILEHANDLE>) {
1343 print "Writing \e[1;32m$file\e[0m ...\n";
1344 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1345 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1346 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1347 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1348 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1349 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1350 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1351 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1352 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1353 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1354 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1355 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1356 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1357 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1358 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1359 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1360 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1361 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1362 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1364 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1365 print FILEHANDLE $tmp;
1368 closedir(DIRHANDLE);
1370 # Make inspircd executable!
1371 chmod 0744, 'inspircd';
1374 sub write_dynamic_modules_makefile {
1375 # Modules Makefile..
1376 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1377 open(FILEHANDLE, ">src/modules/Makefile");
1380 # Module Makefile Header
1382 print FILEHANDLE <<EOF;
1383 ###################################################
1384 # Copyright 2002-2009 The InspIRCd Development Team
1385 # http://www.inspircd.org/wiki/index.php/Credits
1387 # Thanks to Andrew Church <achurch\@achurch.org>
1388 # for assisting with making this work right.
1390 # Automatically Generated by ./configure to add a
1391 # modules please run ./configure -modupdate
1392 ###################################################
1398 if ($config{OSNAME} =~ /darwin/) {
1399 print FILEHANDLE <<EOCHEESE;
1401 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1405 print FILEHANDLE <<EOCHEESE;
1407 PICLDFLAGS = -fPIC -DPIC -shared
1413 # End Module Makefile Header
1416 # Create a Modules List..
1420 foreach my $i (@modlist) {
1422 # Write Entry to the MakeFile
1424 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1425 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1426 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1428 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1431 if (nopedantic("src/modules/m_".$i.".cpp"))
1434 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
1435 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags $SHARED -o m_$i.so m_$i.cpp
1441 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
1442 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags $SHARED -o m_$i.so m_$i.cpp
1445 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1446 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1448 # End Write Entry to the MakeFile
1452 opendir(DIRHANDLE, "src/modules");
1453 foreach my $name (sort readdir(DIRHANDLE)) {
1454 if ($name =~ /^m_(.+?)$/) {
1459 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1460 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1461 read_module_directory("src/modules/$name", $name);
1462 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1463 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";
1464 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) $SHARED $mliflags -o $name.so $mobjs\n";
1465 print FILEHANDLE "\n$mfrules\n";
1466 closedir(MDIRHANDLE);
1467 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1471 closedir(DIRHANDLE);
1474 sub read_module_directory {
1475 my ($dpath, $reldpath) = @_;
1477 if (opendir(MDIRHANDLE, $dpath) == 0) {
1481 foreach my $fname (sort readdir(MDIRHANDLE)) {
1482 if ($fname =~ /\.cpp$/) {
1483 my $cmflags = getcompilerflags("$dpath/$fname");
1484 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1485 my $deps = getdependencies("$dpath/$fname");
1487 $oname =~ s/\.cpp$/.o/g;
1488 $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";
1489 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags $SHARED -o $reldpath/$oname -c $reldpath/$fname\n\n";
1490 $mobjs = $mobjs . " $reldpath/$oname";
1493 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1494 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1501 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1502 # dependencies which are not relevent in C++.
1506 open (CPP, "<$file") or die("Can't open $file for reading!");
1511 foreach my $d (@ignoredeps)
1517 foreach my $dep (@immutabledeps)
1519 $immutable = $immutable . "../include/$dep ";
1521 $immutable =~ s/ $//g;
1523 while (defined(my $line = <CPP>))
1526 if ($line =~ /#include "(.+\.h)"/)
1528 if (!exists($dupe{$1}))
1530 $retlist = $retlist . "../include/$1 ";
1536 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1539 sub write_dynamic_makefile
1543 my %existing_install_list = ();
1544 my %core_files_list = ();
1546 opendir(DIRHANDLE, "src/commands");
1547 foreach my $name (sort readdir(DIRHANDLE))
1549 if ($name =~ /^cmd_(.+)\.cpp$/)
1551 $cmdlist[$i++] = $1;
1552 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1553 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1556 closedir(DIRHANDLE);
1560 $config{USE_EPOLL} = 0;
1564 $config{USE_KQUEUE} = 0;
1568 $config{USE_PORTS} = 0;
1571 # formerly generated below this foreach, now it's not! magic.
1574 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1576 print "Scanning \e[1;32m$dir\e[0m for core files ";
1577 opendir(DIRHANDLE, $dir);
1578 foreach my $name (sort readdir(DIRHANDLE))
1580 if ($name =~ /\.cpp$/)
1582 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1584 while (defined(my $line = <CPP>))
1587 if ($line =~ /\/\* \$Core \*\//i)
1590 $sname =~ s/\.cpp$/.o/;
1592 # append it to list to be built
1593 $all_core = $all_core . $sname . " ";
1594 $filelist{$name} = $sname;
1596 # mark it as a core file, so it won't get shared object cflags
1597 if (!exists($core_files_list{$name}))
1599 $core_files_list{$name} = 1;
1602 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1604 $specialdeps{$name} = $1;
1606 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1608 $extraobjects{$name} = $1;
1610 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1612 $extrabuildlines{$name} = $1;
1614 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1616 $extrasources{$name} = $1;
1618 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1620 if (defined $config{$1})
1622 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1625 while (defined($line = <CPP>))
1628 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1629 last if ($line =~ /\/\* \$EndIf \*\//i);
1634 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1636 if (!exists($existing_install_list{$1}))
1638 $existing_install_list{$1} = 1;
1639 my $idir = (split(' ',$1))[1];
1640 my $ifile = (split(' ',$1))[0];
1641 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1642 $ifile =~ s/.*\///g;
1643 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1646 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1648 if (!exists($existing_install_list{$1}))
1650 $existing_install_list{$1} = 1;
1651 my $idir = (split(' ',$1))[1];
1652 my $ifile = (split(' ',$1))[0];
1653 $install_list = $install_list . " -cp $1\n";
1654 $ifile =~ s/.*\///g;
1655 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1662 closedir(DIRHANDLE);
1666 # modes need to be compiled in too
1667 $all_core = $all_core . "modes/modeclasses.a";
1669 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1671 my $libraryext = "";
1672 my $binary_rule = "";
1674 if ($config{IS_DARWIN} eq "YES")
1676 $libraryext = "dylib";
1677 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -c inspircd.cpp\n \@../make/run-cc.pl \$(CC) -pipe -dynamic -bind_at_load -L. -o inspircd \$(LDLIBS) inspircd.o "
1682 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1685 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1688 CC = im a cheezeball
1689 CXXFLAGS = -I../include \${FLAGS}
1690 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1691 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1695 my $buildstring = "";
1698 foreach my $cpp (sort keys %filelist)
1702 $objs =~ s/\.cpp$/.o/;
1703 if (exists($extraobjects{$cpp}))
1705 $objs = $objs . " " . $extraobjects{$cpp};
1706 $all_core = $all_core . " " . $extraobjects{$cpp};
1708 if (exists($extrasources{$cpp}))
1710 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1713 $deps = calcdeps("src/$cpp");
1714 if (exists($extrasources{$cpp}))
1716 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1718 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1721 $deps = $deps . $d . " ";
1725 $buildstring = $buildstring . $objs . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1727 if (exists($core_files_list{$cpp}))
1729 # core files are statically linked into the binary and do not require $SHARED shared libs switches
1730 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -c $rawcpp\n";
1734 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) $SHARED -c $rawcpp\n";
1737 if (exists($extrabuildlines{$cpp}))
1739 $buildstring = $buildstring . " " . $extrabuildlines{$cpp} . "\n";
1743 print FH "all: inspircd moo\n\n\n";
1745 $deps = calcdeps("src/inspircd.cpp");
1746 print FH "inspircd: inspircd.cpp $deps $all_core\n";
1747 print FH "$binary_rule $all_core\n\n";
1749 print FH $buildstring;
1750 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1752 # close main makefile
1756 # generate a list of .so
1757 foreach my $cmd (@cmdlist) {
1758 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1761 # and now reopen the commands makefile
1762 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1765 CXXFLAGS = -I../../include \${FLAGS}
1772 # now print the command file detail
1773 foreach my $cmd (@cmdlist) {
1775 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
1776 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1782 # Routine to list out the extra/ modules that have been enabled.
1783 # Note: when getting any filenames out and comparing, it's important to lc it if the
1784 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1785 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1786 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1787 sub list_extras () {
1790 my $srcdir = File::Spec->catdir("src", "modules");
1791 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1794 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1795 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1798 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1799 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1802 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1804 EXTRA: for my $extra (@extras) {
1805 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1806 next if ($extra eq '.svn');
1807 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1808 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1809 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1810 if (-l $abs_source) {
1811 # Symlink, is it in the right place?
1812 my $targ = readlink($abs_source);
1813 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1814 if ($abs_targ eq $abs_extra) {
1815 $extras{$extra} = "\e[32;1menabled\e[0m";
1817 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1819 } elsif (-e $abs_source) {
1820 my ($devext, $inoext) = stat($abs_extra);
1821 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1823 if ($devsrc == $devext && $inosrc == $inoext) {
1824 $extras{$extra} = "\e[32;1menabled\e[0m";
1826 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1829 open my $extfd, "<", $abs_extra;
1830 open my $srcfd, "<", $abs_source;
1832 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1833 $extras{$extra} = "\e[32;1menabled\e[0m";
1835 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1839 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1842 # Now let's add dependency info
1843 for my $extra (keys(%extras)) {
1844 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1845 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1846 my @deps = split / +/, getdependencies($abs_extra);
1847 for my $dep (@deps) {
1848 if (exists($extras{$dep})) {
1849 my $ref = \$extras{$dep}; # Take reference.
1850 if ($$ref !~ m/needed by/) {
1851 # First dependency found.
1852 if ($$ref =~ m/enabled/) {
1853 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1855 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1856 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1859 if ($$ref =~ m/enabled/) {
1860 $$ref .= ", \e[32;1m$extra\e[0m";
1862 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1868 for my $extra (sort {$a cmp $b} keys(%extras)) {
1869 my $text = $extras{$extra};
1870 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1871 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1873 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1876 return keys(%extras) if wantarray; # Can be used by manage_extras.
1879 sub enable_extras (@) {
1881 for my $extra (@extras) {
1882 my $extrapath = "src/modules/extra/$extra";
1883 if (!-e $extrapath) {
1884 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1887 my $source = "src/modules/$extra";
1889 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1892 # Get dependencies, and add them to be processed.
1893 my @deps = split / +/, getdependencies($extrapath);
1894 for my $dep (@deps) {
1895 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1896 if (!-e "src/modules/$dep") {
1897 if (-e "src/modules/extra/$dep") {
1898 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1901 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";
1905 print "Enabling $extra ... \n";
1906 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1910 sub disable_extras (@)
1912 opendir my $dd, "src/modules/extra/";
1913 my @files = readdir($dd);
1916 EXTRA: for my $extra (@extras) {
1917 my $extrapath = "src/modules/extra/$extra";
1918 my $source = "src/modules/$extra";
1919 if (!-e $extrapath) {
1920 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1923 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1924 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";
1927 # Check if anything needs this.
1928 for my $file (@files) {
1929 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1930 # File depends on this extra...
1931 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1932 # And is both enabled and not about to be disabled.
1933 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1934 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1940 print "Disabling $extra ... \n";
1941 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";