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";
708 print "yes (upgrade ffs, freebsd 4 is *way* out of date)\n";
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 $config{USE_SSL} = "n";
872 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
874 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
875 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
877 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
878 if ($config{USE_SSL} eq "y")
880 if ($config{HAS_GNUTLS} eq "y")
882 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
883 if ($config{USE_GNUTLS} eq "y")
885 print "\nUsing GnuTLS SSL module.\n";
889 if ($config{HAS_OPENSSL} eq "y")
891 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
892 if ($config{USE_OPENSSL} eq "y")
894 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
901 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
902 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
908 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
910 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
913 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
915 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
920 if ($config{USE_GNUTLS} eq "y") {
921 unless (-r "src/modules/m_ssl_gnutls.cpp") {
922 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
923 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
928 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
929 print "SSL Certificates Not found, Generating.. \n\n
930 *************************************************************
931 * Generating the Private Key may take some time, go grab a *
932 * Coffee. Even better, to generate some more entropy if it *
933 * is taking a while, open another console and type du / a *
934 * few times and get that HD going :) Then answer the *
935 * Questions which follow. If you are unsure, just hit enter *
936 *************************************************************\n\n";
937 $failed = make_gnutls_cert();
939 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
941 print "\nCertificate generation complete, copying to config directory... ";
942 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
943 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
948 print "SSL Certificates found, skipping.\n\n";
953 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
955 } elsif ($config{USE_OPENSSL} eq "y") {
956 unless (-r "src/modules/m_ssl_openssl.cpp") {
957 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
958 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
964 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
965 print "SSL Certificates Not found, Generating.. \n\n
966 *************************************************************
967 * Generating the certificates may take some time, go grab a *
968 * coffee, or something. *
969 *************************************************************\n\n";
971 print "\nCertificate generation complete, copying to config directory... ";
972 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
973 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
974 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
977 print "SSL Certificates found, skipping.\n\n"
982 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
985 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
986 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
994 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
995 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
996 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
997 print "modules in your config. This configure script has added those modules to the\n";
998 print "build process. For more info please refer to:\n";
999 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
1001 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
1002 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
1003 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";
1006 if ($config{GCCVER} < "3") {
1008 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
1009 GCC 2.x series compilers only had partial (read as broken) C++ support, and
1010 your compile will most likely fail horribly! If you have any problems, do NOT
1011 report them to the bugtracker or forums without first upgrading your compiler
1012 to a newer 3.x or 4.x (or whatever is available currently) version.
1016 ################################################################################
1017 # HELPER FUNCTIONS #
1018 ################################################################################
1020 # Retrieves the .config.cache file, and loads values into the main config hash.
1021 open(CACHE, ".config.cache") or return 0;
1024 # Ignore Blank lines, and comments..
1027 my ($key, $value) = split("=", $_, 2);
1028 $value =~ /^\"(.*)\"$/;
1029 # Do something with data here!
1037 # Dump the contents of %config
1038 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1039 open(FILEHANDLE, ">.config.cache");
1040 foreach my $key (keys %config) {
1041 print FILEHANDLE "$key=\"$config{$key}\"\n";
1047 my ($desc, $hash_key) = @_;
1049 while (!$complete) {
1050 print "In what directory $desc?\n";
1051 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1052 chomp(my $var = <STDIN>);
1054 $var = $config{$hash_key};
1056 if ($var =~ /^\~\/(.+)$/) {
1057 # Convert it to a full path..
1058 $var = resolve_directory($ENV{HOME} . "/" . $1);
1060 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1062 # Assume relative Path was given.. fill in the rest.
1063 $var = $this . "/$var";
1066 $var = resolve_directory($var);
1068 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1069 chomp(my $tmp = <STDIN>);
1070 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1071 # Attempt to Create the Dir..
1074 File::Path::mkpath($var, 0, 0777);
1077 unless (defined($chk) && -d $var) {
1078 print "Unable to create directory. ($var)\n\n";
1083 # They said they don't want to create, and we can't install there.
1088 if (!is_dir($var)) {
1089 # Target exists, but is not a directory.
1090 print "File $var exists, but is not a directory.\n\n";
1094 # Either Dir Exists, or was created fine.
1095 $config{$hash_key} = $var;
1105 # Beware: Linux sets it's own cflags below for some retarded reason
1106 $config{LDLIBS} = "-pthread -lstdc++";
1107 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1108 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1109 $SHARED = "-shared";
1110 $config{MAKEPROG} = "make";
1112 if ($config{OSNAME} =~ /darwin/i) {
1113 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1114 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1115 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1118 if ($config{OSNAME} =~ /OpenBSD/i) {
1119 $config{MAKEPROG} = "gmake";
1120 # apparantly (Dagonet says) that this causes problems, so let's try without it.
1121 # $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1122 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1123 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1124 # if theyre not running this, configure lets the build continue but they probably wont manage to
1125 # compile as this standard version is 2.95.3!
1127 $config{CC} = "eg++";
1128 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1129 chomp($config{GCCMINOR} = `eg++ -dumpversion | cut -c 3`);
1134 if ($config{OSNAME} =~ /Linux/i) {
1135 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1136 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1137 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1138 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1139 $config{MAKEPROG} = "make";
1142 if ($config{OSNAME} =~ /FreeBSD/i) {
1143 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1144 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1147 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1149 # solaris/sunos needs these
1150 # socket = bsd sockets api
1152 # rt = POSIX realtime extensions
1153 # resolv = inet_aton only (why isnt this in nsl?!)
1154 $config{MAKEPROG} = "gmake";
1155 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1159 if($config{OSNAME} =~ /MINGW32/i)
1161 # All code is position-independent on windows
1162 $config{FLAGS} =~ s/-fPIC //;
1166 return $config{OSNAME};
1169 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1172 my($writeheader) = @_;
1174 # First File.. inspircd_config.h
1175 chomp(my $incos = `uname -n -s -r`);
1176 chomp(my $version = `sh src/version.sh`);
1177 chomp(my $revision2 = getrevision());
1178 if ($writeheader == 1)
1180 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1181 open(FILEHANDLE, ">include/inspircd_config.h");
1182 print FILEHANDLE <<EOF;
1183 /* Auto generated by configure, do not modify! */
1184 #ifndef __CONFIGURATION_AUTO__
1185 #define __CONFIGURATION_AUTO__
1187 /* this is for windows support. */
1188 #define CoreExport /**/
1189 #define DllExport /**/
1191 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1192 #define MOD_PATH "$config{MODULE_DIR}"
1193 #define VERSION "$version"
1194 #define REVISION "$revision2"
1195 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1196 #define OPTIMISATION $config{OPTIMITEMP}
1197 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1198 #define SYSTEM "$incos"
1199 #define ENTRYPOINT int main(int argc, char** argv)
1202 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1204 if ($config{OSNAME} =~ /SunOS/i) {
1205 print FILEHANDLE "#define IS_SOLARIS\n";
1207 if ($config{OSNAME} =~ /MINGW32/i) {
1208 print FILEHANDLE "#define IS_MINGW\n";
1210 if ($config{GCCVER} >= 3) {
1211 print FILEHANDLE "#define GCC3\n";
1214 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
1216 ($config{GCCVER} > 4)
1218 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
1220 if ($config{HAS_STRLCPY} eq "true") {
1221 print FILEHANDLE "#define HAS_STRLCPY\n";
1223 if ($config{HAS_STDINT} eq "true") {
1224 print FILEHANDLE "#define HAS_STDINT\n";
1226 if ($config{IPV6} =~ /y/i) {
1227 print FILEHANDLE "#define IPV6\n";
1229 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1230 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1233 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1234 print FILEHANDLE "#define USE_KQUEUE\n";
1235 $se = "socketengine_kqueue";
1238 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1239 print FILEHANDLE "#define USE_EPOLL\n";
1240 $se = "socketengine_epoll";
1243 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1244 print FILEHANDLE "#define USE_PORTS\n";
1245 $se = "socketengine_ports";
1248 # user didn't choose either epoll or select for their OS.
1249 # default them to USE_SELECT (ewwy puke puke)
1251 print "no hi-perf, " . $config{USE_POLL};
1252 if ($config{USE_POLL} eq "y")
1254 print FILEHANDLE "#define USE_POLL\n";
1255 $se = "socketengine_poll";
1259 print FILEHANDLE "#define USE_SELECT\n";
1260 $se = "socketengine_select";
1263 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1269 open(FILEHANDLE, ">include/inspircd_se_config.h");
1270 print FILEHANDLE <<EOF;
1271 /* Auto generated by configure, do not modify or commit to svn! */
1272 #ifndef __CONFIGURATION_SOCKETENGINE__
1273 #define __CONFIGURATION_SOCKETENGINE__
1275 #include "socketengines/$se.h"
1283 # Create a Modules List..
1285 foreach my $i (@modlist)
1287 $modules .= "m_".$i.".so ";
1289 chomp($modules); # Remove Redundant whitespace..
1291 opendir(DIRHANDLE, "src/modules");
1292 foreach my $name2 (sort readdir(DIRHANDLE)) {
1293 if ($name2 =~ /^m_(.+?)$/) {
1294 if (defined(opendir(MDIRHANDLE, "src/modules/$name2"))) {
1295 closedir(MDIRHANDLE);
1296 $modules .= "$name2.so ";
1297 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name2.so\n";
1301 closedir(DIRHANDLE);
1304 # Write all .in files.
1307 my $exe = "inspircd";
1309 # Do this once here, and cache it in the .*.inc files,
1310 # rather than attempting to read src/version.sh from
1311 # compiled code -- we might not have the source to hand.
1312 # Fix for bug#177 by Brain.
1314 chomp($version = `sh ./src/version.sh`);
1315 chomp(my $revision = getrevision());
1316 $version = "$version(r$revision)";
1318 # We can actually parse any file starting with . and ending with .inc,
1319 # but right now we only parse .inspircd.inc to form './inspircd'
1321 print "Writing \e[1;32mMakefiles\e[0m\n";
1322 write_dynamic_modules_makefile();
1323 write_dynamic_makefile();
1325 opendir(DIRHANDLE, $this);
1327 foreach my $name (sort readdir(DIRHANDLE)) {
1328 if ($name =~ /^\.(.+)\.inc$/) {
1331 # Bug #353, omit this on non-darwin
1332 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1334 # All .name.inc files need parsing!
1336 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1337 while (<FILEHANDLE>) {
1342 print "Writing \e[1;32m$file\e[0m ...\n";
1343 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1344 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1345 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1346 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1347 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1348 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1349 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1350 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1351 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1352 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1353 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1354 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1355 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1356 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1357 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1358 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1359 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1360 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1361 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1363 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1364 print FILEHANDLE $tmp;
1367 closedir(DIRHANDLE);
1369 # Make inspircd executable!
1370 chmod 0744, 'inspircd';
1373 sub write_dynamic_modules_makefile {
1374 # Modules Makefile..
1375 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1376 open(FILEHANDLE, ">src/modules/Makefile");
1379 # Module Makefile Header
1381 print FILEHANDLE <<EOF;
1382 ###################################################
1383 # Copyright 2002-2007 The InspIRCd Development Team
1384 # http://www.inspircd.org/wiki/index.php/Credits
1386 # Thanks to Andrew Church <achurch\@achurch.org>
1387 # for assisting with making this work right.
1389 # Automatically Generated by ./configure to add a
1390 # modules please run ./configure -modupdate
1391 ###################################################
1397 if ($config{OSNAME} =~ /darwin/) {
1398 print FILEHANDLE <<EOCHEESE;
1400 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1404 print FILEHANDLE <<EOCHEESE;
1406 PICLDFLAGS = -fPIC -DPIC -shared
1412 # End Module Makefile Header
1415 # Create a Modules List..
1419 foreach my $i (@modlist) {
1421 # Write Entry to the MakeFile
1423 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1424 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1425 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1427 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1430 if (nopedantic("src/modules/m_".$i.".cpp"))
1433 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
1434 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1440 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
1441 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1444 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1445 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1447 # End Write Entry to the MakeFile
1451 opendir(DIRHANDLE, "src/modules");
1452 foreach my $name (sort readdir(DIRHANDLE)) {
1453 if ($name =~ /^m_(.+?)$/) {
1458 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1459 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1460 read_module_directory("src/modules/$name", $name);
1461 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1462 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";
1463 if ($config{IS_DARWIN} eq "YES") {
1464 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1466 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1468 print FILEHANDLE "\n$mfrules\n";
1469 closedir(MDIRHANDLE);
1470 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1474 closedir(DIRHANDLE);
1477 sub read_module_directory {
1478 my ($dpath, $reldpath) = @_;
1480 if (opendir(MDIRHANDLE, $dpath) == 0) {
1484 foreach my $fname (sort readdir(MDIRHANDLE)) {
1485 if ($fname =~ /\.cpp$/) {
1486 my $cmflags = getcompilerflags("$dpath/$fname");
1487 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1488 my $deps = getdependencies("$dpath/$fname");
1490 $oname =~ s/\.cpp$/.o/g;
1491 $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";
1492 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1493 $mobjs = $mobjs . " $reldpath/$oname";
1496 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1497 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1504 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1505 # dependencies which are not relevent in C++.
1509 open (CPP, "<$file") or die("Can't open $file for reading!");
1514 foreach my $d (@ignoredeps)
1520 foreach my $dep (@immutabledeps)
1522 $immutable = $immutable . "../include/$dep ";
1524 $immutable =~ s/ $//g;
1526 while (defined(my $line = <CPP>))
1529 if ($line =~ /#include "(.+\.h)"/)
1531 if (!exists($dupe{$1}))
1533 $retlist = $retlist . "../include/$1 ";
1539 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1542 sub write_dynamic_makefile
1546 my %existing_install_list = ();
1547 my %core_files_list = ();
1549 opendir(DIRHANDLE, "src/commands");
1550 foreach my $name (sort readdir(DIRHANDLE))
1552 if ($name =~ /^cmd_(.+)\.cpp$/)
1554 $cmdlist[$i++] = $1;
1555 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1556 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1559 closedir(DIRHANDLE);
1563 $config{USE_EPOLL} = 0;
1567 $config{USE_KQUEUE} = 0;
1571 $config{USE_PORTS} = 0;
1574 # formerly generated below this foreach, now it's not! magic.
1577 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1579 print "Scanning \e[1;32m$dir\e[0m for core files ";
1580 opendir(DIRHANDLE, $dir);
1581 foreach my $name (sort readdir(DIRHANDLE))
1583 if ($name =~ /\.cpp$/)
1585 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1587 while (defined(my $line = <CPP>))
1590 if ($line =~ /\/\* \$Core \*\//i)
1593 $sname =~ s/\.cpp$/.o/;
1595 # append it to list to be built
1596 $all_core = $all_core . $sname . " ";
1597 $filelist{$name} = $sname;
1599 # mark it as a core file, so it won't get shared object cflags
1600 if (!exists($core_files_list{$name}))
1602 $core_files_list{$name} = 1;
1605 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1607 $specialdeps{$name} = $1;
1609 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1611 $extraobjects{$name} = $1;
1613 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1615 $extrabuildlines{$name} = $1;
1617 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1619 $extrasources{$name} = $1;
1621 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1623 if (defined $config{$1})
1625 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1628 while (defined($line = <CPP>))
1631 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1632 last if ($line =~ /\/\* \$EndIf \*\//i);
1637 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1639 if (!exists($existing_install_list{$1}))
1641 $existing_install_list{$1} = 1;
1642 my $idir = (split(' ',$1))[1];
1643 my $ifile = (split(' ',$1))[0];
1644 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1645 $ifile =~ s/.*\///g;
1646 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1649 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1651 if (!exists($existing_install_list{$1}))
1653 $existing_install_list{$1} = 1;
1654 my $idir = (split(' ',$1))[1];
1655 my $ifile = (split(' ',$1))[0];
1656 $install_list = $install_list . " -cp $1\n";
1657 $ifile =~ s/.*\///g;
1658 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1665 closedir(DIRHANDLE);
1669 # modes need to be compiled in too
1670 $all_core = $all_core . "modes/modeclasses.a";
1672 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1674 my $libraryext = "";
1675 my $binary_rule = "";
1677 if ($config{IS_DARWIN} eq "YES")
1679 $libraryext = "dylib";
1680 $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 "
1685 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1688 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1691 CC = im a cheezeball
1692 CXXFLAGS = -I../include \${FLAGS}
1693 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1694 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1698 my $buildstring = "";
1701 foreach my $cpp (sort keys %filelist)
1705 $objs =~ s/\.cpp$/.o/;
1706 if (exists($extraobjects{$cpp}))
1708 $objs = $objs . " " . $extraobjects{$cpp};
1709 $all_core = $all_core . " " . $extraobjects{$cpp};
1711 if (exists($extrasources{$cpp}))
1713 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1716 $deps = calcdeps("src/$cpp");
1717 if (exists($extrasources{$cpp}))
1719 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1721 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1724 $deps = $deps . $d . " ";
1728 $buildstring = $buildstring . $objs . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1730 if (exists($core_files_list{$cpp}))
1732 # core files are statically linked into the binary and do not require -export-dynamic
1733 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -c $rawcpp\n";
1737 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1740 if (exists($extrabuildlines{$cpp}))
1742 $buildstring = $buildstring . " " . $extrabuildlines{$cpp} . "\n";
1746 print FH "all: inspircd moo\n\n\n";
1748 $deps = calcdeps("src/inspircd.cpp");
1749 print FH "inspircd: inspircd.cpp $deps $all_core\n";
1750 print FH "$binary_rule $all_core\n\n";
1752 print FH $buildstring;
1753 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1755 # close main makefile
1759 # generate a list of .so
1760 foreach my $cmd (@cmdlist) {
1761 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1764 # and now reopen the commands makefile
1765 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1768 CXXFLAGS = -I../../include \${FLAGS}
1775 # now print the command file details.
1776 foreach my $cmd (@cmdlist) {
1778 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
1779 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1785 # Routine to list out the extra/ modules that have been enabled.
1786 # Note: when getting any filenames out and comparing, it's important to lc it if the
1787 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1788 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1789 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1790 sub list_extras () {
1793 my $srcdir = File::Spec->catdir("src", "modules");
1794 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1797 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1798 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1801 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1802 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1805 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1807 EXTRA: for my $extra (@extras) {
1808 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1809 next if ($extra eq '.svn');
1810 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1811 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1812 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1813 if (-l $abs_source) {
1814 # Symlink, is it in the right place?
1815 my $targ = readlink($abs_source);
1816 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1817 if ($abs_targ eq $abs_extra) {
1818 $extras{$extra} = "\e[32;1menabled\e[0m";
1820 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1822 } elsif (-e $abs_source) {
1823 my ($devext, $inoext) = stat($abs_extra);
1824 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1826 if ($devsrc == $devext && $inosrc == $inoext) {
1827 $extras{$extra} = "\e[32;1menabled\e[0m";
1829 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1832 open my $extfd, "<", $abs_extra;
1833 open my $srcfd, "<", $abs_source;
1835 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1836 $extras{$extra} = "\e[32;1menabled\e[0m";
1838 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1842 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1845 # Now let's add dependency info
1846 for my $extra (keys(%extras)) {
1847 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1848 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1849 my @deps = split / +/, getdependencies($abs_extra);
1850 for my $dep (@deps) {
1851 if (exists($extras{$dep})) {
1852 my $ref = \$extras{$dep}; # Take reference.
1853 if ($$ref !~ m/needed by/) {
1854 # First dependency found.
1855 if ($$ref =~ m/enabled/) {
1856 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1858 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1859 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1862 if ($$ref =~ m/enabled/) {
1863 $$ref .= ", \e[32;1m$extra\e[0m";
1865 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1871 for my $extra (sort {$a cmp $b} keys(%extras)) {
1872 my $text = $extras{$extra};
1873 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1874 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1876 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1879 return keys(%extras) if wantarray; # Can be used by manage_extras.
1882 sub enable_extras (@) {
1884 for my $extra (@extras) {
1885 my $extrapath = "src/modules/extra/$extra";
1886 if (!-e $extrapath) {
1887 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1890 my $source = "src/modules/$extra";
1892 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1895 # Get dependencies, and add them to be processed.
1896 my @deps = split / +/, getdependencies($extrapath);
1897 for my $dep (@deps) {
1898 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1899 if (!-e "src/modules/$dep") {
1900 if (-e "src/modules/extra/$dep") {
1901 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1904 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";
1908 print "Enabling $extra ... \n";
1909 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1913 sub disable_extras (@)
1915 opendir my $dd, "src/modules/extra/";
1916 my @files = readdir($dd);
1919 EXTRA: for my $extra (@extras) {
1920 my $extrapath = "src/modules/extra/$extra";
1921 my $source = "src/modules/$extra";
1922 if (!-e $extrapath) {
1923 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1926 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1927 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";
1930 # Check if anything needs this.
1931 for my $file (@files) {
1932 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1933 # File depends on this extra...
1934 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1935 # And is both enabled and not about to be disabled.
1936 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1937 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1943 print "Disabling $extra ... \n";
1944 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";