2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2008 The InspIRCd Development Team
6 # http://www.inspircd.org/wiki/index.php/Credits
8 # Licensed under GPL, please see the COPYING file
13 ###################################################
20 use warnings FATAL => qw(all);
24 $Data::Dumper::Sortkeys = 1;
25 $Data::Dumper::Useqq = 1;
34 # Utility functions for our buildsystem
38 use make::opensslcert;
40 ###############################################################################################
44 ###############################################################################################
46 # If you wish to ignore a dependency throughout the entire core, add it here.
49 "inspircd_win32wrapper.h", # windows has its own configure program
52 # If you wish for all files in the entire core to have a given dependency, insert it here.
53 # You should keep this to an absolute minimum to avoid rebuilds that are not neccessary.
55 our @immutabledeps = (
56 "inspircd_config.h", # auto re-generated by configure
60 ###############################################################################################
62 # NON-EDITABLE VARIABLES
64 ###############################################################################################
66 # List of commands that make up 'make install' and 'make deinstall'
68 our $install_list = "";
69 our $uninstall_list = "";
71 # This is a list of all files in the core. Each cpp file is mapped to a shared object file,
72 # whos file extension is omitted (these can vary from system to system). Auto detected by
73 # scanning the src/*.cpp files for files containing /* $Core */ identifiers.
77 # If you wish for a file to have special dependencies in the makefile, add an entry here.
78 # Auto populated by /* $ExtraDeps: */ instruction
80 our %specialdeps = ();
82 # If you wish for a file to have extra make lines (in between the compile and link steps)
83 # then insert them here.
84 # Auto populated by /* $ExtraBuild: */ instruction
86 our %extrabuildlines = ();
88 # If you wish for a file to be linked against extra objects or arctives, insert them here.
89 # Auto populated by /* $ExtraObjects: */ instruction
91 our %extraobjects = ();
93 # If you wish to compile extra cpp sources into an object, define them here.
94 # NOTE: Certain cpp files such as the socket engines have a value auto calculated
95 # for this table so that their derived class is built.
96 # Auto populated by /* $ExtraSources: */ instruction
98 our %extrasources = ();
100 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
101 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
102 $opt_ipv6, $opt_ipv6links, $opt_noipv6links, $opt_maxbuf, $opt_disable_debug,
105 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
110 sub enable_extras (@);
112 sub disable_extras (@);
114 my @opt_enableextras;
115 my @opt_disableextras;
118 'enable-gnutls' => \$opt_use_gnutls,
119 'rebuild' => \$opt_rebuild,
120 'enable-openssl' => \$opt_use_openssl,
121 'disable-interactive' => \$opt_nointeractive,
122 'enable-ports' => \$opt_ports,
123 'enable-epoll' => \$opt_epoll,
124 'enable-kqueue' => \$opt_kqueue,
125 'disable-ports' => \$opt_noports,
126 'disable-epoll' => \$opt_noepoll,
127 'disable-kqueue' => \$opt_nokqueue,
128 'enable-ipv6' => \$opt_ipv6,
129 'enable-remote-ipv6' => \$opt_ipv6links,
130 'disable-remote-ipv6' => \$opt_noipv6links,
131 'with-cc=s' => \$opt_cc,
132 'with-maxbuf=i' => \$opt_maxbuf,
133 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
134 'prefix=s' => \$opt_base_dir,
135 'config-dir=s' => \$opt_config_dir,
136 'module-dir=s' => \$opt_module_dir,
137 'binary-dir=s' => \$opt_binary_dir,
138 'library-dir=s' => \$opt_library_dir,
139 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
140 'help' => sub { showhelp(); },
141 'modupdate' => sub { modupdate(); },
142 'update' => sub { update(); },
143 'svnupdate' => sub { svnupdate(); },
144 'clean' => sub { clean(); },
145 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
146 'enable-extras=s@' => \@opt_enableextras, # ^
147 'disable-extras=s@' => \@opt_disableextras, # ^
150 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
151 @opt_enableextras = split /,/, join(',', @opt_enableextras);
152 @opt_disableextras = split /,/, join(',', @opt_disableextras);
153 enable_extras(@opt_enableextras);
154 disable_extras(@opt_disableextras);
156 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
157 print "Run $0 -modupdate after you've done this to update the makefiles.\n";
161 our $non_interactive = (
162 (defined $opt_library_dir) ||
163 (defined $opt_base_dir) ||
164 (defined $opt_config_dir) ||
165 (defined $opt_module_dir) ||
166 (defined $opt_base_dir) ||
167 (defined $opt_binary_dir) ||
168 (defined $opt_nointeractive) ||
170 (defined $opt_ipv6) ||
171 (defined $opt_ipv6links) ||
172 (defined $opt_noipv6links) ||
173 (defined $opt_kqueue) ||
174 (defined $opt_epoll) ||
175 (defined $opt_ports) ||
176 (defined $opt_use_openssl) ||
177 (defined $opt_nokqueue) ||
178 (defined $opt_noepoll) ||
179 (defined $opt_noports) ||
180 (defined $opt_maxbuf) ||
181 (defined $opt_use_gnutls) ||
182 (defined $opt_freebsd_port)
184 our $interactive = !$non_interactive;
186 chomp(our $topdir = getcwd());
187 our $this = resolve_directory($topdir); # PWD, Regardless.
188 our @modlist = (); # Declare for Module List..
189 our %config = (); # Initiate Configuration Hash..
190 $config{ME} = resolve_directory($topdir); # Present Working Directory
192 $config{BASE_DIR} = $config{ME};
194 if (defined $opt_base_dir)
196 $config{BASE_DIR} = $opt_base_dir;
199 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
200 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
201 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
202 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
204 if (defined $opt_config_dir)
206 $config{CONFIG_DIR} = $opt_config_dir;
208 if (defined $opt_module_dir)
210 $config{MODULE_DIR} = $opt_module_dir;
212 if (defined $opt_binary_dir)
214 $config{BINARY_DIR} = $opt_binary_dir;
216 if (defined $opt_library_dir)
218 $config{LIBRARY_DIR} = $opt_library_dir;
220 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
222 if (defined $opt_freebsd_port)
224 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
225 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
226 $config{USE_FREEBSD_BASE_SSL} = "n";
230 if ($^O eq "freebsd")
232 # default: use base ssl
233 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
234 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
238 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
239 $config{HAS_OPENSSL_PORT} = "";
243 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
244 chomp(our $openssl_ver = $config{HAS_OPENSSL});
245 $config{USE_GNUTLS} = "n";
246 if (defined $opt_use_gnutls)
248 $config{USE_GNUTLS} = "y"; # Use gnutls.
250 $config{USE_OPENSSL} = "n"; # Use openssl.
251 if (defined $opt_use_openssl)
253 $config{USE_OPENSSL} = "y";
256 # no, let's not change these.
257 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
258 if (!defined $opt_disable_debug)
260 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
264 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
267 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
268 $config{HAS_STDINT} = "false"; # stdint.h check
269 $config{USE_KQUEUE} = "y"; # kqueue enabled
270 if (defined $opt_kqueue)
272 $config{USE_KQUEUE} = "y";
274 if (defined $opt_nokqueue)
276 $config{USE_KQUEUE} = "n";
278 $config{USE_POLL} = "y"; # poll enabled
279 $config{USE_EPOLL} = "y"; # epoll enabled
280 if (defined $opt_epoll)
282 $config{USE_EPOLL} = "y";
284 if (defined $opt_noepoll)
286 $config{USE_EPOLL} = "n";
288 $config{USE_PORTS} = "y"; # epoll enabled
289 if (defined $opt_ports)
291 $config{USE_PORTS} = "y";
293 if (defined $opt_noports)
295 $config{USE_PORTS} = "n";
297 $config{IPV6} = "n"; # IPv6 support (experimental)
298 if (defined $opt_ipv6)
302 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
303 if (defined $opt_ipv6links)
305 $config{SUPPORT_IP6LINKS} = "y";
307 if (defined $opt_noipv6links)
309 $config{SUPPORT_IP6LINKS} = "n";
311 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
312 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
313 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
314 $config{OSNAME} = $^O; # Operating System Name
315 $config{IS_DARWIN} = "NO"; # Is OSX?
316 $config{STARTSCRIPT} = "inspircd"; # start script?
317 $config{DESTINATION} = "BASE"; # Is target path.
318 $config{EXTRA_DIR} = ""; # Is empty.
319 if ($config{OSNAME} =~ /darwin/i)
321 $config{IS_DARWIN} = "YES";
322 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
323 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
324 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
326 $config{CC} = "g++"; # C++ compiler
329 $config{CC} = $opt_cc;
331 our $exec = $config{CC} . " -dumpversion | cut -c 1";
332 chomp($config{GCCVER} = `$exec`); # Major GCC Version
333 $exec = $config{CC} . " -dumpversion | cut -c 3";
334 chomp($config{GCCMINOR} = `$exec`);
335 $config{MAKEORDER} = "ircd mods"; # build order
336 $config{MAXBUF} = "512"; # Max buffer size
338 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
339 $config{HAS_OPENSSL} = $1;
341 $config{HAS_OPENSSL} = "";
344 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
345 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
349 # Get and Set some important vars..
354 unlink(".config.cache");
357 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
362 chomp($topdir = getcwd());
363 $this = resolve_directory($topdir); # PWD, Regardless.
365 # Does the cache file exist?
367 # No, No it doesn't.. *BASH*
368 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
371 # We've Loaded the cache file and all our variables..
372 print "Updating files...\n";
374 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
376 print "Disabling debug information (-g).\n";
377 $config{OPTIMISATI} = "";
380 $has_epoll = $config{HAS_EPOLL};
381 $has_ports = $config{HAS_PORTS};
382 $has_kqueue = $config{HAS_KQUEUE};
391 print "Configure update failed: $@\n";
399 chomp($topdir = getcwd());
400 $this = resolve_directory($topdir); # PWD, Regardless.
402 # Does the cache file exist?
404 # No, No it doesn't.. *BASH*
405 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
408 # We've Loaded the cache file and all our variables..
409 print "Updating files...\n";
411 $has_epoll = $config{HAS_EPOLL};
412 $has_ports = $config{HAS_PORTS};
413 $has_kqueue = $config{HAS_KQUEUE};
422 print "Module update failed: $@\n";
432 open(FH,"<.svn/entries") or $fail = 1;
434 print "This is not an SVN copy of InspIRCd.\n";
441 open my $fd, "-|", "svn update";
442 my $configurechanged = 0; # Needs ./configure -update
443 my $coredirchanged = 0; # Needs ./configure -update
444 my $moduledirchanged = 0; # Needs ./configure -modupdate
445 my $rootincchanged = 0;
447 while (defined(my $line = <$fd>))
451 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
452 ($action, $file) = ($1, $2);
455 push @conflicted, $file;
456 if ($file eq "configure")
458 $configurechanged = 1;
460 elsif ($file =~ m#^src/modules#)
462 $moduledirchanged = 1;
464 elsif ($file =~ m#^src/#)
468 elsif ($file =~ m/^\..*\.inc$/)
473 elsif ($action eq "U" || $action eq "G")
475 if ($file eq "configure")
477 $configurechanged = 1;
479 elsif ($file =~ m/^\..*\.inc$/)
484 elsif ($action eq "A" || $action eq "D")
486 if ($file =~ m#^src/modules#)
488 $moduledirchanged = 1;
490 elsif ($file =~ m#^src/#)
496 unless (close $fd) # close() waits for exit and returns false if the command failed
500 print STDERR "Problem updating from SVN, please check above for errors\n";
504 print STDERR "Failed to run SVN: $!\n";
508 if (scalar(@conflicted) > 0)
510 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
511 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate\n", (($coredirchanged || $configurechanged) ? "" : "mod");
512 print "Conflicted files: " . join ", ", @conflicted . "\n";
515 if ($configurechanged || $coredirchanged)
517 system("perl configure -update");
519 elsif ($moduledirchanged || $rootincchanged)
521 system("perl configure -modupdate");
525 print "No need to update Makefiles.\n";
527 if (defined $opt_rebuild) {
528 system("make install");
533 print "Running non-interactive configure...\n" unless $interactive;
534 print "Checking for cache from previous configure... ";
535 print ((!getcache()) ? "not found\n" : "found\n");
536 print "Checking operating system version... ";
537 print getosflags() . "\n";
539 printf "Checking if stdint.h exists... ";
540 $config{HAS_STDINT} = "true";
542 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
543 if ($config{HAS_STDINT} eq "true") {
546 print "yes\n" if $config{HAS_STDINT} eq "true";
547 print "no\n" if $config{HAS_STDINT} eq "false";
549 printf "Checking if strlcpy exists... ";
550 # Perform the strlcpy() test..
551 $config{HAS_STRLCPY} = "false";
553 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
555 while (defined(my $line = <STRLCPY>)) {
557 # try and find the delcaration of:
558 # size_t strlcpy(...)
559 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
560 $config{HAS_STRLCPY} = "true";
565 print "yes\n" if $config{HAS_STRLCPY} eq "true";
566 print "no\n" if $config{HAS_STRLCPY} eq "false";
568 printf "Checking if kqueue exists... ";
571 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
573 while (defined(my $line = <KQUEUE>)) {
575 # try and find the delcaration of:
577 if ($line =~ /int(\0x9|\s)+kqueue/) {
583 print "yes\n" if $has_kqueue == 1;
584 print "no\n" if $has_kqueue == 0;
586 printf "Checking if epoll exists... ";
589 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
595 my $kernel = `uname -r`;
597 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
602 # Suggestion from nenolod, weed out odd systems which have glibc built
603 # against 2.4 kernels (ick)
604 my $kernel_arch = `uname -p`;
608 if ($kernel_arch =~ /x86_64/) {
609 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
612 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
616 while (defined(my $line = <FH>))
619 if ($line =~ /GNU C Library .* version (.*?) /)
622 $libcv =~ /(\d+\.\d+)/;
625 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
628 # Fix for some retarded libc builds, strip off >> and << etc.
629 $kernelv =~ /(\d+\.\d+)/;
637 printf "libc too old: $libcv... ";
642 printf "libc built against older kernel $kernelv... ";
647 print "yes\n" if $has_epoll == 1;
648 print "no\n" if $has_epoll == 0;
650 printf "Checking if Solaris I/O completion ports are available... ";
652 our $system = `uname -s`;
654 $has_ports = 1 if ($system eq "SunOS");
657 my $kernel = `uname -r`;
659 if (($kernel !~ /^5\.1./)) {
663 print "yes\n" if $has_ports == 1;
664 print "no\n" if $has_ports == 0;
666 $config{HAS_EPOLL} = $has_epoll;
667 $config{HAS_KQUEUE} = $has_kqueue;
669 printf "Checking for libgnutls... ";
670 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
671 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
673 $config{HAS_GNUTLS} = "y";
676 $config{HAS_GNUTLS} = "n";
680 $config{HAS_GNUTLS} = "n";
683 printf "Checking for openssl... ";
684 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
685 if (defined($openssl_ver) && ($openssl_ver ne "")) {
687 $config{HAS_OPENSSL} = "y";
690 $config{HAS_OPENSSL} = "n";
694 $config{HAS_OPENSSL} = "n";
697 printf "Checking if you are running an ancient, unsupported OS... ";
698 if ($config{OSNAME} =~ /FreeBSD/i)
700 my $version = `uname -r`;
701 if ($version =~ /^4\./)
703 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
706 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
707 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
712 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
718 print "no ($version)\n";
724 print "no ($config{OSNAME})\n";
727 ################################################################################
728 # BEGIN INTERACTIVE PART #
729 ################################################################################
734 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
737 my $rev = getrevision();
738 # Display Introduction Message..
740 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
741 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
743 *** If you are unsure of any of these values, leave it blank for ***
744 *** standard settings that will work, and your server will run ***
745 *** using them. Please consult your IRC network admin if in doubt. ***
747 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
748 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
749 dir, otherwise you won't have a config file!
751 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
752 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
755 print " (Non-SVN build)";
759 $config{CHANGE_COMPILER} = "n";
760 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";
762 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
763 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
764 should NOT be used. You should probably specify a newer compiler.\n\n";
765 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
766 if ($config{CHANGE_COMPILER} =~ /y/i) {
767 print "What command do you want to use to invoke your compiler?\n";
768 print "[\e[1;32m$config{CC}\e[0m] -> ";
769 chomp($config{CC} = <STDIN>);
770 if ($config{CC} eq "") {
773 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
775 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
776 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
777 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
778 if ($config{GCCVER} < 3) {
779 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
783 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
790 # Directory Settings..
791 my $tmpbase = $config{BASE_DIR};
792 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
793 if ($tmpbase ne $config{BASE_DIR}) {
794 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
795 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
796 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
797 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
800 dir_check("are the configuration files", "CONFIG_DIR");
801 dir_check("are the modules to be compiled to", "MODULE_DIR");
802 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
803 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
805 my $chose_hiperf = 0;
807 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?");
809 if ($config{USE_KQUEUE} eq "y") {
814 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?");
816 if ($config{USE_EPOLL} eq "y") {
821 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?");
823 if ($config{USE_PORTS} eq "y") {
828 if (!$chose_hiperf) {
829 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");
830 if ($config{USE_POLL} ne "y")
832 print "No high-performance socket engines are available, or you chose\n";
833 print "not to enable one. Defaulting to select() engine.\n\n";
837 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
840 if ($config{IPV6} eq "y") {
841 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";
842 $config{SUPPORT_IP6LINKS} = "y";
844 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?");
848 $config{USE_FREEBSD_BASE_SSL} = "n";
849 $config{USE_FREEBSD_PORTS_SSL} = "n";
850 if ($config{HAS_OPENSSL_PORT} ne "")
852 $config{USE_FREEBSD_PORTS_SSL} = "y";
853 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
854 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";
855 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
857 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
859 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
861 # update to port version
862 $openssl_ver = $config{HAS_OPENSSL_PORT};
867 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
870 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
871 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
872 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
873 print "instead, you should enable the OpenSSL module yourself\n";
874 print "by copying it from src/modules/extra to src/modules.\n\n";
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";
879 if ($config{HAS_GNUTLS} eq "y") {
880 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
881 if ($config{USE_GNUTLS} eq "y") {
882 print "\nUsing GnuTLS SSL module.\n";
884 } elsif ($config{HAS_OPENSSL} eq "y") {
885 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
886 if ($config{USE_OPENSSL} eq "y") {
887 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
891 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";
897 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
899 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
902 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
904 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
909 if ($config{USE_GNUTLS} eq "y") {
910 unless (-r "src/modules/m_ssl_gnutls.cpp") {
911 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
912 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
917 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
918 print "SSL Certificates Not found, Generating.. \n\n
919 *************************************************************
920 * Generating the Private Key may take some time, go grab a *
921 * Coffee. Even better, to generate some more entropy if it *
922 * is taking a while, open another console and type du / a *
923 * few times and get that HD going :) Then answer the *
924 * Questions which follow. If you are unsure, just hit enter *
925 *************************************************************\n\n";
926 $failed = make_gnutls_cert();
928 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
930 print "\nCertificate generation complete, copying to config directory... ";
931 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
932 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
937 print "SSL Certificates found, skipping.\n\n";
942 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
944 } elsif ($config{USE_OPENSSL} eq "y") {
945 unless (-r "src/modules/m_ssl_openssl.cpp") {
946 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
947 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
953 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
954 print "SSL Certificates Not found, Generating.. \n\n
955 *************************************************************
956 * Generating the certificates may take some time, go grab a *
957 * coffee, or something. *
958 *************************************************************\n\n";
960 print "\nCertificate generation complete, copying to config directory... ";
961 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
962 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
963 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
966 print "SSL Certificates found, skipping.\n\n"
971 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
974 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
975 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
983 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
984 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
985 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
986 print "modules in your config. This configure script has added those modules to the\n";
987 print "build process. For more info please refer to:\n";
988 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
990 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
991 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
992 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";
995 if ($config{GCCVER} < "3") {
997 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
998 GCC 2.x series compilers only had partial (read as broken) C++ support, and
999 your compile will most likely fail horribly! If you have any problems, do NOT
1000 report them to the bugtracker or forums without first upgrading your compiler
1001 to a newer 3.x or 4.x (or whatever is available currently) version.
1005 ################################################################################
1006 # HELPER FUNCTIONS #
1007 ################################################################################
1009 # Retrieves the .config.cache file, and loads values into the main config hash.
1010 open(CACHE, ".config.cache") or return 0;
1013 # Ignore Blank lines, and comments..
1016 my ($key, $value) = split("=", $_, 2);
1017 $value =~ /^\"(.*)\"$/;
1018 # Do something with data here!
1026 # Dump the contents of %config
1027 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1028 open(FILEHANDLE, ">.config.cache");
1029 foreach my $key (keys %config) {
1030 print FILEHANDLE "$key=\"$config{$key}\"\n";
1036 my ($desc, $hash_key) = @_;
1038 while (!$complete) {
1039 print "In what directory $desc?\n";
1040 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1041 chomp(my $var = <STDIN>);
1043 $var = $config{$hash_key};
1045 if ($var =~ /^\~\/(.+)$/) {
1046 # Convert it to a full path..
1047 $var = resolve_directory($ENV{HOME} . "/" . $1);
1049 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1051 # Assume relative Path was given.. fill in the rest.
1052 $var = $this . "/$var";
1055 $var = resolve_directory($var);
1057 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1058 chomp(my $tmp = <STDIN>);
1059 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1060 # Attempt to Create the Dir..
1063 File::Path::mkpath($var, 0, 0777);
1066 unless (defined($chk) && -d $var) {
1067 print "Unable to create directory. ($var)\n\n";
1072 # They said they don't want to create, and we can't install there.
1077 if (!is_dir($var)) {
1078 # Target exists, but is not a directory.
1079 print "File $var exists, but is not a directory.\n\n";
1083 # Either Dir Exists, or was created fine.
1084 $config{$hash_key} = $var;
1094 # Beware: Linux sets it's own cflags below for some retarded reason
1095 $config{LDLIBS} = "-pthread -lstdc++";
1096 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1097 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1098 $SHARED = "-shared";
1099 $config{MAKEPROG} = "make";
1101 if ($config{OSNAME} =~ /darwin/i) {
1102 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1103 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1104 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1107 if ($config{OSNAME} =~ /OpenBSD/i) {
1108 $config{MAKEPROG} = "gmake";
1109 # apparantly (Dagonet says) that this causes problems, so let's try without it.
1110 # $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1111 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1112 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1113 # if theyre not running this, configure lets the build continue but they probably wont manage to
1114 # compile as this standard version is 2.95.3!
1116 $config{CC} = "eg++";
1117 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1118 chomp($config{GCCMINOR} = `eg++ -dumpversion | cut -c 3`);
1123 if ($config{OSNAME} =~ /Linux/i) {
1124 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1125 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1126 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1127 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1128 $config{MAKEPROG} = "make";
1131 if ($config{OSNAME} =~ /FreeBSD/i) {
1132 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1133 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1136 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1138 # solaris/sunos needs these
1139 # socket = bsd sockets api
1141 # rt = POSIX realtime extensions
1142 # resolv = inet_aton only (why isnt this in nsl?!)
1143 $config{MAKEPROG} = "gmake";
1144 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1148 if($config{OSNAME} =~ /MINGW32/i)
1150 # All code is position-independent on windows
1151 $config{FLAGS} =~ s/-fPIC //;
1155 return $config{OSNAME};
1158 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1161 my($writeheader) = @_;
1163 # First File.. inspircd_config.h
1164 chomp(my $incos = `uname -n -s -r`);
1165 chomp(my $version = `sh src/version.sh`);
1166 chomp(my $revision2 = getrevision());
1167 if ($writeheader == 1)
1169 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1170 open(FILEHANDLE, ">include/inspircd_config.h");
1171 print FILEHANDLE <<EOF;
1172 /* Auto generated by configure, do not modify! */
1173 #ifndef __CONFIGURATION_AUTO__
1174 #define __CONFIGURATION_AUTO__
1176 /* this is for windows support. */
1177 #define CoreExport /**/
1178 #define DllExport /**/
1180 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1181 #define MOD_PATH "$config{MODULE_DIR}"
1182 #define VERSION "$version"
1183 #define REVISION "$revision2"
1184 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1185 #define OPTIMISATION $config{OPTIMITEMP}
1186 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1187 #define SYSTEM "$incos"
1188 #define ENTRYPOINT int main(int argc, char** argv)
1191 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1193 if ($config{OSNAME} =~ /SunOS/i) {
1194 print FILEHANDLE "#define IS_SOLARIS\n";
1196 if ($config{OSNAME} =~ /MINGW32/i) {
1197 print FILEHANDLE "#define IS_MINGW\n";
1199 if ($config{GCCVER} >= 3) {
1200 print FILEHANDLE "#define GCC3\n";
1203 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
1205 ($config{GCCVER} > 4)
1207 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
1209 if ($config{HAS_STRLCPY} eq "true") {
1210 print FILEHANDLE "#define HAS_STRLCPY\n";
1212 if ($config{HAS_STDINT} eq "true") {
1213 print FILEHANDLE "#define HAS_STDINT\n";
1215 if ($config{IPV6} =~ /y/i) {
1216 print FILEHANDLE "#define IPV6\n";
1218 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1219 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1222 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1223 print FILEHANDLE "#define USE_KQUEUE\n";
1224 $se = "socketengine_kqueue";
1227 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1228 print FILEHANDLE "#define USE_EPOLL\n";
1229 $se = "socketengine_epoll";
1232 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1233 print FILEHANDLE "#define USE_PORTS\n";
1234 $se = "socketengine_ports";
1237 # user didn't choose either epoll or select for their OS.
1238 # default them to USE_SELECT (ewwy puke puke)
1240 print "no hi-perf, " . $config{USE_POLL};
1241 if ($config{USE_POLL} eq "y")
1243 print FILEHANDLE "#define USE_POLL\n";
1244 $se = "socketengine_poll";
1248 print FILEHANDLE "#define USE_SELECT\n";
1249 $se = "socketengine_select";
1252 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1258 open(FILEHANDLE, ">include/inspircd_se_config.h");
1259 print FILEHANDLE <<EOF;
1260 /* Auto generated by configure, do not modify or commit to svn! */
1261 #ifndef __CONFIGURATION_SOCKETENGINE__
1262 #define __CONFIGURATION_SOCKETENGINE__
1264 #include "socketengines/$se.h"
1272 # Create a Modules List..
1274 foreach my $i (@modlist)
1276 $modules .= "m_".$i.".so ";
1278 chomp($modules); # Remove Redundant whitespace..
1280 opendir(DIRHANDLE, "src/modules");
1281 foreach my $name2 (sort readdir(DIRHANDLE)) {
1282 if ($name2 =~ /^m_(.+?)$/) {
1283 if (defined(opendir(MDIRHANDLE, "src/modules/$name2"))) {
1284 closedir(MDIRHANDLE);
1285 $modules .= "$name2.so ";
1286 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name2.so\n";
1290 closedir(DIRHANDLE);
1293 # Write all .in files.
1296 my $exe = "inspircd";
1298 # Do this once here, and cache it in the .*.inc files,
1299 # rather than attempting to read src/version.sh from
1300 # compiled code -- we might not have the source to hand.
1301 # Fix for bug#177 by Brain.
1303 chomp($version = `sh ./src/version.sh`);
1304 chomp(my $revision = getrevision());
1305 $version = "$version(r$revision)";
1307 # We can actually parse any file starting with . and ending with .inc,
1308 # but right now we only parse .inspircd.inc to form './inspircd'
1310 print "Writing \e[1;32mMakefiles\e[0m\n";
1311 write_dynamic_modules_makefile();
1312 write_dynamic_makefile();
1314 opendir(DIRHANDLE, $this);
1316 foreach my $name (sort readdir(DIRHANDLE)) {
1317 if ($name =~ /^\.(.+)\.inc$/) {
1320 # Bug #353, omit this on non-darwin
1321 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1323 # All .name.inc files need parsing!
1325 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1326 while (<FILEHANDLE>) {
1331 print "Writing \e[1;32m$file\e[0m ...\n";
1332 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1333 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1334 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1335 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1336 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1337 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1338 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1339 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1340 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1341 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1342 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1343 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1344 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1345 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1346 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1347 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1348 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1349 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1350 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1352 open(FILEHANDLE, ">$file");
1353 print FILEHANDLE $tmp;
1356 closedir(DIRHANDLE);
1358 # Make inspircd executable!
1359 chmod 0744, 'inspircd';
1362 sub write_dynamic_modules_makefile {
1363 # Modules Makefile..
1364 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1365 open(FILEHANDLE, ">src/modules/Makefile");
1368 # Module Makefile Header
1370 print FILEHANDLE <<EOF;
1371 ###################################################
1372 # Copyright 2002-2007 The InspIRCd Development Team
1373 # http://www.inspircd.org/wiki/index.php/Credits
1375 # Thanks to Andrew Church <achurch\@achurch.org>
1376 # for assisting with making this work right.
1378 # Automatically Generated by ./configure to add a
1379 # modules please run ./configure -modupdate
1380 ###################################################
1386 if ($config{OSNAME} =~ /darwin/) {
1387 print FILEHANDLE <<EOCHEESE;
1389 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1393 print FILEHANDLE <<EOCHEESE;
1395 PICLDFLAGS = -fPIC -DPIC -shared
1401 # End Module Makefile Header
1404 # Create a Modules List..
1408 foreach my $i (@modlist) {
1410 # Write Entry to the MakeFile
1412 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1413 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1414 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1416 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1419 if (nopedantic("src/modules/m_".$i.".cpp"))
1422 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
1423 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1429 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
1430 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1433 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1434 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1436 # End Write Entry to the MakeFile
1440 opendir(DIRHANDLE, "src/modules");
1441 foreach my $name (sort readdir(DIRHANDLE)) {
1442 if ($name =~ /^m_(.+?)$/) {
1447 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1448 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1449 read_module_directory("src/modules/$name", $name);
1450 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1451 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";
1452 if ($config{IS_DARWIN} eq "YES") {
1453 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1455 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1457 print FILEHANDLE "\n$mfrules\n";
1458 closedir(MDIRHANDLE);
1459 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1463 closedir(DIRHANDLE);
1466 sub read_module_directory {
1467 my ($dpath, $reldpath) = @_;
1469 if (opendir(MDIRHANDLE, $dpath) == 0) {
1473 foreach my $fname (sort readdir(MDIRHANDLE)) {
1474 if ($fname =~ /\.cpp$/) {
1475 my $cmflags = getcompilerflags("$dpath/$fname");
1476 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1477 my $deps = getdependencies("$dpath/$fname");
1479 $oname =~ s/\.cpp$/.o/g;
1480 $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";
1481 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1482 $mobjs = $mobjs . " $reldpath/$oname";
1485 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1486 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1493 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1494 # dependencies which are not relevent in C++.
1498 open (CPP, "<$file") or die("Can't open $file for reading!");
1503 foreach my $d (@ignoredeps)
1509 foreach my $dep (@immutabledeps)
1511 $immutable = $immutable . "../include/$dep ";
1513 $immutable =~ s/ $//g;
1515 while (defined(my $line = <CPP>))
1518 if ($line =~ /#include "(.+\.h)"/)
1520 if (!exists($dupe{$1}))
1522 $retlist = $retlist . "../include/$1 ";
1528 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1531 sub write_dynamic_makefile
1535 my %existing_install_list = ();
1536 my %core_files_list = ();
1538 opendir(DIRHANDLE, "src/commands");
1539 foreach my $name (sort readdir(DIRHANDLE))
1541 if ($name =~ /^cmd_(.+)\.cpp$/)
1543 $cmdlist[$i++] = $1;
1544 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1545 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1548 closedir(DIRHANDLE);
1552 $config{USE_EPOLL} = 0;
1556 $config{USE_KQUEUE} = 0;
1560 $config{USE_PORTS} = 0;
1563 # formerly generated below this foreach, now it's not! magic.
1566 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1568 print "Scanning \e[1;32m$dir\e[0m for core files ";
1569 opendir(DIRHANDLE, $dir);
1570 foreach my $name (sort readdir(DIRHANDLE))
1572 if ($name =~ /\.cpp$/)
1574 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1576 while (defined(my $line = <CPP>))
1579 if ($line =~ /\/\* \$Core \*\//i)
1582 $sname =~ s/\.cpp$/.o/;
1584 # append it to list to be built
1585 $all_core = $all_core . $sname . " ";
1586 $filelist{$name} = $sname;
1588 # mark it as a core file, so it won't get shared object cflags
1589 if (!exists($core_files_list{$name}))
1591 $core_files_list{$name} = 1;
1594 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1596 $specialdeps{$name} = $1;
1598 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1600 $extraobjects{$name} = $1;
1602 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1604 $extrabuildlines{$name} = $1;
1606 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1608 $extrasources{$name} = $1;
1610 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1612 if (defined $config{$1})
1614 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1617 while (defined($line = <CPP>))
1620 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1621 last if ($line =~ /\/\* \$EndIf \*\//i);
1626 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1628 if (!exists($existing_install_list{$1}))
1630 $existing_install_list{$1} = 1;
1631 my $idir = (split(' ',$1))[1];
1632 my $ifile = (split(' ',$1))[0];
1633 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1634 $ifile =~ s/.*\///g;
1635 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1638 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1640 if (!exists($existing_install_list{$1}))
1642 $existing_install_list{$1} = 1;
1643 my $idir = (split(' ',$1))[1];
1644 my $ifile = (split(' ',$1))[0];
1645 $install_list = $install_list . " -cp $1\n";
1646 $ifile =~ s/.*\///g;
1647 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1654 closedir(DIRHANDLE);
1658 # modes need to be compiled in too
1659 $all_core = $all_core . "modes/modeclasses.a";
1661 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1663 my $libraryext = "";
1664 my $binary_rule = "";
1666 if ($config{IS_DARWIN} eq "YES")
1668 $libraryext = "dylib";
1669 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd.cpp\n \@../make/run-cc.pl \$(CC) -pipe -dynamic -bind_at_load -L. -o inspircd \$(LDLIBS) inspircd.o "
1674 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1677 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1680 CC = im a cheezeball
1681 CXXFLAGS = -I../include \${FLAGS}
1682 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1683 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1687 my $buildstring = "";
1690 foreach my $cpp (sort keys %filelist)
1694 $objs =~ s/\.cpp$/.o/;
1695 if (exists($extraobjects{$cpp}))
1697 $objs = $objs . " " . $extraobjects{$cpp};
1698 $all_core = $all_core . " " . $extraobjects{$cpp};
1700 if (exists($extrasources{$cpp}))
1702 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1705 $deps = calcdeps("src/$cpp");
1706 if (exists($extrasources{$cpp}))
1708 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1710 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1713 $deps = $deps . $d . " ";
1717 $buildstring = $buildstring . $objs . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1719 if (exists($core_files_list{$cpp}))
1721 # core files are statically linked into the binary and do not require -export-dynamic
1722 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -c $rawcpp\n";
1726 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1729 if (exists($extrabuildlines{$cpp}))
1731 $buildstring = $buildstring . " " . $extrabuildlines{$cpp} . "\n";
1735 print FH "all: inspircd moo\n\n\n";
1737 $deps = calcdeps("src/inspircd.cpp");
1738 print FH "inspircd: inspircd.cpp $deps $all_core\n";
1739 print FH "$binary_rule $all_core\n\n";
1741 print FH $buildstring;
1742 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1744 # close main makefile
1748 # generate a list of .so
1749 foreach my $cmd (@cmdlist) {
1750 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1753 # and now reopen the commands makefile
1754 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1757 CXXFLAGS = -I../../include \${FLAGS}
1764 # now print the command file details.
1765 foreach my $cmd (@cmdlist) {
1767 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
1768 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1774 # Routine to list out the extra/ modules that have been enabled.
1775 # Note: when getting any filenames out and comparing, it's important to lc it if the
1776 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1777 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1778 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1779 sub list_extras () {
1782 my $srcdir = File::Spec->catdir("src", "modules");
1783 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1786 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1787 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1790 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1791 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1794 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1796 EXTRA: for my $extra (@extras) {
1797 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1798 next if ($extra eq '.svn');
1799 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1800 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1801 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1802 if (-l $abs_source) {
1803 # Symlink, is it in the right place?
1804 my $targ = readlink($abs_source);
1805 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1806 if ($abs_targ eq $abs_extra) {
1807 $extras{$extra} = "\e[32;1menabled\e[0m";
1809 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1811 } elsif (-e $abs_source) {
1812 my ($devext, $inoext) = stat($abs_extra);
1813 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1815 if ($devsrc == $devext && $inosrc == $inoext) {
1816 $extras{$extra} = "\e[32;1menabled\e[0m";
1818 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1821 open my $extfd, "<", $abs_extra;
1822 open my $srcfd, "<", $abs_source;
1824 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1825 $extras{$extra} = "\e[32;1menabled\e[0m";
1827 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1831 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1834 # Now let's add dependency info
1835 for my $extra (keys(%extras)) {
1836 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1837 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1838 my @deps = split / +/, getdependencies($abs_extra);
1839 for my $dep (@deps) {
1840 if (exists($extras{$dep})) {
1841 my $ref = \$extras{$dep}; # Take reference.
1842 if ($$ref !~ m/needed by/) {
1843 # First dependency found.
1844 if ($$ref =~ m/enabled/) {
1845 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1847 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1848 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1851 if ($$ref =~ m/enabled/) {
1852 $$ref .= ", \e[32;1m$extra\e[0m";
1854 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1860 for my $extra (sort {$a cmp $b} keys(%extras)) {
1861 my $text = $extras{$extra};
1862 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1863 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1865 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1868 return keys(%extras) if wantarray; # Can be used by manage_extras.
1871 sub enable_extras (@) {
1873 for my $extra (@extras) {
1874 my $extrapath = "src/modules/extra/$extra";
1875 if (!-e $extrapath) {
1876 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1879 my $source = "src/modules/$extra";
1881 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1884 # Get dependencies, and add them to be processed.
1885 my @deps = split / +/, getdependencies($extrapath);
1886 for my $dep (@deps) {
1887 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1888 if (!-e "src/modules/$dep") {
1889 if (-e "src/modules/extra/$dep") {
1890 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1893 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";
1897 print "Enabling $extra ... \n";
1898 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1902 sub disable_extras (@)
1904 opendir my $dd, "src/modules/extra/";
1905 my @files = readdir($dd);
1908 EXTRA: for my $extra (@extras) {
1909 my $extrapath = "src/modules/extra/$extra";
1910 my $source = "src/modules/$extra";
1911 if (!-e $extrapath) {
1912 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1915 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1916 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";
1919 # Check if anything needs this.
1920 for my $file (@files) {
1921 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1922 # File depends on this extra...
1923 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1924 # And is both enabled and not about to be disabled.
1925 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1926 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1932 print "Disabling $extra ... \n";
1933 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";