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;
33 # Utility functions for our buildsystem
37 use make::opensslcert;
39 ###############################################################################################
43 ###############################################################################################
45 # If you wish to ignore a dependency throughout the entire core, add it here.
48 "inspircd_win32wrapper.h", # windows has its own configure program
51 # If you wish for all files in the entire core to have a given dependency, insert it here.
52 # You should keep this to an absolute minimum to avoid rebuilds that are not neccessary.
54 our @immutabledeps = (
55 "inspircd_config.h", # auto re-generated by configure
59 ###############################################################################################
61 # NON-EDITABLE VARIABLES
63 ###############################################################################################
65 # List of commands that make up 'make install' and 'make deinstall'
67 our $install_list = "";
68 our $uninstall_list = "";
70 # This is a list of all files in the core. Each cpp file is mapped to a shared object file,
71 # whos file extension is omitted (these can vary from system to system). Auto detected by
72 # scanning the src/*.cpp files for files containing /* $Core */ identifiers.
76 # If you wish for a file to have special dependencies in the makefile, add an entry here.
77 # Auto populated by /* $ExtraDeps: */ instruction
79 our %specialdeps = ();
81 # If you wish for a file to have extra make lines (in between the compile and link steps)
82 # then insert them here.
83 # Auto populated by /* $ExtraBuild: */ instruction
85 our %extrabuildlines = ();
87 # If you wish for a file to be linked against extra objects or arctives, insert them here.
88 # Auto populated by /* $ExtraObjects: */ instruction
90 our %extraobjects = ();
92 # If you wish to compile extra cpp sources into an object, define them here.
93 # NOTE: Certain cpp files such as the socket engines have a value auto calculated
94 # for this table so that their derived class is built.
95 # Auto populated by /* $ExtraSources: */ instruction
97 our %extrasources = ();
99 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
100 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
101 $opt_ipv6, $opt_ipv6links, $opt_noipv6links, $opt_maxbuf, $opt_disable_debug,
104 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
109 sub enable_extras (@);
111 sub disable_extras (@);
113 my @opt_enableextras;
114 my @opt_disableextras;
117 'enable-gnutls' => \$opt_use_gnutls,
118 'rebuild' => \$opt_rebuild,
119 'enable-openssl' => \$opt_use_openssl,
120 'disable-interactive' => \$opt_nointeractive,
121 'enable-ports' => \$opt_ports,
122 'enable-epoll' => \$opt_epoll,
123 'enable-kqueue' => \$opt_kqueue,
124 'disable-ports' => \$opt_noports,
125 'disable-epoll' => \$opt_noepoll,
126 'disable-kqueue' => \$opt_nokqueue,
127 'enable-ipv6' => \$opt_ipv6,
128 'enable-remote-ipv6' => \$opt_ipv6links,
129 'disable-remote-ipv6' => \$opt_noipv6links,
130 'with-cc=s' => \$opt_cc,
131 'with-maxbuf=i' => \$opt_maxbuf,
132 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
133 'prefix=s' => \$opt_base_dir,
134 'config-dir=s' => \$opt_config_dir,
135 'module-dir=s' => \$opt_module_dir,
136 'binary-dir=s' => \$opt_binary_dir,
137 'library-dir=s' => \$opt_library_dir,
138 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
139 'help' => sub { showhelp(); },
140 'modupdate' => sub { modupdate(); },
141 'update' => sub { update(); },
142 'svnupdate' => sub { svnupdate(); },
143 'clean' => sub { clean(); },
144 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
145 'enable-extras=s@' => \@opt_enableextras, # ^
146 'disable-extras=s@' => \@opt_disableextras, # ^
149 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
150 @opt_enableextras = split /,/, join(',', @opt_enableextras);
151 @opt_disableextras = split /,/, join(',', @opt_disableextras);
152 enable_extras(@opt_enableextras);
153 disable_extras(@opt_disableextras);
155 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
156 print "Run $0 -modupdate after you've done this to update the makefiles.\n";
160 our $non_interactive = (
161 (defined $opt_library_dir) ||
162 (defined $opt_base_dir) ||
163 (defined $opt_config_dir) ||
164 (defined $opt_module_dir) ||
165 (defined $opt_base_dir) ||
166 (defined $opt_binary_dir) ||
167 (defined $opt_nointeractive) ||
169 (defined $opt_ipv6) ||
170 (defined $opt_ipv6links) ||
171 (defined $opt_noipv6links) ||
172 (defined $opt_kqueue) ||
173 (defined $opt_epoll) ||
174 (defined $opt_ports) ||
175 (defined $opt_use_openssl) ||
176 (defined $opt_nokqueue) ||
177 (defined $opt_noepoll) ||
178 (defined $opt_noports) ||
179 (defined $opt_maxbuf) ||
180 (defined $opt_use_gnutls) ||
181 (defined $opt_freebsd_port)
183 our $interactive = !$non_interactive;
185 chomp(our $topdir = getcwd());
186 our $this = resolve_directory($topdir); # PWD, Regardless.
187 our @modlist = (); # Declare for Module List..
188 our %config = (); # Initiate Configuration Hash..
189 $config{ME} = resolve_directory($topdir); # Present Working Directory
191 $config{BASE_DIR} = $config{ME};
193 if (defined $opt_base_dir)
195 $config{BASE_DIR} = $opt_base_dir;
198 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
199 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
200 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
201 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
203 if (defined $opt_config_dir)
205 $config{CONFIG_DIR} = $opt_config_dir;
207 if (defined $opt_module_dir)
209 $config{MODULE_DIR} = $opt_module_dir;
211 if (defined $opt_binary_dir)
213 $config{BINARY_DIR} = $opt_binary_dir;
215 if (defined $opt_library_dir)
217 $config{LIBRARY_DIR} = $opt_library_dir;
219 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
221 if (defined $opt_freebsd_port)
223 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
224 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
225 $config{USE_FREEBSD_BASE_SSL} = "n";
229 if ($^O eq "freebsd")
231 # default: use base ssl
232 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
233 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
237 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
238 $config{HAS_OPENSSL_PORT} = "";
242 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
243 chomp(our $openssl_ver = $config{HAS_OPENSSL});
244 $config{USE_GNUTLS} = "n";
245 if (defined $opt_use_gnutls)
247 $config{USE_GNUTLS} = "y"; # Use gnutls.
249 $config{USE_OPENSSL} = "n"; # Use openssl.
250 if (defined $opt_use_openssl)
252 $config{USE_OPENSSL} = "y";
255 # no, let's not change these.
256 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
257 if (!defined $opt_disable_debug)
259 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
263 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
266 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
267 $config{HAS_STDINT} = "false"; # stdint.h check
268 $config{USE_KQUEUE} = "y"; # kqueue enabled
269 if (defined $opt_kqueue)
271 $config{USE_KQUEUE} = "y";
273 if (defined $opt_nokqueue)
275 $config{USE_KQUEUE} = "n";
277 $config{USE_POLL} = "y"; # poll enabled
278 $config{USE_EPOLL} = "y"; # epoll enabled
279 if (defined $opt_epoll)
281 $config{USE_EPOLL} = "y";
283 if (defined $opt_noepoll)
285 $config{USE_EPOLL} = "n";
287 $config{USE_PORTS} = "y"; # epoll enabled
288 if (defined $opt_ports)
290 $config{USE_PORTS} = "y";
292 if (defined $opt_noports)
294 $config{USE_PORTS} = "n";
296 $config{IPV6} = "n"; # IPv6 support (experimental)
297 if (defined $opt_ipv6)
301 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
302 if (defined $opt_ipv6links)
304 $config{SUPPORT_IP6LINKS} = "y";
306 if (defined $opt_noipv6links)
308 $config{SUPPORT_IP6LINKS} = "n";
310 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
311 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
312 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
313 $config{OSNAME} = $^O; # Operating System Name
314 $config{IS_DARWIN} = "NO"; # Is OSX?
315 $config{STARTSCRIPT} = "inspircd"; # start script?
316 $config{DESTINATION} = "BASE"; # Is target path.
317 $config{EXTRA_DIR} = ""; # Is empty.
318 if ($config{OSNAME} =~ /darwin/i)
320 $config{IS_DARWIN} = "YES";
321 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
322 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
323 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
325 $config{CC} = "g++"; # C++ compiler
328 $config{CC} = $opt_cc;
330 our $exec = $config{CC} . " -dumpversion | cut -c 1";
331 chomp($config{GCCVER} = `$exec`); # Major GCC Version
332 $exec = $config{CC} . " -dumpversion | cut -c 3";
333 chomp($config{GCCMINOR} = `$exec`);
334 $config{MAKEORDER} = "ircd mods"; # build order
335 $config{MAXBUF} = "512"; # Max buffer size
337 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
338 $config{HAS_OPENSSL} = $1;
340 $config{HAS_OPENSSL} = "";
343 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
344 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
348 # Get and Set some important vars..
353 unlink(".config.cache");
356 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
361 chomp($topdir = getcwd());
362 $this = resolve_directory($topdir); # PWD, Regardless.
364 # Does the cache file exist?
366 # No, No it doesn't.. *BASH*
367 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
370 # We've Loaded the cache file and all our variables..
371 print "Updating files...\n";
373 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
375 print "Disabling debug information (-g).\n";
376 $config{OPTIMISATI} = "";
379 $has_epoll = $config{HAS_EPOLL};
380 $has_ports = $config{HAS_PORTS};
381 $has_kqueue = $config{HAS_KQUEUE};
390 print "Configure update failed: $@\n";
398 chomp($topdir = getcwd());
399 $this = resolve_directory($topdir); # PWD, Regardless.
401 # Does the cache file exist?
403 # No, No it doesn't.. *BASH*
404 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
407 # We've Loaded the cache file and all our variables..
408 print "Updating files...\n";
410 $has_epoll = $config{HAS_EPOLL};
411 $has_ports = $config{HAS_PORTS};
412 $has_kqueue = $config{HAS_KQUEUE};
421 print "Module update failed: $@\n";
431 open(FH,"<.svn/entries") or $fail = 1;
433 print "This is not an SVN copy of InspIRCd.\n";
440 open my $fd, "-|", "svn update";
441 my $configurechanged = 0; # Needs ./configure -update
442 my $coredirchanged = 0; # Needs ./configure -update
443 my $moduledirchanged = 0; # Needs ./configure -modupdate
444 my $rootincchanged = 0;
446 while (defined(my $line = <$fd>))
450 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
451 ($action, $file) = ($1, $2);
454 push @conflicted, $file;
455 if ($file eq "configure")
457 $configurechanged = 1;
459 elsif ($file =~ m#^src/modules#)
461 $moduledirchanged = 1;
463 elsif ($file =~ m#^src/#)
467 elsif ($file =~ m/^\..*\.inc$/)
472 elsif ($action eq "U" || $action eq "G")
474 if ($file eq "configure")
476 $configurechanged = 1;
478 elsif ($file =~ m/^\..*\.inc$/)
483 elsif ($action eq "A" || $action eq "D")
485 if ($file =~ m#^src/modules#)
487 $moduledirchanged = 1;
489 elsif ($file =~ m#^src/#)
495 unless (close $fd) # close() waits for exit and returns false if the command failed
499 print STDERR "Problem updating from SVN, please check above for errors\n";
503 print STDERR "Failed to run SVN: $!\n";
507 if (scalar(@conflicted) > 0)
509 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
510 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate\n", (($coredirchanged || $configurechanged) ? "" : "mod");
511 print "Conflicted files: " . join ", ", @conflicted . "\n";
514 if ($configurechanged || $coredirchanged)
516 system("perl configure -update");
518 elsif ($moduledirchanged || $rootincchanged)
520 system("perl configure -modupdate");
524 print "No need to update Makefiles.\n";
526 if (defined $opt_rebuild) {
527 system("make install");
532 print "Running non-interactive configure...\n" unless $interactive;
533 print "Checking for cache from previous configure... ";
534 print ((!getcache()) ? "not found\n" : "found\n");
535 print "Checking operating system version... ";
536 print getosflags() . "\n";
538 printf "Checking if stdint.h exists... ";
539 $config{HAS_STDINT} = "true";
541 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
542 if ($config{HAS_STDINT} eq "true") {
545 print "yes\n" if $config{HAS_STDINT} eq "true";
546 print "no\n" if $config{HAS_STDINT} eq "false";
548 printf "Checking if strlcpy exists... ";
549 # Perform the strlcpy() test..
550 $config{HAS_STRLCPY} = "false";
552 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
554 while (defined(my $line = <STRLCPY>)) {
556 # try and find the delcaration of:
557 # size_t strlcpy(...)
558 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
559 $config{HAS_STRLCPY} = "true";
564 print "yes\n" if $config{HAS_STRLCPY} eq "true";
565 print "no\n" if $config{HAS_STRLCPY} eq "false";
567 printf "Checking if kqueue exists... ";
570 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
572 while (defined(my $line = <KQUEUE>)) {
574 # try and find the delcaration of:
576 if ($line =~ /int(\0x9|\s)+kqueue/) {
582 print "yes\n" if $has_kqueue == 1;
583 print "no\n" if $has_kqueue == 0;
585 printf "Checking if epoll exists... ";
588 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
594 my $kernel = `uname -r`;
596 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
601 # Suggestion from nenolod, weed out odd systems which have glibc built
602 # against 2.4 kernels (ick)
603 my $kernel_arch = `uname -p`;
607 if ($kernel_arch =~ /x86_64/) {
608 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
611 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
615 while (defined(my $line = <FH>))
618 if ($line =~ /GNU C Library .* version (.*?) /)
621 $libcv =~ /(\d+\.\d+)/;
624 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
627 # Fix for some retarded libc builds, strip off >> and << etc.
628 $kernelv =~ /(\d+\.\d+)/;
636 printf "libc too old: $libcv... ";
641 printf "libc built against older kernel $kernelv... ";
646 print "yes\n" if $has_epoll == 1;
647 print "no\n" if $has_epoll == 0;
649 printf "Checking if Solaris I/O completion ports are available... ";
651 our $system = `uname -s`;
653 $has_ports = 1 if ($system eq "SunOS");
656 my $kernel = `uname -r`;
658 if (($kernel !~ /^5\.1./)) {
662 print "yes\n" if $has_ports == 1;
663 print "no\n" if $has_ports == 0;
665 $config{HAS_EPOLL} = $has_epoll;
666 $config{HAS_KQUEUE} = $has_kqueue;
668 printf "Checking for libgnutls... ";
669 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
670 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
672 $config{HAS_GNUTLS} = "y";
675 $config{HAS_GNUTLS} = "n";
679 $config{HAS_GNUTLS} = "n";
682 printf "Checking for openssl... ";
683 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
684 if (defined($openssl_ver) && ($openssl_ver ne "")) {
686 $config{HAS_OPENSSL} = "y";
689 $config{HAS_OPENSSL} = "n";
693 $config{HAS_OPENSSL} = "n";
696 printf "Checking if you are running an ancient, unsupported OS... ";
697 if ($config{OSNAME} =~ /FreeBSD/i)
699 my $version = `uname -r`;
700 if ($version =~ /^4\./)
702 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
705 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
706 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
707 print "yes (upgrade ffs, freebsd 4 is *way* out of date)\n";
711 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
717 print "no ($version)\n";
723 print "no ($config{OSNAME})\n";
726 ################################################################################
727 # BEGIN INTERACTIVE PART #
728 ################################################################################
733 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
736 my $rev = getrevision();
737 # Display Introduction Message..
739 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
740 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
742 *** If you are unsure of any of these values, leave it blank for ***
743 *** standard settings that will work, and your server will run ***
744 *** using them. Please consult your IRC network admin if in doubt. ***
746 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
747 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
748 dir, otherwise you won't have a config file!
750 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
751 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
754 print " (Non-SVN build)";
758 $config{CHANGE_COMPILER} = "n";
759 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";
761 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
762 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
763 should NOT be used. You should probably specify a newer compiler.\n\n";
764 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
765 if ($config{CHANGE_COMPILER} =~ /y/i) {
766 print "What command do you want to use to invoke your compiler?\n";
767 print "[\e[1;32m$config{CC}\e[0m] -> ";
768 chomp($config{CC} = <STDIN>);
769 if ($config{CC} eq "") {
772 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
774 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
775 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
776 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
777 if ($config{GCCVER} < 3) {
778 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
782 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
789 # Directory Settings..
790 my $tmpbase = $config{BASE_DIR};
791 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
792 if ($tmpbase ne $config{BASE_DIR}) {
793 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
794 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
795 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
796 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
799 dir_check("are the configuration files", "CONFIG_DIR");
800 dir_check("are the modules to be compiled to", "MODULE_DIR");
801 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
802 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
804 my $chose_hiperf = 0;
806 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?");
808 if ($config{USE_KQUEUE} eq "y") {
813 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?");
815 if ($config{USE_EPOLL} eq "y") {
820 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?");
822 if ($config{USE_PORTS} eq "y") {
827 if (!$chose_hiperf) {
828 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");
829 if ($config{USE_POLL} ne "y")
831 print "No high-performance socket engines are available, or you chose\n";
832 print "not to enable one. Defaulting to select() engine.\n\n";
836 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
839 if ($config{IPV6} eq "y") {
840 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";
841 $config{SUPPORT_IP6LINKS} = "y";
843 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?");
847 $config{USE_FREEBSD_BASE_SSL} = "n";
848 $config{USE_FREEBSD_PORTS_SSL} = "n";
849 if ($config{HAS_OPENSSL_PORT} ne "")
851 $config{USE_FREEBSD_PORTS_SSL} = "y";
852 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
853 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";
854 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
856 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
858 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
860 # update to port version
861 $openssl_ver = $config{HAS_OPENSSL_PORT};
866 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
869 $config{USE_SSL} = "n";
871 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
873 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
874 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
876 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
877 if ($config{USE_SSL} eq "y")
879 if ($config{HAS_GNUTLS} eq "y")
881 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
882 if ($config{USE_GNUTLS} eq "y")
884 print "\nUsing GnuTLS SSL module.\n";
888 if ($config{HAS_OPENSSL} eq "y")
890 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
891 if ($config{USE_OPENSSL} eq "y")
893 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
900 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
901 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
907 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
909 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
912 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
914 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
919 if ($config{USE_GNUTLS} eq "y") {
920 unless (-r "src/modules/m_ssl_gnutls.cpp") {
921 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
922 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
927 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
928 print "SSL Certificates Not found, Generating.. \n\n
929 *************************************************************
930 * Generating the Private Key may take some time, go grab a *
931 * Coffee. Even better, to generate some more entropy if it *
932 * is taking a while, open another console and type du / a *
933 * few times and get that HD going :) Then answer the *
934 * Questions which follow. If you are unsure, just hit enter *
935 *************************************************************\n\n";
936 $failed = make_gnutls_cert();
938 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
940 print "\nCertificate generation complete, copying to config directory... ";
941 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
942 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
947 print "SSL Certificates found, skipping.\n\n";
952 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
954 } elsif ($config{USE_OPENSSL} eq "y") {
955 unless (-r "src/modules/m_ssl_openssl.cpp") {
956 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
957 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
963 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
964 print "SSL Certificates Not found, Generating.. \n\n
965 *************************************************************
966 * Generating the certificates may take some time, go grab a *
967 * coffee, or something. *
968 *************************************************************\n\n";
970 print "\nCertificate generation complete, copying to config directory... ";
971 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
972 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
973 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
976 print "SSL Certificates found, skipping.\n\n"
981 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
984 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
985 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
993 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
994 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
995 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
996 print "modules in your config. This configure script has added those modules to the\n";
997 print "build process. For more info please refer to:\n";
998 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
1000 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
1001 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
1002 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";
1005 if ($config{GCCVER} < "3") {
1007 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
1008 GCC 2.x series compilers only had partial (read as broken) C++ support, and
1009 your compile will most likely fail horribly! If you have any problems, do NOT
1010 report them to the bugtracker or forums without first upgrading your compiler
1011 to a newer 3.x or 4.x (or whatever is available currently) version.
1015 ################################################################################
1016 # HELPER FUNCTIONS #
1017 ################################################################################
1019 # Retrieves the .config.cache file, and loads values into the main config hash.
1020 open(CACHE, ".config.cache") or return 0;
1023 # Ignore Blank lines, and comments..
1026 my ($key, $value) = split("=", $_, 2);
1027 $value =~ /^\"(.*)\"$/;
1028 # Do something with data here!
1036 # Dump the contents of %config
1037 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1038 open(FILEHANDLE, ">.config.cache");
1039 foreach my $key (keys %config) {
1040 print FILEHANDLE "$key=\"$config{$key}\"\n";
1046 my ($desc, $hash_key) = @_;
1048 while (!$complete) {
1049 print "In what directory $desc?\n";
1050 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1051 chomp(my $var = <STDIN>);
1053 $var = $config{$hash_key};
1055 if ($var =~ /^\~\/(.+)$/) {
1056 # Convert it to a full path..
1057 $var = resolve_directory($ENV{HOME} . "/" . $1);
1059 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1061 # Assume relative Path was given.. fill in the rest.
1062 $var = $this . "/$var";
1065 $var = resolve_directory($var);
1067 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1068 chomp(my $tmp = <STDIN>);
1069 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1070 # Attempt to Create the Dir..
1073 File::Path::mkpath($var, 0, 0777);
1076 unless (defined($chk) && -d $var) {
1077 print "Unable to create directory. ($var)\n\n";
1082 # They said they don't want to create, and we can't install there.
1087 if (!is_dir($var)) {
1088 # Target exists, but is not a directory.
1089 print "File $var exists, but is not a directory.\n\n";
1093 # Either Dir Exists, or was created fine.
1094 $config{$hash_key} = $var;
1104 # Beware: Linux sets it's own cflags below for some retarded reason
1105 $config{LDLIBS} = "-pthread -lstdc++";
1106 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1107 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1108 $SHARED = "-shared";
1109 $config{MAKEPROG} = "make";
1111 if ($config{OSNAME} =~ /darwin/i) {
1112 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1113 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1114 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1117 if ($config{OSNAME} =~ /OpenBSD/i) {
1118 $config{MAKEPROG} = "gmake";
1119 # apparantly (Dagonet says) that this causes problems, so let's try without it.
1120 # $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1121 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1122 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1123 # if theyre not running this, configure lets the build continue but they probably wont manage to
1124 # compile as this standard version is 2.95.3!
1126 $config{CC} = "eg++";
1127 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1128 chomp($config{GCCMINOR} = `eg++ -dumpversion | cut -c 3`);
1133 if ($config{OSNAME} =~ /Linux/i) {
1134 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1135 # $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1136 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1137 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1138 $config{MAKEPROG} = "make";
1141 if ($config{OSNAME} =~ /FreeBSD/i) {
1142 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1143 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1146 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1148 # solaris/sunos needs these
1149 # socket = bsd sockets api
1151 # rt = POSIX realtime extensions
1152 # resolv = inet_aton only (why isnt this in nsl?!)
1153 $config{MAKEPROG} = "gmake";
1154 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1158 if($config{OSNAME} =~ /MINGW32/i)
1160 # All code is position-independent on windows
1161 $config{FLAGS} =~ s/-fPIC //;
1165 return $config{OSNAME};
1168 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1171 my($writeheader) = @_;
1173 # First File.. inspircd_config.h
1174 chomp(my $incos = `uname -n -s -r`);
1175 chomp(my $version = `sh src/version.sh`);
1176 chomp(my $revision2 = getrevision());
1177 if ($writeheader == 1)
1179 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1180 open(FILEHANDLE, ">include/inspircd_config.h");
1181 print FILEHANDLE <<EOF;
1182 /* Auto generated by configure, do not modify! */
1183 #ifndef __CONFIGURATION_AUTO__
1184 #define __CONFIGURATION_AUTO__
1186 /* this is for windows support. */
1187 #define CoreExport /**/
1188 #define DllExport /**/
1190 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1191 #define MOD_PATH "$config{MODULE_DIR}"
1192 #define VERSION "$version"
1193 #define REVISION "$revision2"
1194 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1195 #define OPTIMISATION $config{OPTIMITEMP}
1196 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1197 #define SYSTEM "$incos"
1198 #define ENTRYPOINT int main(int argc, char** argv)
1201 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1203 if ($config{OSNAME} =~ /SunOS/i) {
1204 print FILEHANDLE "#define IS_SOLARIS\n";
1206 if ($config{OSNAME} =~ /MINGW32/i) {
1207 print FILEHANDLE "#define IS_MINGW\n";
1209 if ($config{GCCVER} >= 3) {
1210 print FILEHANDLE "#define GCC3\n";
1213 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
1215 ($config{GCCVER} > 4)
1217 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
1219 if ($config{HAS_STRLCPY} eq "true") {
1220 print FILEHANDLE "#define HAS_STRLCPY\n";
1222 if ($config{HAS_STDINT} eq "true") {
1223 print FILEHANDLE "#define HAS_STDINT\n";
1225 if ($config{IPV6} =~ /y/i) {
1226 print FILEHANDLE "#define IPV6\n";
1228 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1229 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1232 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1233 print FILEHANDLE "#define USE_KQUEUE\n";
1234 $se = "socketengine_kqueue";
1237 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1238 print FILEHANDLE "#define USE_EPOLL\n";
1239 $se = "socketengine_epoll";
1242 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1243 print FILEHANDLE "#define USE_PORTS\n";
1244 $se = "socketengine_ports";
1247 # user didn't choose either epoll or select for their OS.
1248 # default them to USE_SELECT (ewwy puke puke)
1250 print "no hi-perf, " . $config{USE_POLL};
1251 if ($config{USE_POLL} eq "y")
1253 print FILEHANDLE "#define USE_POLL\n";
1254 $se = "socketengine_poll";
1258 print FILEHANDLE "#define USE_SELECT\n";
1259 $se = "socketengine_select";
1262 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1268 open(FILEHANDLE, ">include/inspircd_se_config.h");
1269 print FILEHANDLE <<EOF;
1270 /* Auto generated by configure, do not modify or commit to svn! */
1271 #ifndef __CONFIGURATION_SOCKETENGINE__
1272 #define __CONFIGURATION_SOCKETENGINE__
1274 #include "socketengines/$se.h"
1282 # Create a Modules List..
1284 foreach my $i (@modlist)
1286 $modules .= "m_".$i.".so ";
1288 chomp($modules); # Remove Redundant whitespace..
1290 opendir(DIRHANDLE, "src/modules");
1291 foreach my $name2 (sort readdir(DIRHANDLE)) {
1292 if ($name2 =~ /^m_(.+?)$/) {
1293 if (defined(opendir(MDIRHANDLE, "src/modules/$name2"))) {
1294 closedir(MDIRHANDLE);
1295 $modules .= "$name2.so ";
1296 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name2.so\n";
1300 closedir(DIRHANDLE);
1303 # Write all .in files.
1306 my $exe = "inspircd";
1308 # Do this once here, and cache it in the .*.inc files,
1309 # rather than attempting to read src/version.sh from
1310 # compiled code -- we might not have the source to hand.
1311 # Fix for bug#177 by Brain.
1313 chomp($version = `sh ./src/version.sh`);
1314 chomp(my $revision = getrevision());
1315 $version = "$version(r$revision)";
1317 # We can actually parse any file starting with . and ending with .inc,
1318 # but right now we only parse .inspircd.inc to form './inspircd'
1320 print "Writing \e[1;32mMakefiles\e[0m\n";
1321 write_dynamic_modules_makefile();
1322 write_dynamic_makefile();
1324 opendir(DIRHANDLE, $this);
1326 foreach my $name (sort readdir(DIRHANDLE)) {
1327 if ($name =~ /^\.(.+)\.inc$/) {
1330 # Bug #353, omit this on non-darwin
1331 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1333 # All .name.inc files need parsing!
1335 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1336 while (<FILEHANDLE>) {
1341 print "Writing \e[1;32m$file\e[0m ...\n";
1342 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1343 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1344 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1345 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1346 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1347 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1348 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1349 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1350 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1351 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1352 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1353 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1354 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1355 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1356 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1357 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1358 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1359 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1360 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1362 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1363 print FILEHANDLE $tmp;
1366 closedir(DIRHANDLE);
1368 # Make inspircd executable!
1369 chmod 0744, 'inspircd';
1372 sub write_dynamic_modules_makefile {
1373 # Modules Makefile..
1374 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1375 open(FILEHANDLE, ">src/modules/Makefile");
1378 # Module Makefile Header
1380 print FILEHANDLE <<EOF;
1381 ###################################################
1382 # Copyright 2002-2007 The InspIRCd Development Team
1383 # http://www.inspircd.org/wiki/index.php/Credits
1385 # Thanks to Andrew Church <achurch\@achurch.org>
1386 # for assisting with making this work right.
1388 # Automatically Generated by ./configure to add a
1389 # modules please run ./configure -modupdate
1390 ###################################################
1396 if ($config{OSNAME} =~ /darwin/) {
1397 print FILEHANDLE <<EOCHEESE;
1399 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1403 print FILEHANDLE <<EOCHEESE;
1405 PICLDFLAGS = -fPIC -DPIC -shared
1411 # End Module Makefile Header
1414 # Create a Modules List..
1418 foreach my $i (@modlist) {
1420 # Write Entry to the MakeFile
1422 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1423 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1424 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1426 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1429 if (nopedantic("src/modules/m_".$i.".cpp"))
1432 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
1433 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1439 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
1440 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1443 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1444 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1446 # End Write Entry to the MakeFile
1450 opendir(DIRHANDLE, "src/modules");
1451 foreach my $name (sort readdir(DIRHANDLE)) {
1452 if ($name =~ /^m_(.+?)$/) {
1457 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1458 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1459 read_module_directory("src/modules/$name", $name);
1460 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1461 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";
1462 if ($config{IS_DARWIN} eq "YES") {
1463 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1465 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1467 print FILEHANDLE "\n$mfrules\n";
1468 closedir(MDIRHANDLE);
1469 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1473 closedir(DIRHANDLE);
1476 sub read_module_directory {
1477 my ($dpath, $reldpath) = @_;
1479 if (opendir(MDIRHANDLE, $dpath) == 0) {
1483 foreach my $fname (sort readdir(MDIRHANDLE)) {
1484 if ($fname =~ /\.cpp$/) {
1485 my $cmflags = getcompilerflags("$dpath/$fname");
1486 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1487 my $deps = getdependencies("$dpath/$fname");
1489 $oname =~ s/\.cpp$/.o/g;
1490 $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";
1491 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1492 $mobjs = $mobjs . " $reldpath/$oname";
1495 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1496 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1503 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1504 # dependencies which are not relevent in C++.
1508 open (CPP, "<$file") or die("Can't open $file for reading!");
1513 foreach my $d (@ignoredeps)
1519 foreach my $dep (@immutabledeps)
1521 $immutable = $immutable . "../include/$dep ";
1523 $immutable =~ s/ $//g;
1525 while (defined(my $line = <CPP>))
1528 if ($line =~ /#include "(.+\.h)"/)
1530 if (!exists($dupe{$1}))
1532 $retlist = $retlist . "../include/$1 ";
1538 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1541 sub write_dynamic_makefile
1545 my %existing_install_list = ();
1546 my %core_files_list = ();
1548 opendir(DIRHANDLE, "src/commands");
1549 foreach my $name (sort readdir(DIRHANDLE))
1551 if ($name =~ /^cmd_(.+)\.cpp$/)
1553 $cmdlist[$i++] = $1;
1554 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1555 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1558 closedir(DIRHANDLE);
1562 $config{USE_EPOLL} = 0;
1566 $config{USE_KQUEUE} = 0;
1570 $config{USE_PORTS} = 0;
1573 # formerly generated below this foreach, now it's not! magic.
1576 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1578 print "Scanning \e[1;32m$dir\e[0m for core files ";
1579 opendir(DIRHANDLE, $dir);
1580 foreach my $name (sort readdir(DIRHANDLE))
1582 if ($name =~ /\.cpp$/)
1584 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1586 while (defined(my $line = <CPP>))
1589 if ($line =~ /\/\* \$Core \*\//i)
1592 $sname =~ s/\.cpp$/.o/;
1594 # append it to list to be built
1595 $all_core = $all_core . $sname . " ";
1596 $filelist{$name} = $sname;
1598 # mark it as a core file, so it won't get shared object cflags
1599 if (!exists($core_files_list{$name}))
1601 $core_files_list{$name} = 1;
1604 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1606 $specialdeps{$name} = $1;
1608 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1610 $extraobjects{$name} = $1;
1612 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1614 $extrabuildlines{$name} = $1;
1616 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1618 $extrasources{$name} = $1;
1620 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1622 if (defined $config{$1})
1624 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1627 while (defined($line = <CPP>))
1630 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1631 last if ($line =~ /\/\* \$EndIf \*\//i);
1636 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1638 if (!exists($existing_install_list{$1}))
1640 $existing_install_list{$1} = 1;
1641 my $idir = (split(' ',$1))[1];
1642 my $ifile = (split(' ',$1))[0];
1643 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1644 $ifile =~ s/.*\///g;
1645 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1648 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1650 if (!exists($existing_install_list{$1}))
1652 $existing_install_list{$1} = 1;
1653 my $idir = (split(' ',$1))[1];
1654 my $ifile = (split(' ',$1))[0];
1655 $install_list = $install_list . " -cp $1\n";
1656 $ifile =~ s/.*\///g;
1657 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1664 closedir(DIRHANDLE);
1668 # modes need to be compiled in too
1669 $all_core = $all_core . "modes/modeclasses.a";
1671 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1673 my $libraryext = "";
1674 my $binary_rule = "";
1676 if ($config{IS_DARWIN} eq "YES")
1678 $libraryext = "dylib";
1679 $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 "
1684 $binary_rule = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1687 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1690 CC = im a cheezeball
1691 CXXFLAGS = -I../include \${FLAGS}
1692 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1693 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1697 my $buildstring = "";
1700 foreach my $cpp (sort keys %filelist)
1704 $objs =~ s/\.cpp$/.o/;
1705 if (exists($extraobjects{$cpp}))
1707 $objs = $objs . " " . $extraobjects{$cpp};
1708 $all_core = $all_core . " " . $extraobjects{$cpp};
1710 if (exists($extrasources{$cpp}))
1712 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1715 $deps = calcdeps("src/$cpp");
1716 if (exists($extrasources{$cpp}))
1718 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1720 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1723 $deps = $deps . $d . " ";
1727 $buildstring = $buildstring . $objs . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1729 if (exists($core_files_list{$cpp}))
1731 # core files are statically linked into the binary and do not require -export-dynamic
1732 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -c $rawcpp\n";
1736 $buildstring = $buildstring . " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1739 if (exists($extrabuildlines{$cpp}))
1741 $buildstring = $buildstring . " " . $extrabuildlines{$cpp} . "\n";
1745 print FH "all: inspircd moo\n\n\n";
1747 $deps = calcdeps("src/inspircd.cpp");
1748 print FH "inspircd: inspircd.cpp $deps $all_core\n";
1749 print FH "$binary_rule $all_core\n\n";
1751 print FH $buildstring;
1752 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1754 # close main makefile
1758 # generate a list of .so
1759 foreach my $cmd (@cmdlist) {
1760 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1763 # and now reopen the commands makefile
1764 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1767 CXXFLAGS = -I../../include \${FLAGS}
1774 # now print the command file details.
1775 foreach my $cmd (@cmdlist) {
1777 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
1778 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1784 # Routine to list out the extra/ modules that have been enabled.
1785 # Note: when getting any filenames out and comparing, it's important to lc it if the
1786 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1787 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1788 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1789 sub list_extras () {
1792 my $srcdir = File::Spec->catdir("src", "modules");
1793 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1796 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1797 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1800 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1801 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1804 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1806 EXTRA: for my $extra (@extras) {
1807 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1808 next if ($extra eq '.svn');
1809 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1810 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1811 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1812 if (-l $abs_source) {
1813 # Symlink, is it in the right place?
1814 my $targ = readlink($abs_source);
1815 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1816 if ($abs_targ eq $abs_extra) {
1817 $extras{$extra} = "\e[32;1menabled\e[0m";
1819 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1821 } elsif (-e $abs_source) {
1822 my ($devext, $inoext) = stat($abs_extra);
1823 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1825 if ($devsrc == $devext && $inosrc == $inoext) {
1826 $extras{$extra} = "\e[32;1menabled\e[0m";
1828 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1831 open my $extfd, "<", $abs_extra;
1832 open my $srcfd, "<", $abs_source;
1834 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1835 $extras{$extra} = "\e[32;1menabled\e[0m";
1837 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1841 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1844 # Now let's add dependency info
1845 for my $extra (keys(%extras)) {
1846 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1847 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1848 my @deps = split / +/, getdependencies($abs_extra);
1849 for my $dep (@deps) {
1850 if (exists($extras{$dep})) {
1851 my $ref = \$extras{$dep}; # Take reference.
1852 if ($$ref !~ m/needed by/) {
1853 # First dependency found.
1854 if ($$ref =~ m/enabled/) {
1855 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1857 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1858 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1861 if ($$ref =~ m/enabled/) {
1862 $$ref .= ", \e[32;1m$extra\e[0m";
1864 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1870 for my $extra (sort {$a cmp $b} keys(%extras)) {
1871 my $text = $extras{$extra};
1872 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1873 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1875 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1878 return keys(%extras) if wantarray; # Can be used by manage_extras.
1881 sub enable_extras (@) {
1883 for my $extra (@extras) {
1884 my $extrapath = "src/modules/extra/$extra";
1885 if (!-e $extrapath) {
1886 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1889 my $source = "src/modules/$extra";
1891 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1894 # Get dependencies, and add them to be processed.
1895 my @deps = split / +/, getdependencies($extrapath);
1896 for my $dep (@deps) {
1897 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1898 if (!-e "src/modules/$dep") {
1899 if (-e "src/modules/extra/$dep") {
1900 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1903 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";
1907 print "Enabling $extra ... \n";
1908 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1912 sub disable_extras (@)
1914 opendir my $dd, "src/modules/extra/";
1915 my @files = readdir($dd);
1918 EXTRA: for my $extra (@extras) {
1919 my $extrapath = "src/modules/extra/$extra";
1920 my $source = "src/modules/$extra";
1921 if (!-e $extrapath) {
1922 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1925 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1926 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";
1929 # Check if anything needs this.
1930 for my $file (@files) {
1931 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1932 # File depends on this extra...
1933 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1934 # And is both enabled and not about to be disabled.
1935 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1936 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1942 print "Disabling $extra ... \n";
1943 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";